The Mediator pattern facilitates communication between components without having references to each other. It avoids tight coupling between components and helps maintainability.
Let’s say we are building a user interface to visualizes photos. There are multiple components such as the image, the title, the author, the image exif info, the comments, the thumbnail bar, etc. When a user selects a new image, all those components need to be updated. Without the Mediator pattern, the “next” button would call all the components to update them.
public class NextButton {
private Display imageDisplay;
private Label title;
private Label author;
...
public onClick() {
// some code to get the image
imageDisplay.goto(image);
title.set(image);
author.set(image);
// etc...
}
}
We can also imagine that adding a comment would update the title of the image with the total count of comments. It would mean that the comment section has a reference on the title. All those components would be tightly linked.
The Mediator pattern introduces a new component which would be the only one with references to all the different components. Whenever a component needs to communicate with the others, it would send a message to the mediator which then dispatch it to the others.
In our case, the click on “Next” would send an event.
public class NextButton implements UIComponent { private EventBroker mediator; public void onClick() { // some code to get the image mediator.publish(new Event("updateImage")); } public void listen(Event e) { // do something when necessary } }
The mediator would then publish the events to all the components that are listening.
public class EventBroker { private List<UIComponent> components; public void subscribe(UIComponent component) { components.add(component); } public void publish(Event e) { components.foreach(it -> it.listen(e)); } }