IT専科TOP>デザインパターン入門> Chain of Responsibility パターン

Chain of Responsibility パターン

「Chain of Responsibility」という英単語は、「責任の連鎖」を意味します。

このパターンは、ある要求の受取り対象となる複数のオブジェクトに鎖状の関係を構築し、要求を処理する事が可能なオブジェクトに渡るまで、順次、構築した鎖状の関係に沿って要求を受流していくパターンです。

このパターンを適用すると、「この要求はこのオブジェクトが処理する」などという司令塔的な役割り(結び付き)を利用者側が意識しなくて良くなり、利用者側は「連鎖関係にある任意のオブジェクトに要求を投げるだけ」、処理側は「流れてきた要求が自身で処理できる場合は処理し、できない場合は、その要求を次のオブジェクトに渡すだけ」という役割分担が明確となります。(利用者側は、処理の詳細まで意識する必要はない)


※ 連鎖構造が深いと、実際どのオブジェクトが処理しているのかわからなくなったり(保守性が低下)処理速度の低下を招くので注意が必要です。


役割り

1. Handler(処理者)
要求を処理するインタフェースを定義します。 自身で処理できない要求の場合に受流す先(「Handler」を実装したオブジェクト)を格納するフィールドを定義します。
2. ConcreteHandlerA・B(具体的な処理者)
「Handler」のインタフェースを実装します。 実際に要求を処理する(自身で要求を処理するか、次のオブジェクトに要求を渡すか)クラスです。
3. Client(利用者)
「Chain Of Responsibility」パターンを適用したクラスを利用し処理します。

▲PageTop

クラス図

Chain of Responsibilityパターンのクラス図

Chain of Responsibilityパターン クラス図

▲PageTop

サンプル

ソースコード

1. Handler.java

public abstract class Handler {
    protected String name;
    protected Handler next;
    public Handler(String name) {
        this.name = name;
    }
    public Handler setNext(Handler handler) {
        this.next = handler;
        return handler;
    }
    public abstract void request(int req);
}

2-1. ConcreteHandlerA.java

public class ConcreteHandlerA extends Handler {
    private int rangeS;
    private int rangeE;
    public ConcreteHandlerA(String name, int rangeS, int rangeE) {
        super(name);
        this.rangeS = rangeS;
        this.rangeE = rangeE;
    }
    public void request(int req) {
        if (req >= rangeS && req <= rangeE) {
            System.out.println(name + ":私が成敗してくれるわ!");
        } else if (next != null) {
            System.out.println(name + ":私では無理じゃ!次の者出合えー");
            next.request(req);
        } else {
            System.out.println(name + ":次の者がおりませぬー");
        }
    }
}

2-2. ConcreteHandlerB.java

public class ConcreteHandlerB extends Handler {
    public ConcreteHandlerB(String name) {
        super(name);
    }
    public void request(int req) {
        if (req % 2 == 0) {
            System.out.println(name + ":ようこそ!偶数は私のテリトリーです。");
        } else if (next != null) {
            System.out.println(name + ":無念!偶数以外は・・・!次の方お願いします。");
            next.request(req);
        } else {
            System.out.println(name + ":無念!偶数以外は・・・!次もいないー");
        }
    }
}

3. Client.java

public abstract class Client {
    public static void main(String[] args) {
        Handler hand1 = new ConcreteHandlerA("A", 1, 10);
        Handler hand2 = new ConcreteHandlerA("B", 11, 20);
        Handler hand3 = new ConcreteHandlerA("C", 21, 30);
        Handler hand11 = new ConcreteHandlerB("D");
        hand1.setNext(hand2).setNext(hand3).setNext(hand11); // 責任のチェーンを構築
        hand1.request(31);
    }
}

実行結果

C:\sample\desin_pattern\Chain_of_Responsibility>javac Client.java [Enter]

C:\sample\desin_pattern\Chain_of_Responsibility>java Client [Enter]
A:私では無理じゃ!次の者出合えー
B:私では無理じゃ!次の者出合えー
C:私では無理じゃ!次の者出合えー
D:無念!偶数以外は・・・!次もいないー
        

▲PageTop