TypeScript Mediator Pattern Example

In this article, we will learn how to use and implement the Mediator Pattern in TypeScript with an example.
Mediator is a behavioral design pattern that lets you reduce chaotic dependencies between objects. The pattern restricts direct communications between the objects and forces them to collaborate only via a mediator object.

TypeScript Mediator Pattern Example

The below diagram shows the generic structure of the Mediator Pattern:

Let's refer to the above structure to create an example to demonstrates the usage of the Mediator Pattern.
Let's create mediator.ts file and add the following code to it:
export interface Mediator {
    send(msg: string, colleague: Colleague): void;
}

export class Colleague {
    public mediator: Mediator;

    constructor(mediator: Mediator) {
        this.mediator = mediator;
    }

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

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

export class ConcreteColleagueA extends Colleague {
    constructor(mediator: Mediator) {
        super(mediator);
    }

    public send(msg: string): void {
        this.mediator.send(msg, this);
    }

    public receive(msg: string): void {
        console.log(msg, "`receive` of ConcreteColleagueA is being called!");
    }
}

export class ConcreteColleagueB extends Colleague {
    constructor(mediator: Mediator) {
        super(mediator);
    }

    public send(msg: string): void {
        this.mediator.send(msg, this);
    }

    public receive(msg: string): void {
        console.log(msg, "`receive` of ConcreteColleagueB is being called!");
    }
}

export class ConcreteMediator implements Mediator {
    public concreteColleagueA: ConcreteColleagueA;
    public concreteColleagueB: ConcreteColleagueB;

    public send(msg: string, colleague: Colleague): void {
        if (this.concreteColleagueA === colleague) {
            this.concreteColleagueB.receive(msg);
        } else {
            this.concreteColleagueA.receive(msg);
        }
    }
}

Usage

Let's create demo.ts file and add the following code to it:
import { ConcreteMediator, ConcreteColleagueA, ConcreteColleagueB } from "./mediator";

export function show() : void {
 var cm: ConcreteMediator = new ConcreteMediator(),
  c1: ConcreteColleagueA = new ConcreteColleagueA(cm),
  c2: ConcreteColleagueB = new ConcreteColleagueB(cm);

 cm.concreteColleagueA = c1;
 cm.concreteColleagueB = c2;

 c1.send("`send` of ConcreteColleagueA is being called!");
 c2.send("`send` of ConcreteColleagueB is being called!");
}
show();
Run:
  • Compile the above code using the TypeScript compiler.
  • Above code is compiled to plan JavaScript code
  • Run Javascript code using node
design_patterns_in_typescript\iterator> tsc --target ES5 .\demo.ts
design_patterns_in_typescript\iterator> node .\demo.js
1
7
21
657
3
2
765
13
65

When to Use Mediator Pattern

  • Use the Mediator pattern when it’s hard to change some of the classes because they are tightly coupled to a bunch of other classes.
  • Use the pattern when you can’t reuse a component in a different program because it’s too dependent on other components.
  • Use the Mediator when you find yourself creating tons of component subclasses just to reuse some basic behavior in various contexts

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