Mediator Design Pattern

Learn via video courses
Topics Covered

Overview

Mediator Design Pattern is a behavioral design pattern. It is one of the most widely used and important types of design patterns. The Mediator design pattern restricts direct communication between objects by detaching them with the addition of a mediator (i.e. a layer to curb direct interaction between them) that forces communication through it.

When Will We Need Mediator Design Pattern?

Structure of Mediator Design Pattern

If the objects interact directly with one other, the system components will be strongly connected with each other, resulting in increased maintainability costs and ease of extension. The Mediator pattern focuses on acting as a bridge between items to facilitate communication and aid in the implementation of lose-coupling between components. The mediator pattern is used to decrease the complexity of communication between many objects or classes. The mediator design pattern specifies an object that encapsulates how a group of items communicate with one another.

We are accustomed to seeing programs comprising a huge number of classes. However, when additional classes are introduced to a program, the communication problem between these classes may get more difficult.  As a result, maintenance has become a major issue that must be addressed in some way.

The mediator pattern, like many other Design Patterns, appears to address the problem. It facilitates communication between items that are enclosed by a mediator object. Objects do not communicate directly with one another, but rather through the mediator.

Scenarios Where You Can Use the Mediator Design Pattern

How Mediator Patterns Work

The Mediator Pattern can be used in the following scenarios:

  • When you find yourself creating a plethora of component subclasses just to reuse some basic behavior in different contexts - Because all relationships between components are contained within the mediator, it's simple to define alternative means for these components to collaborate by adding additional mediator classes, without needing to alter the components themselves.

  • When it's difficult to alter certain classes because they're closely connected to a slew of other classes - The Mediator Design pattern allows you to isolate all the relationships between classes into a new class, separating any changes to a single component from the rest of the components.

  • When you can't reuse a component in another application because it is too dependent on other components - When you utilize the Mediator, individual components become oblivious of the other components. They could still communicate with one another, although through a mediator item. If you want to reuse a component in another project, you must provide it with a new mediator class.

Examples of Mediator Design Pattern

Social Media Chat Group Mediator

  • A chat application is a popular example of a mediator design. We can have several participants in a chat application and connecting each participant with every other would cause harm to privacy and security and would also increase the number of connections.  The safest alternative is to have a central location where all participants may connect; this central location is simply the mediator class.

Airplane Mediator Design Pattern

  • The traffic control room at airports is a fantastic real-world illustration of the mediator design pattern. It will be a huge disaster if all flights were to converse with each other to figure out which flight is going to arrive next. Instead, flights just transmit their status to the tower. These towers, in turn, relay signals to determine whether planes can take off or land. It is important to realize that these towers do not control the whole flight. They solely apply restrictions at terminal areas.

Translator Example

In this article, we'll look at a communication system where a person A who converses in English is communicating with a group of people who speak different languages and are unable to understand English accurately. Likewise, A is only able to communicate in English and cannot understand the language spoken by others.

Here, the live captioning system acts as a mediator aiding in the communication process. If they attempt direct communication, they tend to send wrong signals and confuse each other even more. The captioning system will act as a router between the people on the call and has its own logic to give a means of communication.

How Does Mediator Design Pattern Work?

The Mediator is an entity that governs how a group of items communicate with one another. Loose coupling between coworker objects is done by having them communicate with the Mediator rather than with one another. This pattern is extremely effectively demonstrated by the live captioning system. Each of the attendees of the call will set the captions to their language. When A speaks something, the captioning system (mediator) will display the message in the necessary language on the screen of the respective attendee.

In no way, the participants will communicate directly with each other. The captioning system who is the mediator will not control the actions of the attendees. It exists only to enforce the communication by effective translation of their messages.

Structure

Working of Mediator Design Pattern

1. Components are different classes that provide business logic. Each component has a reference to a mediator, which is specified with the mediator interface's type. Because the component is unaware of the actual class of the mediator, it may be reused in other projects by attaching it to a different mediator.

