2014-11-24 96 views
0

我有一个算法大纲 - 一些逻辑步骤必须按特定顺序执行。算法的结果必须是某个数字。当然,这使我想到了使用模板方法模式的想法。这适用于void方法,但这里出现了我的问题:算法中的每个步骤都不是void方法,但允许返回一个数字(因此它们是int方法) - 如果某个步骤返回非零数字,则此数字是算法执行的结果,如果它是零 - 执行继续下一步。带返回值的模板方法

这听起来真的很微不足道,但我仍然觉得它在某种程度上丑有类似:

public int algorithm() { 
    int resultStep1 = step1(); 
    if (resultStep1!=0) { 
     return resultStep1; 
    } 
    int resultStep2 = step2(); 
    if (resultStep2!=0) { 
     return resultStep2; 
    } 
    ... 
} 

当然step1()step2()和等等都是抽象方法,有自己特定的实现在相应的班级那延伸我的。

我想到的另一个想法是使用异常,但因为我们在谈论控制流,所以这将是一种反模式。

我在这里错过了什么,或者这只是我必须写的吗?

+0

我在这个问题的一半停下理解。你想返回第一个非零步骤,真正的问题是什么 – 2014-11-24 11:02:32

+0

如何可迭代?你可以写一个next()给你的steps(),它不会返回下一步,但是你的结果,如果它不是零。所有紧密的一个整洁的循环。 – 2014-11-24 11:04:25

+0

@RoyalBg当某些步骤返回一个非零数字时,那么这是算法的返回值,否则执行继续N步并返回其他东西作为最后的手段 – Anton 2014-11-24 11:05:38

回答

0

你可以做到以下几点:

if(setResultAndCheckIsNonZero(step1())) { 
    return result; 
} else if(setResultAndCheckIsNonZero(step2())) { 
    return result; 
} else if ... 

其中:

private int result; 

private boolean setResultAndCheckIsNonZero(int x) { 
    result = x; 
    if(result != 0) 
     return true; 
    return false; 
} 
+2

这使用“副作用”。名为'...的方法不仅仅是一个测试,它设置了一个字段。这有点讨厌。 – weston 2014-11-24 11:27:35

+0

修复名称将是一种方法。如果你调用了'setResultAndCheckIsNonZero'方法,那么副作用是明确的。 – weston 2014-11-24 11:31:23

+0

我觉得设置一个字段非常好,因为我们在这里讨论的是同一个类,它已经加载到内存中。 – 2014-11-24 11:32:16

3

的Java 7

您可以定义一个接口为您的步骤:

interface Step { 
    int step(); 
} 

然后使用一系列步骤:

ArrayList<Step> steps = new ArrayList<Step>(); 

遍历它像这样:

public int algorithm() { 
    for (Step step : steps) { 
     int result = step.step(); 
     if (result != 0) 
      return result; 
    } 
    return 0; 
} 

初始化列表中,你可以使用匿名的实现类做到这一点:

steps.add(new Step() { 
    @Override 
    public int step() { 
     return step1(); //or the code directly 
    } 
}); 

steps.add(new Step() { 
    @Override 
    public int step() { 
     return step2(); 
    } 
}); 

或者每一步精心打造名为实现类:

public class Step1 implements Step { 
    @Override 
    public int step() { 
     // TODO Auto-generated method stub 
     return 0; 
    }  
} 

并添加到列表如下:

steps.add(new Step1()); 
steps.add(new Step2()); 

使用lambda在Java8

无需接口。

列表:

ArrayList<Supplier<Integer>> steps = new ArrayList<Supplier<Integer>>(); 

设置:

steps.add(()-> step1()); 
steps.add(()-> step2()); 

算法:

public int algorithm() { 
    for (Supplier<Integer> step : steps) { 
     int result = step.get(); 
     if (result != 0) 
      return result; 
    } 
    return 0; 
} 
+0

这需要很多工作要做,因为有很多步骤()s – 2014-11-24 11:31:06

+2

+使用lambda而不是匿名,如果您使用java8 – user2504380 2014-11-24 11:33:51

+0

@ user2504380伟大的一点,我只是想安装Java 8来做到这一点。我是Android程序员,所以我还没有需要! – weston 2014-11-24 11:38:30