外觀模式
- 外觀類 為呼叫端提供統一的呼叫介面,外觀類知到那些子系統負責處理請求,從而將呼叫端的請求代理給適當的子系統
外觀模式對外遮蔽了子系統的細節,因此外觀模式降低了客戶端對子系統的使用的複雜性
外觀模式對客戶端與子系統的耦合關係,讓子系統內部的模組更容易維護和擴充套件
透過合理的使用外觀模式,可以更好的劃分訪問的層次
生活舉例,比如有一個影院系統,影院裡有DVD,投影儀,爆米花機,幕布,音響,燈光,總共有這麼多裝置,我們去電影院開電影呢,使用者是不關心影院怎麼
工作的,使用者只關心的電影開始,暫停,繼續播放,結束,他們關心的只有這四個階段,至於電影院怎麼開啟燈光,拉下幕布,開啟投影儀,除錯音響,開啟DVD
這些工作,使用者都不需要知道,他們使用的時候,只需要知道上面說的四個階段就好了,這樣就降低了對使用者來說這個系統的複雜度,而且對維護者來說也是更加
的利於維護,那個階段出了問題,分四步走,哪一個步驟有問題,一目瞭然。而這裡,剛好就可以使用外觀模式來嘗試一下做這個事情。
具體的實現:
- 建立一個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");
}
}
- 燈光類,開啟燈,關閉燈
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("關閉燈光");
}
}
- 音響類,開啟音響,關閉音響,加大聲音,減小聲音
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("減小音量");
}
}
- 娛樂爆米花類,開啟爆米花機,製作爆米花,關閉爆米花機
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("製作爆米花");
}
}
- 投影儀類,開啟投影儀,關閉投影儀
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("關閉投影儀");
}
}
- 幕布類,放下幕布,升起幕布
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("升起幕布");
}
}
- 影院的外觀類,電影開始,暫停,繼續播放,結束,在這裡,把所有的子系統全部集中到影院的外觀類裡,使用私有的屬性儲存各個子系統,為了簡單起見,
沒有使用依賴注入,而是使用單例模式來獲取各個子系統。
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();
}
}
- 最後客戶端的呼叫
class Client
{
public function __construct(HomeFacade $facade)
{
$facade->ready();
$facade->play();
$facade->pause();
$facade->end();
}
}
- 完整輸出:
#################
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地址