相关嵌套条件的设计模式



我知道,通过使用策略、命令、责任链等设计模式,大多数条件地狱都可以以更面向对象的方式简化。

如果条件不包含很多侧分支(同一层次的分支),但嵌套得很重,每个条件都依赖于前一个条件的结果,那该怎么办?

下面是一个例子:

nestedFunction(input: Input){
if(input!=null){
a = func1(input)
if(p(a)){    // where p() is a predicate
b = func2(a)
if(p(b)){
c = func3(b)
if(p(c)){
// dosomething1
} else {
// dosomething2
}
} else {
// dosomething3
}
} else {
// dosomething4
}
} else {
// dosomething5
}      
}

我可以通过将每个嵌套的条件提取到不同的函数中来简化它,如下所示:https://blog.codinghorror.com/flattening-arrow-code/

但我很好奇是否有更多的OO友好的方式来做到这一点?

您可以使用管道模式。

管道是一系列IO步骤连接在一起的方式,下一个步骤处理前一个步骤的输出(想想unix风格的管道)。你可以用分支步骤来处理条件,它只做委托而不是实际的处理。

。显然,这个例子有点傻,而且设计过度,因为标准的函数组合会更简单、更优雅。我当然会从在较小的函数中提取代码开始,并使用标准技术组合分支,然后如果这仍然很繁琐,您可以尝试切换到另一种方法。

const pipeline = ifNotNull(
input => pipe(
input => input.toUpperCase(),
input => input + " added suffix",
console.log
)(input), 
() => console.log('input was null')
);

pipeline(null);
pipeline("some value");

function ifNotNull(thenStep, elseStep) {
return match({
condition: input => input !== null,
body: thenStep
}, {
condition: () => true,
body: elseStep
});
}
function match(...branches) {
return input => {
for (branch of branches) {
if (branch.condition(input)) {
return branch.body(input);
}
}
};
}
function pipe(...steps) {
return input => {
for (step of steps) {
input = step(input);
}

return input;
};
}

最新更新