3.5. Mediator

3.5.1. Scopo

Questo pattern permette di disaccoppiare facilmente molti componenti che collaborano insieme. È una buona alternativa all’Observer SE hai una sorta di «intelligenza centrale», come un controller (ma non nel senso MVC).

Tutti i componenti (chiamati Colleghi) sono accoppiati unicamente dall’intefaccia del Mediatore ed è una buona cosa in quanto nella programmazione OO, un buon amico è meglio di tanti. Questa è la caratteristica chiave di questo pattern.

3.5.2. Diagramma UML

Alt Mediator UML Diagram

3.5.3. Codice

Potete trovare questo codice anche su GitHub

Mediator.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Behavioral\Mediator;
 6
 7interface Mediator
 8{
 9    public function getUser(string $username): string;
10}

Colleague.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Behavioral\Mediator;
 6
 7abstract class Colleague
 8{
 9    protected Mediator $mediator;
10
11    final public function setMediator(Mediator $mediator)
12    {
13        $this->mediator = $mediator;
14    }
15}

Ui.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Behavioral\Mediator;
 6
 7class Ui extends Colleague
 8{
 9    public function outputUserInfo(string $username)
10    {
11        echo $this->mediator->getUser($username);
12    }
13}

UserRepository.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Behavioral\Mediator;
 6
 7class UserRepository extends Colleague
 8{
 9    public function getUserName(string $user): string
10    {
11        return 'User: ' . $user;
12    }
13}

UserRepositoryUiMediator.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Behavioral\Mediator;
 6
 7class UserRepositoryUiMediator implements Mediator
 8{
 9    public function __construct(private UserRepository $userRepository, private Ui $ui)
10    {
11        $this->userRepository->setMediator($this);
12        $this->ui->setMediator($this);
13    }
14
15    public function printInfoAbout(string $user)
16    {
17        $this->ui->outputUserInfo($user);
18    }
19
20    public function getUser(string $username): string
21    {
22        return $this->userRepository->getUserName($username);
23    }
24}

3.5.4. Test

Tests/MediatorTest.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Tests\Mediator\Tests;
 6
 7use DesignPatterns\Behavioral\Mediator\Ui;
 8use DesignPatterns\Behavioral\Mediator\UserRepository;
 9use DesignPatterns\Behavioral\Mediator\UserRepositoryUiMediator;
10use PHPUnit\Framework\TestCase;
11
12class MediatorTest extends TestCase
13{
14    public function testOutputHelloWorld()
15    {
16        $mediator = new UserRepositoryUiMediator(new UserRepository(), new Ui());
17
18        $this->expectOutputString('User: Dominik');
19        $mediator->printInfoAbout('Dominik');
20    }
21}