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:

  1. Mediator Interface: Mediator defines the notify() method for communication between colleague objects.
  2. Concrete Mediator: ConcreteMediator implements the Mediator interface and coordinates the interactions between Component1 and Component2.
  3. 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.