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()等等都是抽象方法,在扩展我的相应类中有自己的具体实现。

我想到的另一个想法是使用异常,但是当我们在这里讨论控制流时,这将是一种反模式。

我在这里遗漏了什么还是这只是我必须写的方式?

4

2 回答 2

3

爪哇 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());

在 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;
}
于 2014-11-24T11:22:29.113 回答
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;
}
于 2014-11-24T11:05:49.450 回答