2011-06-28 3 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; 
    } 
} 

ITSは、常にどちらかの真偽値ではない-I'veはよくとして可変オブジェクトでこのパターンを使用しますが、短絡状態が(常にあります例えば、trueを返し、Stringは空のStringであり、フラグがセットされます。

これまで、基本クラスを継承して実装の詳細を継承するという問題を考慮して、これを「責任の連鎖」パターンと呼びました。しかし、今日私は重要な違いを認識しました。チェーンに沿ったオブジェクトはチェーンの残りの部分を中断できません。実装が「これは偽であり、どの条件でも偽であることを保証できます」(nb:短絡はtrueのみ)と言うことはできません。

これは、チェーンの責任パターン以外のものと呼ばれるべきですか?このアプローチを伝統的なものよりも使用する際に考慮すべき問題や懸案事項はありますか?

答えて

2

私はこの責任チェーンを連鎖しません。

「短絡」は大雑把に「私はこれを処理できるので、チェーンの次の人は何らかの戻り値ではなくてもよい」ということです。チェーン内の各オブジェクトは、チェーン内の次のオブジェクトを知り、必要に応じてその次のオブジェクトに制御を渡すのが普通です。通常はとなります。値を返すのではなく、を実行します。

あなたが提示した例は完全に合理的ですが、私はそれが名前付きパターンであるかどうかはわかりません。私は今あなたが描いている他の変種についてはあまり明確ではありません。

+0

私はキーがあなたの「通常は値を返すのではなく何かをする」というコメントだったと思います。私が使用した変種は、一連のテキストフィルタです。 1つのフィルターは、呪いの言葉、別のストップワード、別の数字などを取り除きます。返された結果は、次のものに引き渡されます。フィルタが空の文字列(例えば、呪いフィルタによって処理される呪い語のみからなる文字列)を返す場合、それは短絡する。私の指摘は、パターンがブール値ではなく、イメージフィルタでそれを使用することが想像できます。 – ArtB

+1

@ArtB:データフィルタを使用するあなたの例は、パイプラインやデコレータパターンのように聞こえます。 – rwong

1

あなたが持っているのは責任の連鎖ですが、いくつかの小さな変更を追加することで、「純粋な」連鎖を作り出すことができます。

この関数から期待される3つの異なる結果を表す列挙型を作成できます。

public enum Validity{ 
    Invalid, 
    Indeterminate, 
    Valid 
} 

あなたはそうのように連鎖できるようにインターフェースを変更することができます。そして、

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

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

あなたFooBar秒のほとんどは、このようなメソッドを実装する必要がありますチェーンを変更して確定的な回答のいずれかを確認することができます。

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を返すことを本当に望んでいるわけではありません。通常、各インスタンスは特定の制約を表しています。あなたは、間違った答えをしたくないです。また、Indeterminateは、連鎖しているときにのみ存在します。ただ1つのクラスを処理しているときには、それは単なる処理状態になります。また、あなたはまだそれをCoRパターンと呼んでいるかどうかは答えていませんでした。 – ArtB

+0

私は自分の答えを更新しました。 CoRの質問は難しいです。なぜなら、その中間にいるからです。正のどちらかの否定的な答えで短絡するオプションを追加すると、純粋なCoRが実行されますが、そのままではCoRですが、純粋ではありません。 –

関連する問題