Mediator pattern with an example of a chat room
Behavioral design pattern: Behavioral patterns are concerned with algorithms and assigning responsibilities between objects.
Mediator is a behavioral design pattern. This pattern allows objects to communicate with each other without the need for them to be aware of each other’s identities. It defines a mediator object that encapsulates the coordination logic between multiple objects.
A Real-World Analogy
Think about an airport traffic system.
There is no direct communication between the pilots of aircraft as they enter or leave the airport control area. Instead, they converse with a controller of air traffic who is stationed in a large tower not far from the runway. Without the air traffic controller, pilots would have to be informed of every aircraft in the area of the airport and decide which planes should land first with a group of several other pilots. The number of aircraft crashes would most likely increase dramatically.
The entire flight need not be under the direction of the tower. Its sole purpose is to enforce limitations at the terminal area since the sheer quantity of participants there might be too much for a pilot to handle.
Chat room example:
As a real-life example of the Mediator pattern, I am using an online chat system. The chat system could have individual chat rooms and users. Without the Mediator pattern, each user would need to be aware of all other users and chat rooms in order to send messages. But with the Mediator pattern, the users only need to be aware of the mediator object, which handles the routing of messages between users and chat rooms.
Here is an example of how the Mediator pattern could be implemented using PHP:
In this example, the ChatMediator
class acts as the mediator and coordinates communication between ChatUser
objects. The ChatUser objects only need to be aware of the ChatMediator and can send messages to other users through it, without needing to know the identities of the other users.
Mediator interface:
interface Mediator
{
public function send($message, $colleague);
}
Mediator class:
class ChatMediator implements Mediator
{
private $users;
public function __construct()
{
$this->users = array();
}
public function addUser($user)
{
$this->users[] = $user;
}
public function send($message, $sender)
{
foreach ($this->users as $user) {
if ($user != $sender) {
$user->receive($message);
}
}
}
}
Abstract User class:
abstract class User
{
protected $mediator;
public function __construct($mediator)
{
$this->mediator = $mediator;
}
public function send($message)
{
$this->mediator->send($message, $this);
}
abstract public function receive($message);
}
Now, the Client code:
$mediator = new ChatMediator();
$john = new ChatUser($mediator, 'John');
$jane = new ChatUser($mediator, 'Jane');
$mediator->addUser($john);
$mediator->addUser($jane);
$john->send('Hi there!');
$jane->send('Hello!');
In this example, two ChatUser objects, “John” and “Jane”, are created and added to the ChatMediator. Then, “John” sends the message “Hi there!” and “Jane” sends the message “Hello!”.
When “John” sends a message, the ChatMediator’s send() method is called with the message and the sender, “John”. The send() method then iterates through all users and calls the receive() method on each user except the sender. So, in this case, “Jane” receives the message “Hi there!”. The same happens when “Jane” sends the message “Hello!”, “John” receives the message.
As a result, the two users can communicate with each other via the mediator, without the need to have direct references to each other. Also, the new user could be added to the chat room without changing any other code and the users could communicate with each other without knowing who is in the room.
In this way, the Mediator design pattern facilitates loose coupling between objects, making it easier to modify or extend the system in the future. It also provides a single point of control for managing communication between objects, making the communication logic more centralized and easier to understand.
Hope it helps to understand the Mediator pattern.
You can find this code example in this github repository
Happy coding 🙂