Mediator Design Pattern
Mediator Design Pattern is one of the Behavioral Design Pattern. With the Mediator Design Pattern, communication between objects is encapsulated with a mediator object.
Objects no longer communicate directly with each other, but
Definition
GoF Definition: Define an object that encapsulates how a set of objects interacts. The mediator pattern promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
Concept
A mediator is the one who takes the responsibility of communication among a group of objects. The mediator acts as an intermediary who can track the communication between two objects.
The other objects (also known as Colleagues) in the system are also aware of this mediator and they know that if they need to communicate among themselves, they need to go through the mediator.
The advantage of using such a mediator is that we can reduce the direct interconnections among the objects and thus lower the coupling.
Before Mediator Design Pattern
This complex interaction between objects creates dependency and tighter coupling. If we want to achieve loose coupling, we need to reduce dependency as much as possible.
After Mediator Design Pattern
The mediator is the communication center for the objects. When an object needs to communicate to another object, it does not call the other object directly. Instead, it calls the mediator object whose main duty is to route the messages to the destination object.
Real-Life Example
1) Air Traffic Controller
Air traffic controller (ATC) is a mediator between flights. It helps in communication between flights and coordinates/controls landing, take-off.
Two flights need not interact directly and there is no dependency between them. This dependency is solved by the mediator ATC.
If ATC is not there all the flights have to interact with one another and managing the show will be very difficult and things may go wrong.
2) Traffic Light Signal
When one light turns ON, rest other have to be turned OFF.
If each light will communicate with
By introducing Light Mediator which is responsible to hold object reference of all other light and communication task, the design becomes flexible and de-coupled.
We can add any color light and remove it
Java Implementation
Let's Implement above Traffic Light Signal Mediator Example using Java.
import java.util.HashSet; public class MediatorDesignPatternDemo { public static void main(String[] args) { LightMediator lightMediator = new LightMediator(); Light red = new Light("Red", lightMediator); Light green = new Light("Green", lightMediator); Light yellow = new Light("Yellow", lightMediator); red.turnON(); green.turnON(); yellow.turnON(); } } /** * * When any light turns ON in traffic Signal, * Light Mediator turns OFF other lights. * */ class LightMediator { // Using Hashset to achieve uniqueness in light color. HashSet<Light> trafficSignal = new HashSet<>(); /** * register passed light object in LightMediator * It is being called by constructor of Light class. * We can also explicitly call this method. */ public void registerLight(Light light) { trafficSignal.add(light); } /** * unregisters light from LightMediator */ public void unRegisterLight(Light light) { trafficSignal.remove(light); } /** * Turns off all the lights other than * passed light Object */ void turnOffAllOtherLights(Light light) { for (Light l : trafficSignal) { if (!(l.equals(light))) { l.turnOFF(); } } System.out.println("------------------------------"); } /** * When any light turns ON, it calls this method * to notify mediator. Light mediator will turn OFF * all other light by calling turnOffAllOtherLights(light) * method */ public void notifyMediator(Light light) { turnOffAllOtherLights(light); } } /** * Represent light in traffic signal i.e. Red, Green or Yellow light */ class Light { /** * represents the turn ON and OFF state of light */ enum State { ON, OFF } private String color; private State currentState; private LightMediator LightMediator; /** * Creates Light object and register it to LightMediator */ Light(String color, LightMediator LightMediator) { this.color = color; this.LightMediator = LightMediator; LightMediator.registerLight(this); } /** * Turns ON the light and notify mediator for the same */ void turnON() { currentState = State.ON; System.out.printf("%s is turned %s \n", this, currentState.ON); LightMediator.notifyMediator(this); } /** * Turns OFF the light */ void turnOFF() { currentState = State.OFF; System.out.printf("%s is turned %s \n", this, currentState.OFF); } /** * It is generated using its String property * color's inbuilt hashcode() method */ @Override public int hashCode() { return color.hashCode(); } /** * Uses its String property color's inbuilt hashcode() method */ @Override public boolean equals(Object obj) { Light light = (Light) obj; return color.equals(light.color); } /** * returns light color */ @Override public String toString() { return color; } }
Output:
Red is turned ON Yellow is turned OFF Green is turned OFF ------------------------------ Green is turned ON Red is turned OFF Yellow is turned OFF ------------------------------ Yellow is turned ON Red is turned OFF Green is turned OFF ------------------------------
Download Complete Java Program »
Mediator Design Pattern VS Observer Design Pattern
In the original book that coined the terms Observer and Mediator, Design Patterns, Elements of Reusable Object-Oriented Software it says that the Mediator pattern can be implemented by using the observer pattern.
A comparison between the mediator pattern and the Observer Design Pattern shows some similarities and some clear differences.
Difference : The main difference is that in the Mediator Design Pattern there is the notion of the participants and they communicate with each other using the mediator as a central hub, whereas in the Observer Design Pattern, there is a clear distinction between the sender and the receiver, and the receiver merely listens to the changes in the sender.
For Example:
Observer Design Pattern: Class A, can have zero or more observers of type O registered with it. When something in A is changed it notifies all of the observers.
Mediator Design Pattern: You have some number of instances of class X (or maybe even several different types:X, Y & Z), and they wish to communicate with each other (but you don't want each to have explicit references to each other), so you create a mediator class M. Each instance of X has a reference to a shared instance of M, through which it can communicate with the other instances of X (or X, Y
Existing Implementation in JDK
-
java.util.Timer
(allscheduleXXX()
methods) -
java.util.concurrent.Executor#execute()
-
java.util.concurrent.ExecutorService
(theinvokeXXX()
andsubmit()
methods) -
java.util.concurrent.ScheduledExecutorService
(allscheduleXXX()
methods) -
java.lang.reflect.Method#invoke()
Note : Read our article Threadpool using Executor Framework to know more about above mentioned
ExecutorService
class.
That's all for this topic. If you guys have any suggestions or queries, feel free to drop a comment. We would be happy to add that in our post. You can also contribute your articles by creating contributor account here.
Happy Learning 🙂
If you like the content on CodePumpkin and if you wish to do something for the community and the planet Earth, you can donate to our campaign for planting more trees at CodePumpkin Cauvery Calling Campaign.
We may not get time to plant a tree, but we can definitely donate ₹42 per Tree.
About the Author
Tags: Behavioral Design Pattern, Design Patterns, Java
Comments and Queries
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:<pre><code class="java"> String foo = "bar"; </code></pre>For more information on supported HTML tags in disqus comment, click here.