2011-06-28 24 views
0

我一直在使用設計模式很長一段時間,一直在呼籲/將其稱爲「Chain-of-Responsibility pattern」,但現在我意識到存在差異,並且可能不適合這樣做。所以我的問題是1,「下面是這種模式的一個實例,還是應該被稱爲別的東西?」和2,「有什麼理由我應該更喜歡傳統的方式嗎?」。這仍然被認爲是職責鏈模式?

我在開發軟件時經常使用以下模式。我有一個界面,定義了一個functor,就像這樣。

interface FooBar{ 
    boolean isFooBar(Object o); 
} 

這些通常是搜索,過濾或處理類;通常像Comparator。實現方法通常是功能性的(即無副作用)。最後,我發現自己創建看起來接口的實現,如:

class FooBarChain implements FooBar{ 
    FooBar[] foobars; 

    FooBarChain(FooBar... fubars){ 
     foobars = fubars; 
    } 

    boolean isFooBar(Object o){ 
     for(FooBar f : foobars) 
      if( f.isFooBar(o) ) 
       return true; 

     return false; 
    } 
} 

它並不總是布爾要麼-I've使用這種模式與可變對象爲良好,但總有一個短路條件(例如返回true,String爲空字符串,一個標誌被設置等)。

到目前爲止,我一直把這稱爲「責任鏈」模式,考慮從基類繼承的問題作爲實現細節。但是,今天我意識到了一個重要的區別:沿着鏈條的物體不能打斷鏈條的其餘部分。實施方式沒有辦法說「這是錯誤的,我可以保證它對任何情況都是錯誤的」(nb:僅在true上短路)。

那麼,這應該被稱爲除責任鏈模式之外的東西嗎?在使用這種方法的情況下,如果使用傳統方式傳遞消息,那麼我是否應該考慮一些問題或問題。

回答

2

我不會稱之爲責任鏈的這個鏈條。

在責任鏈中,「短路」大致是「我可以處理這個問題,所以鏈中的下一個人不必」而不是任何類型的返回值。鏈中的每個對象都知道鏈中的下一個是誰,並根據需要將控制權交給下一個對象。他們通常做一些而不是返回一個值。

你提出的例子是完全合理的,但我不確定它是一個命名模式。我現在不太清楚你描述的其他變體。

+0

我認爲關鍵是你的「通常做某件事而不是回報價值」的評論。我使用的一個變體是一系列文本過濾器。一個過濾器刪除罵人詞,另一個停止詞,另一個數字等。返回的結果被傳遞到下一個。如果一個過濾器返回一個空字符串(例如一個字符串只包含由一個curse過濾器處理的curse words),那麼它就會短路。我的觀點是模式不是布爾特定的,我可以想象使用它與圖像過濾器。 – ArtB

+1

@ArtB:你的數據過濾器的例子聽起來像一個管道或裝飾模式。 – rwong

1

你有什麼是責任鏈,但你可以通過添加一些小的改變來創建一個「純粹」的責任鏈。

您可以創建一個枚舉,它將表示您期望從此函數獲得的3個不同結果。

public enum Validity{ 
    Invalid, 
    Indeterminate, 
    Valid 
} 

您可以更改爲鏈,能夠像這樣的接口:

public interface ChainFooBar{ 
    public boolean isFooBar(Object o); 
    public Validity checkFooBar(Object o); 
} 

你的大部分FooBar S的將不得不實行這樣的方法:

public abstract class AbstractFooBar implements FooBar{ 
    public Validity checkFooBar(Object o){ 
     return this.isFooBar(o) ? Validity.Valid : Validity.Indeterminate; 
    } 
} 

然後你可以改變你的鏈條來檢查任何一個確定的答案。

public class FooBarChain implements FooBar{ 
    private FooBar[] fooBars; 

    public FooBarChain(FooBar... fooBars){ 
     this.fooBars = fooBars; 
    } 

    public Validity isFooBar(Object o){ 
     for(FooBar fooBar : this.fooBars){ 
      Validity validity = fooBar.checkFooBar(o); 
      if(validity != Validity.Indeterminate){ 
       return validity == Validity.Valid; 
      } 
     } 
     return false; 
    } 
} 
+0

我想我可以,但我不認爲這是一個好主意,我很抱歉地說。 1)它不能與現有的接口一起工作,2)你並不真的想要返回Inderterminate,因爲你需要在每一個確定的答案。通常我發現每個實例代表一個特定的約束。你不想要Interdeterminate答案。此外,不確定只存在於你將它們鏈接起來的時候,因爲當你只處理一個類時,就會變成更多的狀態來處理。此外,你沒有回答你是否仍稱它爲CoR模式。 – ArtB

+0

我更新了我的答案。 CoR問題很難,因爲它介於兩者之間。當你選擇短路時選擇正面或負面答案,那麼你正在做一個純粹的CoR,但它仍然是CoR,但不是純粹的。 –