2014-11-24 112 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