PHP设计模式之适配器模式

PHP设计模式之适配器模式

这个模式一直以来都有一个很经典的例子,那就是插座!没错,当咱们从国外买回来电器,或者旅游出差去国外的时候,常常会须要一个电源适配器,由于我国的电压标准是220伏,而其余国家则有110伏的标准。而这个电源适配器正是适配器模式的一种标志。当对象不太符合要求的时候,给他加一个适配器呗!!php

Gof类图及解释

GoF定义:将一个类的接口转换成客户但愿的另一个接口。Adapter模式使得本来因为接口不兼容而不能一块儿工做的那些类能够一块儿工做git

GoF类图github

继承式编程

适配器方法结构类图-继承式

组合式设计模式

适配器方法结构类图-组合式

代码实现安全

interface Target{
    function Request() : void;
}
复制代码

定义一个接口契约,也能够是一个正常的有实现方法的类(后面的例子咱们会用类)this

class Adapter implements Target{
    private $adaptee;

    function __constuct($adaptee){
        $this->adaptee = $adaptee;
    }

    function Request() : void {
        $this->adaptee->SpecificRequest();
    }
}
复制代码

适配器实现这个接口契约,让Request()方法得以实现,但请注意,咱们真正调用的实际上是Adaptee类中的方法阿里云

class Adaptee {
    function SpecificRequest() : void{
        echo "I'm China Standard!";
    }
}
复制代码
  • 适配器有两种形式,上方类图中给出了,咱们代码实现的组合形式的
  • 继承形式的在GoF书中是以C++为示例的,由于C++能够实现多重继承,但如今流行的大部分语言是以接口为形式的,也能够实现,但使用这种形式的适配器很少
  • 其实仍是面向接口编程的一种思惟,相似于装饰器对旧功能的包装,咱们这里就是直接去进行了替换,但对外的调用仍是保持不变
  • 适配器模式其实很好理解,代码真的就只有这么点

又说到个人手机工厂了,这回我们的生意真的作大了哦!卖到泰国、新加坡、印度尼西亚去了,反正有咖喱的地方都有咱们的身影了。听说是咱们出了个咖喱色。换壳这事儿可不彻底是由于受到诺X亚的影响,而是真的通过长期的调研咱们发现不一样颜色在不一样的地方销量会更好。因而,富X康在原有的手机壳生产线(Target)上为咱们加装了一个喷涂适配器(adapter),当咱们须要其余颜色的壳时,只须要这个适配器换不一样的颜料就好啦(adaptee),直接装上这个喷涂器,新的颜色的手机就诞生了。而当向另一个国家扩展业务时,咱们换颜料就行啦,用过久了不行就连喷头也换掉(是否是想起了连供打印机)spa

完整代码:适配器模式设计

实例

继续发短信,看我能编到何时~~~

各位大拿在对接信息、支付类的接口时,常常会使用这些平台提供的SDK。特别是有了Composer以后,安装SDK就更加的方便了,可是,又有一个严重的问题,这帮人作的SDK虽然说功能实现大同小异,但命名但是千差万别啊!!咱们的系统原来一直使用的阿里云的业务,可是这回要增长极光和百度云的信息功能,一来作个后备,二来根据不一样业务使用不一样的接口达到安全或节约的目的,有没有办法统一一下他们对外的接口,让咱们使用他们的SDK时可以很是方便的和以前使用你们都已经很习惯的阿里云的接口同样呢?固然有,给他们各自都上个适配器呗,实例化的时候大不了外面再套个工厂返回不一样的适配器就好啦,只要适配器里的实现方法和阿里云同样就OK啦!

短信发送类图

短信发送装饰器方法

完整源码:短信发送适配器方法

<?php

class Message{
    public function send(){
        echo "阿里云发送短信!" . PHP_EOL;
    }
    public function push(){
        echo "阿里云发送推送!" . PHP_EOL;
    }
}

class JiguangSDKAdapter extends Message{
    private $message;

    public function __construct($message){
        $this->message = $message;
    }

    public function send(){
        $this->message->send_out_msg();
    }
    public function push(){
        $this->message->push_msg();
    }
}

class JiguangMessage{
    public function send_out_msg(){
        echo "极光发送短信!" . PHP_EOL;
    }
    public function push_msg(){
        echo "极光发送推送!" . PHP_EOL;
    }
}
class BaiduYunSDKAdapter extends Message{
    private $message;

    public function __construct($message){
        $this->message = $message;
    }

    public function send(){
        $this->message->transmission_msg();
    }
    public function push(){
        $this->message->transmission_push();
    }
}
class BaiduYunMessage{
    public function transmission_msg(){
        echo "百度云发送短信!" . PHP_EOL;
    }
    public function transmission_push(){
        echo "百度云发送推送!" . PHP_EOL;
    }
}

$jiguangMessage = new JiguangMessage();
$baiduYunMessage = new BaiduYunMessage();
$message = new Message();

// 原来的老系统发短信,使用阿里云
$message->send();
$message->push();


// 部分模块用极光发吧
$jgAdatper = new JiguangSDKAdapter($jiguangMessage);
$jgAdatper->send();
$jgAdatper->push();

// 部分模块用百度云发吧
$bdAatper = new BaiduYunSDKAdapter($baiduYunMessage);
$bdAatper->send();
$bdAatper->push();
复制代码

说明

  • 在这个例子中,咱们有两个适配器,由于有两个SDK须要咱们去适配,谁说只能有一个电源转换器,万一哪一个神奇的国度是用500伏的电压呢,因此仍是多带个电源转换器吧
  • 这里咱们是继承的Message类,由于Message类是以前已经写好的代码,里面可能有一些能够公用的方法,因此并无作接口抽象。能够考虑在重构代码的时候实现提取一个抽象接口,但在这里只是为了演示适配器不必定只是能去针对接口,只要和原对象保持一致,不去继承什么也是能够的,毕竟咱们是弱类型语言,若是是相似于Java的强类型,那么继承或者实现仍是颇有必要的(多态性)
  • 组合式的适配器与装饰器相似,都会维护一个外部对象,装饰器更多的会使用原来的类中的方法,对其进行增长功能的操做,而适配器则不多去增长功能,而是直接替换掉
  • Laravel中的Filesystem模块,有一个FilesystemAdapter类,我以为没啥可说的了,很明显的告诉你们咱用了适配器模式,好好研究一下吧
  • 当你想使用一个类,但他提供的内容跟你的业务又不太匹配的时候;或者你想建立一个类,能够与其余不相关的类或不可预见的类协同工做的时候,不妨试试适配器模式吧

下期看点

事件订阅有没有据说过?没有?若是地震算一个事件的话,那么一旦发生这个灾难了,立刻会有种类政府部门和社会团队开始行动,救援、抢险等各类工做立刻展开,咱们能够把整个社会力量都当作是订阅者,包括咱们每个都会很关心灾区的状况。在这里,咱们全部人都是观察者。这下就很容易理解观察者模式了吧,下节咱们再详述!

相关文章
相关标签/搜索