0

私はかなり長い間デザインパターンを使用しており、それを「責任の連鎖パターン」と呼んだり参照したりしてきましたが、今では違いがあることに気づきました。そうするのは適切ではないかもしれません。したがって、私の質問は 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;
    }
}

常にブール値であるとは限りません-私はこのパターンを変更可能なオブジェクトでも使用しました-しかし、短絡条件が常にあります(たとえば、trueを返す、文字列が空の文字列である、フラグが設定されるなど)。

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

では、これは責任連鎖パターン以外の何かと呼ぶべきでしょうか? インスタンスにメッセージを渡す従来のアプローチよりもこのアプローチを使用する場合に考慮すべき懸念事項や問題はありますか。

4

2 に答える 2

2

この連鎖を責任の連鎖とは呼びません。

Chain of Responsibility では、「ショートサーキット」は、何らかの戻り値ではなく、大まかに「私はこれを処理できるので、チェーンの次の人は処理する必要はありません」です。チェーン内の各オブジェクトがチェーン内の次のオブジェクトを認識し、必要に応じてその次のオブジェクトに制御を渡すのは正常です。通常、値を返すのではなく、何かを行います。

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

于 2011-06-28T22:23:28.627 に答える
1

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

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

 public enum Validity{
     Invalid,
     Indeterminate,
     Valid
 }

次のように、インターフェイスをチェーン可能に変更できます。

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

ほとんどの は、FooBar次のようなメソッドを実装する必要があります。

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;
    }
}
于 2011-06-28T16:05:24.167 に答える