PHP 外觀模式

2022-03-21 18:05 更新

目的

外觀模式的目的不是為了讓你避免閱讀煩人的API文檔(當(dāng)然,它有這樣的作用),它的主要目的是為了減少耦合并且遵循得墨忒耳定律(Law of Demeter)

外觀模式通過嵌入多個(gè)(當(dāng)然,有時(shí)只有一個(gè))接口來解耦訪客與子系統(tǒng),當(dāng)然也降低復(fù)雜度。

  • Facade 不會(huì)禁止你訪問子系統(tǒng)
  • 你可以(應(yīng)該)為一個(gè)子系統(tǒng)提供多個(gè) Facade

因此一個(gè)好的 Facade 里面不會(huì)有 new 。如果每個(gè)方法里都要構(gòu)造多個(gè)對(duì)象,那么它就不是 Facade,而是生成器或者[抽象|靜態(tài)|簡(jiǎn)單] 工廠 [方法]。

優(yōu)秀的 Facade 不會(huì)有 new,并且構(gòu)造函數(shù)參數(shù)是接口類型的。如果你需要?jiǎng)?chuàng)建一個(gè)新實(shí)例,則在參數(shù)中傳入一個(gè)工廠對(duì)象。

UML 圖

Alt Facade UML Diagram

代碼

Facade.php

<?php

declare(strict_types=1);

namespace DesignPatterns\Structural\Facade;

class Facade
{
    public function __construct(private Bios $bios, private OperatingSystem $os)
    {
    }

    public function turnOn()
    {
        $this->bios->execute();
        $this->bios->waitForKeyPress();
        $this->bios->launch($this->os);
    }

    public function turnOff()
    {
        $this->os->halt();
        $this->bios->powerDown();
    }
}

OperatingSystem.php

<?php

declare(strict_types=1);

namespace DesignPatterns\Structural\Facade;

interface OperatingSystem
{
    public function halt();

    public function getName(): string;
}

Bios.php

<?php

declare(strict_types=1);

namespace DesignPatterns\Structural\Facade;

interface Bios
{
    public function execute();

    public function waitForKeyPress();

    public function launch(OperatingSystem $os);

    public function powerDown();
}

測(cè)試

Tests/FacadeTest.php

<?php

declare(strict_types=1);

namespace DesignPatterns\Structural\Facade\Tests;

use DesignPatterns\Structural\Facade\Bios;
use DesignPatterns\Structural\Facade\Facade;
use DesignPatterns\Structural\Facade\OperatingSystem;
use PHPUnit\Framework\TestCase;

class FacadeTest extends TestCase
{
    public function testComputerOn()
    {
        $os = $this->createMock(OperatingSystem::class);

        $os->method('getName')
            ->will($this->returnValue('Linux'));

        $bios = $this->createMock(Bios::class);

        $bios->method('launch')
            ->with($os);

        /** @noinspection PhpParamsInspection */
        $facade = new Facade($bios, $os);
        $facade->turnOn();

        $this->assertSame('Linux', $os->getName());
    }
}




以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)