在之前的文章《一起聊聊PHP中的備忘錄模式》中我們介紹了PHP中的備忘錄模式,下面這篇文章帶大家了解一下PHP設計模式中的橋接模式。
橋接模式,在程式世界中,其實就是組合/聚合的代名詞。為什麼這麼說呢?熟悉物件導向的我們都知道繼承的好處,子類別可以共享父類別的許多屬性、功能。但是,繼承也會帶來一個問題,那就是嚴重的耦合性。父類別的修改多少都會對子類別產生影響,甚至一個方法或屬性的修改都有可能讓所有子類別都去修改一遍。這樣就違背了開放性封裝原則。而橋接就是為了解決這個問題,它強調的是用組合/聚合的方式來共享一些能用的方法。相信大家一定想到了php中的trait,如果你在工作上使用過這個特性,那麼你就已經用過橋接模式了!
GoF定義:將抽象部分與它的實作部分分離,使它們都可以獨立地變更。
GoF類別圖
#程式碼實作
interface Implementor { public function OperationImp(); } class ConcreteImplementorA implements Implementor { public function OperationImp() { echo '具体实现A', PHP_EOL; } } class ConcreteImplementorB implements Implementor { public function OperationImp() { echo '具体实现B', PHP_EOL; } }
我們先來定義實作介面以及它們具體的實現,也就是真正要執行的功能。就像是適配器模式中的Adaptee。
abstract class Abstraction { protected $imp; public function SetImplementor(Implementor $imp) { $this->imp = $imp; } abstract public function Operation(); } class RefinedAbstraction extends Abstraction { public function Operation() { $this->imp->OperationImp(); } }
定義抽象類別的接口,並維護一個對實作的參考。在具體的抽象類別的實作方法中,我們直接呼叫實作介面的真實操作方法。類似於適配器中的Adapter。
$impA = new ConcreteImplementorA(); $impB = new ConcreteImplementorB(); $ra = new RefinedAbstraction(); $ra->SetImplementor($impA); $ra->Operation(); $ra->SetImplementor($impB); $ra->Operation();
客戶端調用,我們的抽象類別使用不使用的實作類別就可以讓操作方法變成多態的感覺。
我們的手機有不同的型號,每個型號又要生產大致相同但不同的配件。例如X1手機殼、貼膜、耳機;X2的手機殼、貼膜、耳機等。受限於成本的問題,我們不會給每個型號的手機都去生產完全不一樣的配套配件。而是去盡量使用外部通用的配件(Implementor),讓每一種型號的手機(Abstraction)去進行組合(Bridge),搭配售賣給消費者。這樣,才不至於讓我們的手機品牌太早的消耗完融資關門大吉。看來,做企業和學設計模式還真是有很多相關之處! !
完整程式碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/18.bridge/source/bridge.php
我們的簡訊傳送也可以用橋接來實現。假設我們有很多的簡訊模板,然後搭配不同的簡訊提供者進行簡訊的發送。這時,我們就可以用橋接模式來形成各種不同的組合。
簡訊發送類別圖
#完整原始碼:https://github.com/zhangyue0503/designpatterns-php /blob/master/18.bridge/source/bridge-message.php
<?php interface MessageTemplate { public function GetTemplate(); } class LoginMessage implements MessageTemplate { public function GetTemplate() { echo '您的登录验证码是【AAA】,请不要泄露给他人【XXX公司】!', PHP_EOL; } } class RegisterMessage implements MessageTemplate { public function GetTemplate() { echo '您的注册验证码是【BBB】,请不要泄露给他人【XXX公司】!', PHP_EOL; } } class FindPasswordMessage implements MessageTemplate { public function GetTemplate() { echo '您的找回密码验证码是【CCC】,请不要泄露给他人【XXX公司】!', PHP_EOL; } } abstract class MessageService { protected $template; public function SetTemplate($template) { $this->template = $template; } abstract public function Send(); } class AliYunService extends MessageService { public function Send() { echo '阿里云开始发送短信:'; $this->template->GetTemplate(); } } class JiGuangService extends MessageService { public function Send() { echo '极光开始发送短信:'; $this->template->GetTemplate(); } } // 三个短信模板 $loginTemplate = new LoginMessage(); $registerTemplate = new RegisterMessage(); $findPwTemplate = new FindPasswordMessage(); // 两个短信服务商 $aliYun = new AliYunService(); $jg = new JiGuangService(); // 随意组合 // 极光发注册短信 $jg->SetTemplate($registerTemplate); $jg->Send(); // 阿里云发登录短信 $aliYun->SetTemplate($loginTemplate); $aliYun->Send(); // 阿里云发找回密码短信 $aliYun->SetTemplate($findPwTemplate); $aliYun->Send(); // 极光发登录短信 $jg->SetTemplate($loginTemplate); $jg->Send(); // ......
說明
原文網址:https://juejin.cn/post/6844903986655395848#作者:硬派專案經理
推薦學習:《PHP影片教學》
以上是淺談PHP中的橋接模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!