0
0

More than 3 years have passed since last update.

Typescriptでデザインパターン [chain of responsibility]

Posted at

chain of responsibilityパターンとは

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

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

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

サンプル

こちらを参考にしました。

chainOfResponsibility.ts

HandlerというスーパークラスからConcreteHandlerクラスにextendsしている。
setHandlerメソッドでHandlerのクラスを継承している。
operationメソッドでクラスのprivate変数の初期化したさいの値と、引数として与えられた値を比較する。

export class Handler {
    private handler: Handler;
    private req: number;

    constructor(req: number) {
        this.req = req;
    }

    public setHandler(handler: Handler): void {
        this.handler = handler;
    }

    public operation(msg: string, req: number): void {
        if (req <= this.req) {
            this.handlerRequest(msg)
        } else if (this.handler !== null && this.handler !== undefined) {
            this.handler.operation(msg, req);
        }
    }

    public handlerRequest(msg: string): void {
        throw new Error("Abstract method!");
    }
}

export class ConcreteHandler1 extends Handler {
    constructor(req: number) {
        super(req);
    }
    public handlerRequest(msg: string) {
        console.log("Message (ConcreteHandler1) :: ", msg);
    }
}


export class ConcreteHandler2 extends Handler {
    constructor(req: number) {
        super(req);
    }
    public handlerRequest(msg: string) {
        console.log("Message :: (ConcreteHandler2) ", msg);
    }
}

export class ConcreteHandler3 extends Handler {
    constructor(req: number) {
        super(req);
    }
    public handlerRequest(msg: string) {
        console.log("Message :: (ConcreteHandler3) ", msg);
    }
}

demo.ts

import { Handler, ConcreteHandler1, ConcreteHandler2, ConcreteHandler3 } from "./chainOfResponsibility";

export function show() : void {
 let h1: Handler,
  h2: Handler,
  h3: Handler,
  reqs: number[],
  i: number,
  max: number;

 reqs = [2, 7, 23, 34, 4, 5, 8, 3];

 h1 = new ConcreteHandler1(3);
 h2 = new ConcreteHandler2(7);
 h3 = new ConcreteHandler3(20);

 h1.setHandler(h2);
 h2.setHandler(h3);

 for (i = 0, max = reqs.length; i < max; i += 1) {
  h1.operation("operation is fired!", reqs[i]);
 }
}

show();

結果

chain_of_responsibility> tsc --target ES5 .\demo.ts
chain_of_responsibility> node .\demo.js
Message (ConcreteHandler1) ::  operation is fired!
Message :: (ConcreteHandler2)  operation is fired!
Message :: (ConcreteHandler2)  operation is fired!
Message :: (ConcreteHandler2)  operation is fired!
Message :: (ConcreteHandler3)  operation is fired!
Message (ConcreteHandler1) ::  operation is fired!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0