3.5. Mediator

3.5.1. Propósito

Este patrón proporciona una forma sencilla de desacoplar muchos componentes que funcionan conjuntamente. Es una buena alternativa a Observer SI tiene una «inteligencia central» como un controlador (pero no en el sentido de MVC).

Todos los componentes (llamados Colleague) solo están acoplados a la interfaz del Mediator y es algo bueno porque en POO, un buen amigo es mejor que muchos. Esta es la característica clave de este patrón.

3.5.2. Diagrama UML

Alt Mediator UML Diagram

3.5.3. Código

Puedes encontrar el código en GitHub

Mediator.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php

declare(strict_types=1);

namespace DesignPatterns\Behavioral\Mediator;

interface Mediator
{
    public function getUser(string $username): string;
}

Colleague.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<?php

declare(strict_types=1);

namespace DesignPatterns\Behavioral\Mediator;

abstract class Colleague
{
    protected Mediator $mediator;

    public function setMediator(Mediator $mediator)
    {
        $this->mediator = $mediator;
    }
}

Ui.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php

declare(strict_types=1);

namespace DesignPatterns\Behavioral\Mediator;

class Ui extends Colleague
{
    public function outputUserInfo(string $username)
    {
        echo $this->mediator->getUser($username);
    }
}

UserRepository.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php

declare(strict_types=1);

namespace DesignPatterns\Behavioral\Mediator;

class UserRepository extends Colleague
{
    public function getUserName(string $user): string
    {
        return 'User: ' . $user;
    }
}

UserRepositoryUiMediator.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

declare(strict_types=1);

namespace DesignPatterns\Behavioral\Mediator;

class UserRepositoryUiMediator implements Mediator
{
    public function __construct(private UserRepository $userRepository, private Ui $ui)
    {
        $this->userRepository->setMediator($this);
        $this->ui->setMediator($this);
    }

    public function printInfoAbout(string $user)
    {
        $this->ui->outputUserInfo($user);
    }

    public function getUser(string $username): string
    {
        return $this->userRepository->getUserName($username);
    }
}

3.5.4. Test

Tests/MediatorTest.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

declare(strict_types=1);

namespace DesignPatterns\Tests\Mediator\Tests;

use DesignPatterns\Behavioral\Mediator\Ui;
use DesignPatterns\Behavioral\Mediator\UserRepository;
use DesignPatterns\Behavioral\Mediator\UserRepositoryUiMediator;
use PHPUnit\Framework\TestCase;

class MediatorTest extends TestCase
{
    public function testOutputHelloWorld()
    {
        $mediator = new UserRepositoryUiMediator(new UserRepository(), new Ui());

        $this->expectOutputString('User: Dominik');
        $mediator->printInfoAbout('Dominik');
    }
}