桥接模式,在程序世界中,其实就是组合/聚合的代名词。为什么这么说呢?熟悉面向对象的我们都知道继承的好处,子类可以共享父类的很多属性、功能。但是,继承也会带来一个问题,那就是严重的耦合性。父类的修改多少都会对子类产生影响,甚至一个方法或属性的修改都有可能让所有子类都去修改一遍。这样就违背了开放封装原则。而桥接就是为了解决这个问题,它强调的是用组合/聚合的方式来共享一些能用的方法。相信大家一定想到了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; }}
interface Implementor
{
public function OperationImp();
}
class ConcreteImplementorA implements Implementor
public function OperationImp()
echo '具体实现A', PHP_EOL;
class ConcreteImplementorB implements Implementor
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(); }}
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();
$impA = new ConcreteImplementorA();
$impB = new ConcreteImplementorB();
$ra = new RefinedAbstraction();
$ra->SetImplementor($impA);
$ra->Operation();
$ra->SetImplementor($impB);
客户端调用,我们的抽象类使用不用的实现类就可以让操作方法变成多态的感觉。
我们的手机有不同的型号,每个型号又要生产大致相同但不同的配件。比如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
<?phpinterface 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();// ......
<?php
interface MessageTemplate
public function GetTemplate();
class LoginMessage implements MessageTemplate
public function GetTemplate()
echo '您的登录验证码是【AAA】,请不要泄露给他人【XXX公司】!', PHP_EOL;
class RegisterMessage implements MessageTemplate
echo '您的注册验证码是【BBB】,请不要泄露给他人【XXX公司】!', PHP_EOL;
class FindPasswordMessage implements MessageTemplate
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
echo '极光开始发送短信:';
// 三个短信模板
$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);
// 极光发登录短信
$jg->SetTemplate($loginTemplate);
// ......
说明
关注公众号:【硬核项目经理】获取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料
知乎、公众号、抖音、头条搜索【硬核项目经理】
B站ID:482780532
原文链接:http://www.cnblogs.com/zyblog-coder/p/14214776.html
本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728