有时我会遇到一个例程,它会测试一些条件并继续或退出,如下面的代码:
public void execute() {
if (context.condition1()) {
LOGGER.info("Condition 1 not satisfied.");
return;
}
doSomeStuff();
if (context.condition2()) {
LOGGER.info("Condition 2 not satisfied.");
return;
}
if (context.condition3()) {
LOGGER.info("Condition 3 not satisfied.");
return;
}
doRestOfStuff();
}
假设在输入此方法之前无法测试这些条件。也许这是一个具有这个单一入口点的servlet或控制器。根据我的经验(远远不是很大),这似乎是一种常见的情况。
现在,这段代码闻起来并不好,是吗?处理这个问题的最佳策略是什么?
答案 0 :(得分:3)
我们谈论了多少个不同的退出点?
如果您的示例中只有3个,那么您的原始代码就可以了。它易于阅读。我会认为"只有一个退出点"作为一般指导而非硬性规则。
将其更改为if
/ else if
块的嵌套组,特别是在缩进后,我发现难以阅读。如果您将来必须添加更多条件检查,您还有可能忘记将新条件正确地放入链中。
但是,如果您有很多条件,并且可能需要在运行时添加更多条件,那么您可以利用Chain of Responsibility
模式。
最终结果如下所示:
public void execute() {
List<Condition> conditionChains = ....
for(Condition condition : conditionChain){
if(condition.notSatisfied(context)){
//here use condition#toString() to explain what wasn't satisfied.
//Could use another method like getDescrption() instead...
LOGGER.info(condition + " not satisfied.");
return;
}
condition.execute(context);
}
}
你将拥有一个接口Condition
,它有2个方法来检查可满足性,然后是另一个执行任何相关代码的方法。
示例实现:
class Condition1 implements Condition{
public boolean isSatisfied(Context context){
...
}
public void execute(Context context){
doSomeStuff();
}
}
class Condition2 implements Condition{
public boolean isSatisfied(Context context){
...
}
public void execute(Context context){
//do nothing
}
}
class Condition3 implements Condition{
public boolean isSatisfied(Context context){
return !context.notCondition3();
}
public void execute(Context context){
doRestOfStuff();
}
}
答案 1 :(得分:1)
尝试阅读有关switch语句的信息,它是多种语言的解决方案,特别是在java中:
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
答案 2 :(得分:0)
这是我到目前为止所提出的:
public void execute() {
checkCondition1AndExecute();
}
private void checkCondition1AndExecute() {
if (context.notCondition1()) {
doSomeStuff();
checkCondition2AndExecute();
} else {
LOGGER.info("Condition 1 not satisfied.");
}
}
private void checkCondition2AndExecute() {
if (context.notCondition2()) {
checkCondition3AndExecute();
} else {
LOGGER.info("Condition 2 not satisfied.");
}
}
private void checkCondition3AndExecute() {
if (context.notCondition3()) {
doRestOfStuff();
} else {
LOGGER.info("Condition 3 not satisfied.");
}
}
它看起来并不好,但对我来说确实闻起来更好。我没有使用多个退出的大方法,而是使用小方法,每个方法负责一个特定条件(和退出点)。此外,它摆脱了愚蠢的return;
行。
但是,我仍然想知道是否有某种模式或更好的策略来处理这个问题。