TypeScript Chain of Responsibility Pattern Example

In this article, we will learn how to use and implement the Chain of Responsibility Pattern in TypeScript with an example.
Chain of Responsibility is a behavioral design pattern that lets you pass requests along a chain of handlers. Upon receiving a request, each handler decides either to process the request or to pass it to the next handler in the chain.

TypeScript Chain of Responsibility Pattern Example

The below diagram shows the generic structure of the Chain of Responsibility Pattern:

Let's refer to the above structure to create an example to demonstrates the usage of the Chain of Responsibility Pattern.

Let's create chainOfResponsibility.ts file and add the following code to it:
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);
    }
}

Usage

Let's create demo.ts file and add the following code to it:
import { Handler, ConcreteHandler1, ConcreteHandler2, ConcreteHandler3 } from "./chainOfResponsibility";

export function show() : void {
 var 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();
Run:
  • Compile the above code using the TypeScript compiler.
  • Above code is compiled to plan JavaScript code
  • Run Javascript code using node
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!

When to Use Chain of Responsibility Pattern

  • Use the Chain of Responsibility pattern when your program is expected to process different kinds of requests in various ways, but the exact types of requests and their sequences are unknown beforehand.
  • Use the pattern when it’s essential to execute several handlers in a particular order.
  • Use the CoR pattern when the set of handlers and their order are supposed to change at runtime.

All TypeScript Design Patterns

1. Creational Design Patterns

Creational patterns provide various object creation mechanisms, which increase flexibility and reuse of existing code.
  1. TypeScript Singleton Pattern Example
  2. TypeScript Factory Design Pattern with Example
  3. TypeScript Abstract Factory Pattern Example
  4. TypeScript Builder Pattern Example
  5. TypeScript Prototype Pattern Example

2. Structural Design Patterns

Structural patterns explain how to assemble objects and classes into larger structures while keeping these structures flexible and efficient.
  1. TypeScript Bridge Pattern Example
  2. TypeScript Adapter Pattern Example
  3. TypeScript Decorator Pattern Example
  4. TypeScript Composite Pattern Example
  5. TypeScript Flyweight Design Pattern Example
  6. TypeScript Facade Pattern Example
  7. TypeScript Proxy Pattern Example

3. Behavioral Design Patterns

Behavioral design patterns are concerned with algorithms and the assignment of responsibilities between objects.
  1. TypeScript Command Pattern Example
  2. TypeScript Chain of Responsibility Pattern Example
  3. TypeScript Visitor Pattern Example
  4. TypeScript Template Method Pattern Example
  5. TypeScript Strategy Pattern Example
  6. TypeScript State Pattern Example
  7. TypeScript Observer Pattern Example
  8. TypeScript Memento Pattern Example
  9. TypeScript Mediator Pattern Example
  10. TypeScript Iterator Pattern Example
  11. TypeScript Interpreter Design Pattern Example


Comments