On this page
17. Mediator
The Mediator pattern is a behavioral design pattern that defines an object that encapsulates how a set of objects interact. It promotes loose coupling by preventing objects from referring to each other explicitly and allows their interaction to be managed by a mediator object.
Key Characteristics:
- Centralized Control: Manages communication between objects, promoting loose coupling.
- Encapsulation of Interaction: Encapsulates the interaction logic between multiple objects.
- Simplified Communication: Reduces the dependencies between objects, making the system more maintainable.
How It Works:
- Mediator Interface: Defines an interface for communicating with colleague objects.
- Concrete Mediator: Implements the mediator interface and coordinates communication between colleague objects.
- Colleague Classes: Classes that interact with each other through the mediator. They communicate only with the mediator, not directly with each other.
Example in PHP:
// Mediator Interface
interface Mediator {
public function notify($sender, $event);
}
// Concrete Mediator
class ConcreteMediator implements Mediator {
private $component1;
private $component2;
public function __construct(Component1 $c1, Component2 $c2) {
$this->component1 = $c1;
$this->component2 = $c2;
$this->component1->setMediator($this);
$this->component2->setMediator($this);
}
public function notify($sender, $event) {
if ($event === "A") {
echo "Mediator reacts on A and triggers following operations:\n";
$this->component2->doC();
} elseif ($event === "B") {
echo "Mediator reacts on B and triggers following operations:\n";
$this->component1->doA();
}
}
}
// Abstract Colleague
abstract class Colleague {
protected $mediator;
public function setMediator(Mediator $mediator) {
$this->mediator = $mediator;
}
}
// Concrete Colleague 1
class Component1 extends Colleague {
public function doA() {
echo "Component1 does A.\n";
$this->mediator->notify($this, "A");
}
public function doB() {
echo "Component1 does B.\n";
$this->mediator->notify($this, "B");
}
}
// Concrete Colleague 2
class Component2 extends Colleague {
public function doC() {
echo "Component2 does C.\n";
}
}
// Client Code
$c1 = new Component1();
$c2 = new Component2();
$mediator = new ConcreteMediator($c1, $c2);
$c1->doA(); // Output: Component1 does A.
// Mediator reacts on A and triggers following operations:
// Component2 does C.
$c1->doB(); // Output: Component1 does B.
// Mediator reacts on B and triggers following operations:
// Component1 does A.
Explanation:
- Mediator Interface: Mediator defines the notify() method for communication between colleague objects.
- Concrete Mediator: ConcreteMediator implements the Mediator interface and coordinates the interactions between Component1 and Component2.
- Colleague Classes: Component1 and Component2 represent objects that interact through the mediator. They do not communicate directly with each other but rely on the mediator.
Benefits:
- Decoupling: Reduces the dependency between objects, promoting loose coupling and easier maintenance.
- Centralized Communication: Centralizes the interaction logic, making it easier to manage and modify.
- Enhanced Maintainability: Simplifies the modification of interactions between objects without changing their internal implementations.
Use Cases:
- Complex Interaction Scenarios: When multiple objects need to interact in complex ways and direct communication would lead to a tightly coupled system.
- GUI Systems: Managing interactions between GUI components (like buttons, text fields, etc.) through a mediator.
- Communication Systems: Handling communication between different parts of a system, such as between different modules or services.
The Mediator pattern is useful for managing complex interactions between objects, reducing coupling, and centralizing communication logic in a way that enhances the maintainability and flexibility of the system.