Mediator

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.

classDiagram
    class Mediator {
        <<interface>>
        +notify(sender, event)
    }
    class ConcreteMediator {
        -Component1 component1
        -Component2 component2
        +notify(sender, event)
    }
    class Component1 {
        -Mediator mediator
        +operationA()
    }
    class Component2 {
        -Mediator mediator
        +operationB()
    }

    Mediator <|.. ConcreteMediator
    Component1 --> Mediator
    Component2 --> Mediator
    ConcreteMediator --> Component1
    ConcreteMediator --> Component2

When to use

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 when you can’t reuse a component in a different program because it’s too dependent on other components.

Explanation

Problem

Say you have a dialog for creating and editing customer profiles. It consists of various controls such as text fields, checkboxes, buttons, etc.

Some of the form elements may interact with others. For instance, selecting the “I have a dog” checkbox may reveal a hidden text field for entering the dog’s name. Another button may have to validate values of all fields before saving the data.

By having this logic implemented directly inside the code of the form elements developers make these elements much harder to reuse in other forms checking other kinds of data.

Solution

The Mediator pattern suggests that you should cease all direct communication between the components which you want to make independent of each other. Instead, these components must collaborate indirectly, by calling a special mediator object that redirects the calls to appropriate components. As a result, the components depend only on a single mediator class instead of being coupled to dozens of their colleagues.

Real world problem

  1. Air Traffic Control: Pilots (Components) don’t talk to each other directly. They talk to the Tower (Mediator).
  2. UI Dialogs: A dialog controller manages communication between inputs, buttons, and lists.

Pros and Cons

Pros Cons
- Single Responsibility Principle: You can extract the communications between various components into a single place, making it easier to comprehend and maintain.
- Open/Closed Principle: You can introduce new mediators without having to change the actual components.
- Coupling: You can reduce coupling between multiple components of a program.
- Reuse: You can reuse individual components more easily.
- God Object: Over time a mediator can evolve into a God Object.

Comparison

  • Chain of Responsibility: Passes a request sequentially. Mediator centralizes communication.
  • Observer: The difference is often in intent. Observer allows dynamic subscription. Mediator encapsulates interaction.
  • Facade: Facade simplifies a subsystem. Mediator coordinates interaction between components.

Code example

Typescript

Php