2. The Mediator interface specifies communication methods with components, which typically comprise only a single notification method. Components may pass any context, including their own objects, as parameters to this function, but only in such a way that no coupling exists between a receiving component and the sender's class.

3. Concrete Mediators contain the interactions of distinct components. Concrete mediators frequently maintain track of all the components they govern and, in some cases, manage their whole lifespan.

4. Concrete Colleague uses its mediator to speak with other colleagues and implements the colleague interface.

Components must not be aware of the existence of other components. If anything significant occurs inside or to a component, the component must only alert the mediator. When the mediator receives the notice, it may simply identify the sender, which may be sufficient to determine which component should be invoked in response. From the standpoint of a component, everything appears to be a whole black box. The sender has no idea who will handle the request, and the recipient has no idea who issued the request in the first place.

Implementation

In this example, considering a general scenario, the person hosting the meeting would have to learn every language and find a way to simultaneously communicate with each other. This would be a very complex process. However, the Mediator pattern helps eliminate mutual dependencies between the different people on the call.

Implementation of Mediator Design Pattern

Although the different participants on the call seem to be communicating directly, they don't. Instead, the participant only needs to check the captioning system to understand a message and then speak without knowledge of the words and their meanings used by the other attendees.

Steps to be followed while implementing a solution

1. Identify a set of strongly connected classes that might benefit from more independence.

2. Define the mediator interface and the appropriate communication protocol between mediators and other components. When you wish to reuse component classes in multiple situations, this interface is critical. You can link the component with a different mediator implementation as long as the component communicates with its mediator using the general interface.

3. Put the concrete mediator class into action. This class would benefit from keeping track of all of the components it maintains. You may take it a step further and hold the mediator accountable for the creation and destruction of component objects. Following that, the mediator may take on the appearance of a factory or a facade.

4. The mediator object should be referenced by components. The connection is often made in the connector of the component, where a mediator object is supplied as a parameter.

5. Modify the code of the components so that they call the mediator's notification method rather than methods on other components. Extract the code that calls other components into the mediator class. When the mediator gets alerts from that component, run this code.

Pseudocode

Pros and Cons of Mediator Design Pattern

Pros:

  • The principle of single responsibility: It reduces communication paths between numerous components by consolidating them into a single location, making them easier to understand and manage.
  • The principle of open/closed: You can add additional mediators without changing the actual components.
  • Reuse of individual components: It restricts subclassing. A mediator directs action that might otherwise be dispersed among several objects. Subclassing Mediator is the only way to change this behavior; Colleague classes can be reused as-is.
  • Simplicity: You may swap out one item in the structure for another without altering the classes or interfaces.

Cons:

  • Centralization of Control: The mediator pattern exchanges interaction complexity for mediator complexity. A mediator might become more complicated than any individual colleague since it incorporates protocols. This can result in the mediator becoming a monolith that is difficult to maintain.
  • Intimate Mediator Behavior: A mediator might grow into a God Object over time. The Mediator frequently has to be quite conversant with all of the different classes.
  • Complexity: The mediator object is in charge of all interactions between the participants' objects. When the number of participants and the distinct participant classes are large, the potential problem of mediator complexity occurs. If you've ever written custom dialogues for graphical user interface (GUI) apps, you'll recall that the dialogue classes grow quite complicated after a while.
  • Difficult to maintain: The complexity of a mediator and its centralized controlling nature makes it very hard to maintain.

Difference between Mediator Design Pattern and Other Design Patterns

Mediator vs. Facade Pattern

The mediator design pattern is similar to the facade design pattern. Instead of dealing with a single object's interface in a mediator, you create a multiplexed interface across numerous objects to allow seamless transitions. Mediator, like Facade, isolates functionality from existing classes. In Mediator, a mediator adds functionality and thus is known by the colleague objects.  Facade, on the other hand, defines a simplified interface to a subsystem; it does not introduce additional functionality and is unknown to the subsystem classes.

