- Chain of Responsibility の実装の比較-
Java による実装

Java による実装例だ。

いろんな実装が考えられるけど、ここでは Method オブジェクトを使ってみた。この場合、リクエストはメソッドの名前として与えられるんだ。それぞれのオブジェクトで、対応するメソッドが実装されているかどうかを調べ、ハンドラを呼び出すか、チェインをたぐって次のオブジェクトに投げるかを決定する。

Handler クラス

/* チェインのための Handler クラス */
public class Handler {
  /* 次の handler */
  Handler _successor;
  
  /* コンストラクタ */
  public Handler(Handler successor) {
    _successor = successor;
  }
  
  /* リクエスを投げる */
  public void sendRequest(String request) {
    try {
      /* リクエストの名前から Method を取得 */
      Method method = 
        this.getClass().getMethod(request, null);
      /* ハンドラの呼び出し */
      method.invoke(this, null);
    }
    catch(NoSuchMethodException e) {
      if (_successor != null) {
        /* チェインをたぐって、 */
        /* 次のオブジェクトにリクエストを投げる */
        _successor.sendRequest(request);
      }
    }
    catch(Exception e) {
      /* その他の例外 */
    }
  }
}

Button クラス

/* Button クラス */
public class Button extends Handler {
  /* コンストラクタ */
  public Button(Handler handler) {
    super(handler);
  }
  
  /* help リクエストのためのハンドラ */
  public void help() {
    /* help リクエストの処理 */
  }
}

Dialog クラス

/* Dialog クラス */
public class Dialog extends Handler {
  /* コンストラクタ */
  public Dialog(Handler handler) {
    super(handler);
  }
  
  /* print リクエストのためのハンドラ */
  public void print() {
    /* print リクエストの処理 */
  }
}

Application クラス

/* Application クラス */
public class Application extends Handler {
  /* コンストラクタ */
  public Application(Handler handler) {
    super(handler);
  }
  
  /* preview リクエストのためのハンドラ */
  public void preview() {
    /* preview リクエストの処理 */
  }
}

main()

public class Test {
  public static void main(String args[]) {
    /* それぞれのインスタンスを作る */
    Application app = new Application(null);
    Dialog dialog = new Dialog(app);
    Button button = new Button(dialog);
    
    /* help リクエストを投げる */
    button.sendRequest("help");
    /* print リクエストを投げる */
    button.sendRequest("print");
    /* preview リクエストを投げる */
    button.sendRequest("preview");
  }
}

これでオッケー!Method オブジェクトを使った場合、次のような利点がある。

この利点は、ほかのメッセージ送信を用いている言語のものと同じだね。かわりに欠点としては、C++ のように switch を用いたときに比べると、パフォーマンスが悪くなりがち、というとこか。


[Home] [Download] [Archives] [BBS] [Cocoa Programming Tips 1001] [Core Foundation の秘密] [Safari Developer News] [はじめてのブラウザのつくり方] [Sketch BP] [スクリーンセイバーを作ろう] [Objective-C 最適化] [Authorization API 完全理解] [Mac OS X Programming Books Review] [オブジェクト指向の言語比較論]

mailto: mkino@xd5.so-net.ne.jp