PHP設計模式之外觀模式

echo_dump發表於2020-08-07

外觀模式

  • 外觀類 為呼叫端提供統一的呼叫介面,外觀類知到那些子系統負責處理請求,從而將呼叫端的請求代理給適當的子系統
  1. 外觀模式對外遮蔽了子系統的細節,因此外觀模式降低了客戶端對子系統的使用的複雜性

  2. 外觀模式對客戶端與子系統的耦合關係,讓子系統內部的模組更容易維護和擴充套件

  3. 透過合理的使用外觀模式,可以更好的劃分訪問的層次

生活舉例,比如有一個影院系統,影院裡有DVD,投影儀,爆米花機,幕布,音響,燈光,總共有這麼多裝置,我們去電影院開電影呢,使用者是不關心影院怎麼
工作的,使用者只關心的電影開始,暫停,繼續播放,結束,他們關心的只有這四個階段,至於電影院怎麼開啟燈光,拉下幕布,開啟投影儀,除錯音響,開啟DVD
這些工作,使用者都不需要知道,他們使用的時候,只需要知道上面說的四個階段就好了,這樣就降低了對使用者來說這個系統的複雜度,而且對維護者來說也是更加
的利於維護,那個階段出了問題,分四步走,哪一個步驟有問題,一目瞭然。而這裡,剛好就可以使用外觀模式來嘗試一下做這個事情。

具體的實現:

  1. 建立一個DVD類,dvd可以開啟,暫停,繼續播放,結束關閉
class DvdPlayer
{
    public static $instance = null;

    public static function getInstance()
    {
        if (self::$instance === null) {
            static::$instance = new self();
        }
        return static::$instance;
    }

    public function on()
    {
        var_dump("開啟 DVD");
    }

    public function off()
    {
        var_dump("關閉DVD");
    }

    public function play()
    {
        var_dump("開始播播放DVD");
    }

    public function suspend()
    {
        var_dump("暫停播放DVD");
    }
}
  1. 燈光類,開啟燈,關閉燈
class TheaterLight
{
    public static $instance = null;

    public static function getInstance()
    {
        if (self::$instance === null) {
            static::$instance = new self();
        }
        return static::$instance;
    }

    public function on()
    {
        var_dump("開啟燈光");
    }

    public function off()
    {
        var_dump("關閉燈光");
    }
}
  1. 音響類,開啟音響,關閉音響,加大聲音,減小聲音
class Stereo
{
    public static $instance = null;

    public static function getInstance()
    {
        if (self::$instance === null) {
            static::$instance = new self();
        }
        return static::$instance;
    }

    public function on()
    {
        var_dump("開啟音響");
    }

    public function off()
    {
        var_dump("關閉音響");
    }

    public function volumeUp()
    {
       var_dump("加大音量"); 
    }

    public function volumeDown()
    {
        var_dump("減小音量");
    }
}
  1. 娛樂爆米花類,開啟爆米花機,製作爆米花,關閉爆米花機
class Popcorn
{
    public static $instance = null;

    public static function getInstance()
    {
        if (self::$instance === null) {
            static::$instance = new self();
        }
        return static::$instance;
    }

    public function on()
    {
        var_dump("開啟爆米花機");
    }

    public function up()
    {
        var_dump("關閉爆米花機");
    }

    public function make()
    {
        var_dump("製作爆米花");
    }
}
  1. 投影儀類,開啟投影儀,關閉投影儀
class Projector
{
    public static $instance = null;

    public static function getInstance()
    {
        if (self::$instance === null) {
            static::$instance = new self();
        }
        return static::$instance;
    }

    public function on()
    {
        var_dump("開啟投影儀");
    }

    public function off()
    {
        var_dump("關閉投影儀"); 
    }
}
  1. 幕布類,放下幕布,升起幕布
class Screen
{
    public static $instance = null;

    public static function getInstance()
    {
        if (self::$instance === null) {
            static::$instance = new self();
        }
        return static::$instance;
    }

    public function down()
    {
        var_dump("放下幕布");
    }

    public function up()
    {
        var_dump("升起幕布");
    }
}
  1. 影院的外觀類,電影開始,暫停,繼續播放,結束,在這裡,把所有的子系統全部集中到影院的外觀類裡,使用私有的屬性儲存各個子系統,為了簡單起見,
    沒有使用依賴注入,而是使用單例模式來獲取各個子系統。
class HomeFacade
{
    private $dvd;

    private $theaterLight;

    private $popcorn;

    private $stereo;

    private $projector;

    private $screen;

    public function __construct()
    {
        $this->dvd = DvdPlayer::getInstance();

        $this->theaterLight = TheaterLight::getInstance();

        $this->popcorn = Popcorn::getInstance();

        $this->stereo = Stereo::getInstance();

        $this->projector = Projector::getInstance();

        $this->screen = Screen::getInstance();
    }

    public function ready()
    {
        //開啟
        echo "#################" . PHP_EOL;
        $this->theaterLight->on();//燈
        $this->popcorn->on();//爆米花
        $this->popcorn->make();
        $this->screen->down();//幕布
        $this->projector->on();//投影儀
        $this->stereo->on();//音響
        $this->dvd->on();//dvd
    }

    public function play()
    {
        echo "#################" . PHP_EOL;
        $this->theaterLight->off();
        $this->dvd->play();
        $this->stereo->volumeUp();
        //播放
    }

    public function pause()
    {
        echo "#################" . PHP_EOL;
       //暫停
        $this->dvd->suspend();
    }

    public function end()
    {
        echo "#################" . PHP_EOL;
        //結束
        $this->theaterLight->on();
        $this->stereo->volumeDown();
        $this->dvd->off();
        $this->stereo->off();
        $this->projector->off();
        $this->screen->up();
        $this->popcorn->off();
        $this->theaterLight->off();
    }

}
  1. 最後客戶端的呼叫
class Client
{
    public function __construct(HomeFacade $facade)
    {
        $facade->ready();

        $facade->play();

        $facade->pause();

        $facade->end();
    }
}
  1. 完整輸出:
#################
string(12) "開啟燈光"
string(18) "開啟爆米花機"
string(15) "製作爆米花"
string(12) "放下幕布"
string(15) "開啟投影儀"
string(12) "開啟音響"
string(10) "開啟 DVD"
#################
string(12) "關閉燈光"
string(18) "開始播播放DVD"
string(12) "加大音量"
#################
string(15) "暫停播放DVD"
#################
string(12) "開啟燈光"
string(12) "減小音量"
string(9) "關閉DVD"
string(12) "關閉音響"
string(15) "關閉投影儀"
string(12) "升起幕布"
string(18) "關閉爆米花機"
string(12) "關閉燈光"
本作品採用《CC 協議》,轉載必須註明作者和本文連結
LIYi ---- github地址

相關文章