如何在Java中处理多个出口点

时间:2015-07-29 16:40:49

标签: java design-patterns

有时我会遇到一个例程,它会测试一些条件并继续或退出,如下面的代码:

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或控制器。根据我的经验(远远不是很大),这似乎是一种常见的情况。

现在,这段代码闻起来并不好,是吗?处理这个问题的最佳策略是什么?

3 个答案:

答案 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;行。

但是,我仍然想知道是否有某种模式或更好的策略来处理这个问题。