Introduction
The mediator pattern allows loose coupling by encapsulating the way disparate sets of objects interact and communicate with each other. Allows for the actions of each object set to vary independently of one another.

Definition
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.
Problem solved by „Mediator”
Imagine we’re building a cooling system that consists of a power supply, fan and a button. Pressing the button should either turn on or turn off the fan. Before we turn the fan on, we need to turn on the power. Similarly, we have to turn off the power right after the fan is turned off.
First let’s implement class for a power supply.
Now it’s turn for a fan class. Every electric fan needs source of energy, therefore we need to reference PowerSupply class to Fan class.
public class PowerSupply { public void turnOn() { System.out.println("Turn on power-supply"); } public void turnOff() { System.out.println("Turn off power-supply"); } }
public class Fan { private PowerSupply powerSupply; private boolean isOn = false; public Fan(PowerSupply powerSupply){ this.powerSupply = powerSupply; } public boolean isOn() { return isOn; } public void turnOn() { powerSupply.turnOn(); isOn = true; } public void turnOff() { isOn = false; powerSupply.turnOff(); } }
public class Button { private Fan fan; public Button(Fan fan) { this.fan = fan; } public void press(){ if(fan.isOn()){ fan.turnOff(); } else { fan.turnOn(); } } }
public class CoolingSystem { public static void main(String[] args){ PowerSupplier powerSupplier = new PowerSupplier(); Fan fan = new Fan(powerSupplier); Button button = new Button(fan); System.out.println(fan.isOn()); button.press(); System.out.println(fan.isOn()); button.press(); System.out.println(fan.isOn()); } }Our system is working, but as you can predict, it will be difficult to implement changes and expand the system in such full of dependencies logic. That is not what good programmers do.
Solution
Solution for reducing element’s dependencies would be to introduce mediator class. In our case it will also cover cooling system functionality.public class Mediator { private Button button; private Fan fan; private PowerSupply PowerSupply; public Mediator() { this.button = new Button(this); this.fan = new Fan(this); this.PowerSupply = new PowerSupply(); } public void press() { if (fan.isOn()) { fan.turnOff(); } else { fan.turnOn(); } } public void start() { PowerSupply.turnOn(); } public void stop() { PowerSupply.turnOff(); } }Components should refer to mediator object and not each other, because mediator is taking care about system functionality and dependencies.
public class Button { private Mediator mediator; public Button(Mediator mediator){ this.mediator = mediator; } public void press() { mediator.press(); } }
public class Fan { private Mediator mediator; private boolean isOn = false; public Fan(Mediator mediator){ this.mediator = mediator; } public boolean isOn() { return isOn; } public void turnOn() { mediator.start(); isOn = true; } public void turnOff() { isOn = false; mediator.stop(); } }PowerSupply class does not require any changes. Also notice that Button and Fan classes are referencing back to Mediator class. We are ready for retesting our cooling system one more time.
public class CoolingSystem { public static void main(String[] args){ Mediator coolingSystem = new Mediator(); Button button = new Button(coolingSystem); button.press(); button.press(); } }
Pros
- 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.
- You can reduce coupling between various components of a program.
- You can reuse individual components more easily.
Cons
- Over time a mediator can evolve into a God Object.