門面模式,也叫外觀模式,不管是門面還是外觀,都是我們對外的媒介,就好像我們的臉面一樣,所以,這個模式最大的特點就是要表現的“好看”,怎么說呢?一堆復雜的物件呼叫,自己都看蒙了,特別是對老系統進行升級維護的時候,用門面來把老系統的功能呼叫封裝起來,在外面看來就和新系統一樣,這就是門面模式的用途啦!
Gof類圖及解釋
GoF定義:為子系統中的一組介面提供一個一致的界面,Facade模式定義了一個高層介面,這個介面使得這一子系統更加容易使用,
GoF類圖

代碼實作
class SubSystemOne
{
public function MethodOne()
{
echo '子系統方法一', PHP_EOL;
}
}
class SubSystemTwo
{
public function MethodTwo()
{
echo '子系統方法二', PHP_EOL;
}
}
class SubSystemThree
{
public function MethodThree()
{
echo '子系統方法三', PHP_EOL;
}
}
class SubSystemFour
{
public function MethodFour()
{
echo '子系統方法四', PHP_EOL;
}
}
定義四個或者N多個子系統,這個沒什么好說的吧,可以想象是很多子系統,而且他們之間并不一定和這四個子系統一樣的相似,有可能是千差萬別的,
class Facade
{
private $subStytemOne;
private $subStytemTwo;
private $subStytemThree;
private $subStytemFour;
public function __construct()
{
$this->subSystemOne = new SubSystemOne();
$this->subSystemTwo = new SubSystemTwo();
$this->subSystemThree = new SubSystemThree();
$this->subSystemFour = new SubSystemFour();
}
public function MethodA()
{
$this->subSystemOne->MethodOne();
$this->subSystemTwo->MethodTwo();
}
public function MethodB()
{
$this->subSystemOne->MethodOne();
$this->subSystemTwo->MethodTwo();
$this->subSystemThree->MethodThree();
$this->subSystemFour->MethodFour();
}
}
通過門面類將這些子系統包裝起來,對外提供的只是門面新定義的方法,
$facade = new Facade();
$facade->MethodA();
$facade->MethodB();
客戶端的呼叫就非常簡單了,我們不用知道具體呼叫了哪些子系統,只需要知道門面的這些方法干什么了就行啦!
- 門面模式就是這么的簡單,而且只要是真實的在專案中做過開發的朋友一定在不知不覺中就已經使用過這個模式了
- 當你需要為一個復雜子系統提供一個簡單的介面時,門面模式就非常適用,同時,如果客戶程式與抽象類的實作部分之間存在著很大的依賴性時,也可以引入門面模式來進行解耦,提高子系統的獨立性和可維護性,另外就是你需要構建一個層次結構的子系統時,門面可以充當每層子系統的入口點
- Laravel中的門面系統相信使用過框架的人一定都用過,比如:Cache::put(),在Laravel中,門面的實作使用了一個魔術方法__callStatic(),然后讓物件的方法可以實作直接使用靜態方法來進行呼叫,是不是很神奇,有興趣的朋友可以翻翻原始碼,就在/Illuminate/Support/Facades/Facade.php中,
- 劃重點:三層結構或者MVC也是門面模式的體現哦,上面說了,門面模式適合分層子系統的維護,而三層結構、MVC、MVP、MVVM這些貨,本質上都是為了分層,而分層的目的,就是為了降低系統的復雜性,
光賣我們的手機可不行,向X米一樣做高科技的家電企業才是我們最終的目標,不過那么多的家電產品我們可生產不過來,于是,我們決定做一個商城(Facade)讓一些質量非常好的商家加入我們的陣營,將他們的產品(SubSystem)放到商城中一起賣,當然,這些商品可是經過我們慎重挑選的,絕對都是優品中的優品哦!!
完整代碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/19.facade/source/facade.php
實體
這回我們將短信的發送以發送的維度進行包裝,將不同的短信和推送運營商的介面包裝起來,在發送的時候只需要通過發送類就可以控制用不同的第三方服務進行短信或推送的發送啦,想想都很方便呢!
短信發送類圖

完整原始碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/19.facade/source/facade-push.php
<?php
class Send
{
private $aliYunService;
private $jiGuangService;
private $message;
private $push;
public function __construct()
{
$this->aliYunService = new AliYunService();
$this->jiGuangService = new JiGuangService();
$this->message = new MessageInfo();
$this->push = new PushInfo();
}
public function PushAndSendAliYun()
{
$this->message->Send($this->aliYunService);
$this->push->Push($this->aliYunService);
}
public function PushAndSendJiGuang()
{
$this->message->Send($this->jiGuangService);
$this->push->Push($this->jiGuangService);
}
}
class MessageInfo
{
public function Send($service)
{
$service->Send();
}
}
class PushInfo
{
public function Push($service)
{
$service->Push();
}
}
class AliYunService
{
public function Send()
{
echo '發送阿里云短信!', PHP_EOL;
}
public function Push()
{
echo '推送阿里云通知!', PHP_EOL;
}
}
class JiGuangService
{
public function Send()
{
echo '發送極光短信!', PHP_EOL;
}
public function Push()
{
echo '推送極光通知!', PHP_EOL;
}
}
$send = new Send();
$send->PushAndSendAliYun();
$send->PushAndSendJiGuang();
說明
- 依然還是熟悉的配方熟悉的味道,在這里,可以想象我們的第三方服務類都是較老的介面,或者已經是很復雜的介面了,這時,使用外觀模式一來是可以與新系統配合,二來也能降低復雜度
- 但是要注意的,外觀類本身可能成為復雜度的來源,不過幸好我們可以遵從單一職責的原則,一個外觀類就做一件事就好啦
下期看點
外觀模式其實并沒有太多可說的,因為它確實非常簡單而且無處不在,不要被Laravel花哨的Facade類所欺騙,它并沒有那么的復雜,下回我們學習到的依然是一個非常簡單而且在不知不覺中就會用到的模式:模板方法模式
關注公眾號:【硬核專案經理】獲取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、專案管理學習資料
知乎、公眾號、抖音、頭條搜索【硬核專案經理】
B站ID:482780532
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/244559.html
標籤:PHP
上一篇:LeetCode遞增順序查找樹
