2.7. Фасад (Facade)
2.7.1. Назначение
The primary goal of a Facade Pattern is not to avoid you having to read the manual of a complex API. It’s only a side-effect. The first goal is to reduce coupling and follow the Law of Demeter.
Фасад предназначен для разделения клиента и подсистемы путем внедрения многих (но иногда только одного) интерфейсов, и, конечно, уменьшения общей сложности.
Фасад не запрещает прямой доступ к подсистеме. Просто он делает его проще и понятнее.
Вы можете (и вам стоило бы) иметь несколько фасадов для одной подсистемы.
Вот почему хороший фасад не содержит созданий экземпляров классов (new
) внутри. Если внутри фасада создаются объекты для реализации каждого метода, это не Фасад, это Строитель или [Абстрактная|Статическая|Простая] Фабрика [или Фабричный Метод].
Лучший фасад не содержит new
или конструктора с type-hinted параметрами. Если вам необходимо создавать новые экземпляры классов, в таком случае лучше использовать Фабрику в качестве аргумента.
2.7.2. Диаграмма UML
2.7.3. Код
Вы можете найти этот код на 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. Тест
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}