Mediator Pattern vs. Adapter Pattern

The mediator pattern simply "mediates" requests between coworker classes. It is not meant to alter the messages it receives and transmits; if it does, it is an Adapter design pattern.

Mediator Pattern vs Observer Pattern

The observer and mediator design patterns that solve the same problem. The fundamental distinction between them is the issue they address. The distinction is that an Observer object spreads communication by inserting "observer" and "subject" objects, but a Mediator object contains communication between other objects. The mediator class is most likely to be inherited in the mediator design pattern. The design patterns of Mediator and Observer are opposing. It has been discovered that it is easier to create reusable Observers and Subjects than it is to create reusable Mediators.

Summary

  • The Mediator Design Pattern is one of the most important forms of behavioral design pattern.
  • The Mediator design pattern limits direct connection between items by separating them and adding a mediator (i.e. 'a layer to hinder direct interaction between them') that compels communication via it.
  • It solves the problem of communication between multiple classes.
  • The Mediator Design Pattern is used in situations when there are multiple classes and it's difficult to alter their behavior or reuse them because of their dependencies on other components.
  • Common examples of the mediator design pattern are Social Media Chat Group Mediator, Traffic Control Room at Airports and Translator.
  • A basic mediator pattern design structure contains components, mediator interface, concrete mediators, and concrete colleagues.
  • The Mediator Design pattern reduces communication paths between components making them easier to understand and enhancing the reusability of code.
  • Maintenance of the mediator is complex due to its centralized controlling nature.

FAQs

Q: Name 2 real-world uses of Mediator Design Pattern.

A:
1. The mediator pattern is the most commonly employed design pattern when it comes to user interfaces. It is the foundation of almost every GUI framework. The classes representing forms (Dialog, Form, Button, Checkbox, etc.) represent the mediator, whereas each control represents a colleague. The form class provides the method for interacting with controls; when a new screen is generated, an inherited class is produced, and the relevant code is written in this class. This form of class acts as a conduit for control communication.

2. The Java Message Service (JMS) API is a Java Message Oriented Middleware (MOM) API that allows messages to be sent between two or more clients. There are two models supported by the JMS API. The publish-subscribe model is one of them. It is a mediator pattern implementation. Messages can be published depending on a certain topic. The publisher must set up a subscription to which various subscribers can subscribe. Subscribers may subscribe to receive messages on a certain message topic if there are zero or more subscribers. The publisher and subscriber don't know anything about one other, and the subscriber may even be inactive. In this situation, the subscriber will get messages when it becomes active.

Q: Are Abstract Mediators needed in single-mediator classes?

A: As long as the colleagues will only use one mediator, there is no need to build an Abstract Mediator class or an interface. Only if the colleagues need to deal with different mediators does the notion of an abstract Mediator become necessary.

Q: How is communication established between mediators and colleagues?

A: There are several approaches for establishing communication between colleagues and its mediator:   * A basic delegation may be employed, and the mediator object can offer specialized methods.  * In more complicated implementations, asynchronous messages can be added to a message queue, from which the mediator object can be picked up. * Observer pattern can be made to put to use. In such cases, a mediator can also act as an observer and colleagues can act as implementors of the observable object. Whenever there is a state change made to the object, the mediator (observer) gets notified and further notifies all colleagues.

Q: How different is the Chain of Responsibility Design Pattern from the Mediator Design Pattern?

A: The design patterns of Chain of Responsibility, Command, Mediator, and Observer address how to decouple senders and receivers, albeit with varying trade-offs. A sender request is routed via a chain of possible recipients using the Chain of Responsibility. A sender-receiver relationship with a subclass is generally specified by the command. Senders and recipients are referred to indirectly by Mediator. Observer presents a relatively decoupled interface that enables the configuration of many receivers at run-time.