Dyuichi Blog

オブジェクト指向シリーズⅣ: デザインパターン [⑭ Chain of Responsibility]

概要

chainは日本語で「鎖」,responsibilityは日本語で「責任」という意味になる.したがって,chain of responsibilityは,「責任の鎖」という意味になる.Chain of Responsibilityパターンは,要求を受け取るオブジェクトの連鎖を形成し,いずれかのオブジェクトが要求を処理するまで,その要求が連鎖に沿って次のオブジェクトへ要求を渡していくパターンである.

Chain of Responsibilityパターンの主な要素は以下である.

  • Handler:要求を処理するためのインターフェース
  • ConcreteHandler:Handlerを実装したクラス

クラス図

画像が読み込まれない場合はページを更新してみてください。

実装例(Java)

java// Handler
abstract class Handler {
    protected Handler successor;
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
    public abstract void handleRequest(Request request);
}

// Concrete Handler
class ConcreteHandlerA extends Handler {
    @Override
    public void handleRequest(Request request) {
        if (request.getType() == RequestType.TYPE_A) {
            System.out.println(request.getName() + " is handle by ConcreteHandlerA");
            return;
        }
        if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

class ConcreteHandlerB extends Handler {
    @Override
    public void handleRequest(Request request) {
        if (request.getType() == RequestType.TYPE_B) {
            System.out.println(request.getName() + " is handle by ConcreteHandlerB");
            return;
        }
        if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

// Request
class Request {
    private RequestType type;
    private String name;
    public Request(RequestType type, String name) {
        this.type = type;
        this.name = name;
    }
    public RequestType getType() {
        return type;
    }
    public String getName() {
        return name;
    }
}

enum RequestType {
    TYPE_A, TYPE_B
}

// Client
public class ChainOfResponsibilityPattern {
    public static void main(String[] args) {
        Handler handlerA = new ConcreteHandlerA();
        Handler handlerB = new ConcreteHandlerB();
        handlerA.setSuccessor(handlerB);
        handlerA.handleRequest(new Request(RequestType.TYPE_A, "requestA"));
        handlerA.handleRequest(new Request(RequestType.TYPE_B, "requestB"));
    }
}

まとめ,所感

これまで登場したデザインパターンとは独立していることはわかる.

クライアント側は要求がどのように処理されているか知る必要が無いので,オブジェクトの結合度は低くなる.

しかし,Handlerオブジェクトを実装する側は,Handlerオブジェクトの数が増えすぎると管理が難しくなると思われる.おそらくその時は別のパターンを採用したほうがいいだろう.