The Mediator Design Pattern is a behavioral design pattern that promotes loose coupling between objects by introducing a mediator object that acts as an intermediary between the objects. This pattern is useful when a system contains a large number of interacting objects, and direct communication between them would result in a complex and tightly coupled system. The Mediator Design Pattern helps to reduce the complexity by centralizing the communication between the objects through the mediator.
In this article, we will explore the Mediator Design Pattern in Java, including its structure, implementation, and use cases.
Structure of the Mediator Design Pattern:
The Mediator Design Pattern consists of the following components:
Mediator: This is an interface that defines the methods used by the objects to communicate with each other.
ConcreteMediator: This is a class that implements the Mediator interface and manages the communication between the objects. It maintains references to all the objects that it is mediating.
Colleague: This is an interface that defines the methods used by the objects to communicate with the mediator.
ConcreteColleague: This is a class that implements the Colleague interface and interacts with other objects through the mediator.
Implementation of the Mediator Design Pattern:
import java.util.ArrayList;
import java.util.List;
interface Mediator {
void sendMessage(String message, Colleague colleague);
}
interface Colleague {
void sendMessage(String message);
void receiveMessage(String message);
}
class ConcreteMediator implements Mediator {
private List colleagues;
public ConcreteMediator() {
colleagues = new ArrayList<>();
}
public void addColleague(Colleague colleague) {
colleagues.add(colleague);
}
public void sendMessage(String message, Colleague sender) {
for (Colleague colleague : colleagues) {
if (colleague != sender) {
colleague.receiveMessage(message);
}
}
}
}
class ConcreteColleague implements Colleague {
private Mediator mediator;
private String name;
public ConcreteColleague(Mediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public void sendMessage(String message) {
mediator.sendMessage(message, this);
}
public void receiveMessage(String message) {
System.out.println(name + " received message: " + message);
}
}
public class MediatorExample {
public static void main(String[] args) {
Mediator mediator = new ConcreteMediator();
Colleague colleague1 = new ConcreteColleague(mediator, "Colleague 1");
Colleague colleague2 = new ConcreteColleague(mediator, "Colleague 2");
Colleague colleague3 = new ConcreteColleague(mediator, "Colleague 3");
mediator.addColleague(colleague1);
mediator.addColleague(colleague2);
mediator.addColleague(colleague3);
colleague1.sendMessage("Hello World!");
colleague2.sendMessage("How are you?");
colleague3.sendMessage("Fine, thanks!");
}
}
In this example, we first define two interfaces – Mediator and Colleague. The Mediator interface declares a method sendMessage that is used by the colleagues to communicate with each other through the mediator. The Colleague interface declares two methods – sendMessage to send messages to other colleagues and receiveMessage to receive messages from other colleagues.
We then define two classes – ConcreteMediator and ConcreteColleague. The ConcreteMediator class implements the Mediator interface and manages the communication between the colleagues. It maintains a list of all the colleagues and when a colleague sends a message, it broadcasts the message to all the other colleagues except the sender.
The ConcreteColleague class implements the Colleague interface and interacts with other colleagues through the mediator. When a colleague sends a message, it calls the sendMessage method of the mediator and passes the message along with a reference to itself as the sender. When a colleague receives a message, it simply prints out the message.
Finally, in the main method, we create an instance of the ConcreteMediator class and register three ConcreteColleague objects with it. We then simulate some interactions between the colleagues by calling their sendMessage methods. When a colleague sends a message, the mediator broadcasts it to all the other colleagues, who receive the message and print it out.
This is a simple example, but it illustrates the basic structure and functionality of the Mediator Design Pattern. In a real-world application, the Mediator Design Pattern can be used to manage the interactions between a large number of objects in a more scalable and maintainable way.