3.5. Посредник (Mediator)

3.5.1. Назначение

Этот паттерн позволяет снизить связность множества компонентов, работающих совместно. Объектам больше нет нужды вызывать друг друга напрямую. Это хорошая альтернатива Наблюдателю, если у вас есть “центр интеллекта” вроде контроллера (но не в смысле MVC)

Все компоненты (называемые «Коллеги») объединяются в интерфейс Mediator и это хорошо, потому что в рамках ООП, «старый друг лучше новых двух».

3.5.2. Диаграмма UML

Alt Mediator UML Diagram

3.5.3. Код

Вы можете найти этот код на 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. Тест

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}