2.7. Facade (Fachada)
2.7.1. Objetivo
O principal objetivo de um Facade Pattern não é evitar que você tenha que ler o manual de uma API complexa. É apenas um efeito colateral. O primeiro objetivo é reduzir o acoplamento e seguir a Lei de Demeter.
Uma Facade destina-se a dissociar um cliente e um subsistema, incorporando muitas (porém as vezes apenas uma) interface e, é claro, para reduzir a complexidade.
Uma Facade não proibe você de acessar o sub-sistema
Você pode (você deve) ter múltiplas facades para um sub-sistema
É por isso que uma boa facade não tem nenhum new
nela. Se há multiplas criações para cada método, ela não é uma facade, ela é uma Builder (Construtora) ou uma [Abstract|Static|Simple] Factory (Fábrica) [Method].
A melhor facade não tem nenhum new
e um construtor com parâmetros interface-type-hinted. Se você precisa da criação de novas instâncias, use uma Factory (Fábrica) como argumento.
2.7.2. Diagrama UML
2.7.3. Código
Você também pode encontrar este código no GitHub
Facade.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\Facade;
6
7class Facade
8{
9 public function __construct(private Bios $bios, private OperatingSystem $os)
10 {
11 }
12
13 public function turnOn()
14 {
15 $this->bios->execute();
16 $this->bios->waitForKeyPress();
17 $this->bios->launch($this->os);
18 }
19
20 public function turnOff()
21 {
22 $this->os->halt();
23 $this->bios->powerDown();
24 }
25}
OperatingSystem.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\Facade;
6
7interface OperatingSystem
8{
9 public function halt();
10
11 public function getName(): string;
12}
Bios.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\Facade;
6
7interface Bios
8{
9 public function execute();
10
11 public function waitForKeyPress();
12
13 public function launch(OperatingSystem $os);
14
15 public function powerDown();
16}
2.7.4. Teste
Tests/FacadeTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\Facade\Tests;
6
7use DesignPatterns\Structural\Facade\Bios;
8use DesignPatterns\Structural\Facade\Facade;
9use DesignPatterns\Structural\Facade\OperatingSystem;
10use PHPUnit\Framework\TestCase;
11
12class FacadeTest extends TestCase
13{
14 public function testComputerOn()
15 {
16 $os = $this->createMock(OperatingSystem::class);
17
18 $os->method('getName')
19 ->will($this->returnValue('Linux'));
20
21 $bios = $this->createMock(Bios::class);
22
23 $bios->method('launch')
24 ->with($os);
25
26 /** @noinspection PhpParamsInspection */
27 $facade = new Facade($bios, $os);
28 $facade->turnOn();
29
30 $this->assertSame('Linux', $os->getName());
31 }
32}