我有一个算法大纲 - 一些必须按特定顺序执行的逻辑步骤。算法的结果必须是某个数字。很自然地,这让我产生了使用模板方法模式的想法。这适用于 void
方法,但我的问题来了:算法中的每个步骤都不是 void
方法,但允许返回一个数字(因此它们是 int
methods) - 如果一个步骤返回一个非零数字,这个数字就是算法执行的结果,如果它是一个零 - 执行继续下一步。
这听起来可能真的微不足道,但我还是觉得有点丑陋,比如:
public int algorithm() {
int resultStep1 = step1();
if (resultStep1!=0) {
return resultStep1;
}
int resultStep2 = step2();
if (resultStep2!=0) {
return resultStep2;
}
...
}
当然step1()
、step2()
等都是抽象方法,在我的扩展的相应类中都有自己的具体实现。
我想到的另一个想法是使用异常,但当我们在这里讨论控制流时,这将是一种反模式。
我是不是漏掉了什么,还是我必须这样写?
最佳答案
Java 7
您可以为您的步骤定义一个接口(interface):
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());
在 Java8 中使用 lambda
不需要界面。
列表:
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;
}
关于java - 具有返回值的模板方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27103231/