目的

将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原来由于接口不兼容而不能一起工作的那此类可以一起工作

主要角色

目标角色:定义客户端使用的与特定领域相关的接口,这就是我们所期待得到的

源角色:需要进行适配的接口

适配器角色:对Adaptee的接口与target接口进行适配;适配器是本模式的核心,适配器把源接口转成目标接口,此角色为具体的类

适用性

1、你想使用一个已经存在的类,而它的接口不符合你的需求

2、你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类协同工作

3、你想要一个已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口(仅限于对象适配器)

//目标角色
interface Target {  public function simpleMethod1();  public function simpleMethod2();
}  //源角色
class Adaptee {  public function simpleMethod1(){  echo 'Adapter simpleMethod1'."<br>";  }
}  //类适配器角色
class Adapter implements Target {  private $adaptee;  function __construct(Adaptee $adaptee) {  $this->adaptee = $adaptee;   }  //委派调用Adaptee的sampleMethod1方法  public function simpleMethod1(){  echo $this->adaptee->simpleMethod1();  }  public function simpleMethod2(){  echo 'Adapter simpleMethod2'."<br>";     }   }  //客户端
class Client {  public static function main() {  $adaptee = new Adaptee();  $adapter = new Adapter($adaptee);  $adapter->simpleMethod1();  $adapter->simpleMethod2();   }
}  Client::main();

也许上述这么讲,你们还不知道什么是适配器。那么接下来,我再详细的讲解一下

什么时候使用适配器模式呢?

其实最简单的一个例子就是使用第三方类库。这些类库都会随着版本的升级,对应的api也会改变。当接口发生改变的时候,适配器就派上用场了

我举一个实际的例子吧

一开始的和谐

黑枣玩具公司专门生产玩具,生产的玩具不限于狗、猫、狮子,鱼等动物。每个玩具都可以进行“张嘴”与“闭嘴”操作,分别调用了openMouth与closeMouth方法。 在这个时候,我们很容易想到可以第一定义一个抽象类Toy,甚至是接口Toy,这些问题不大,其他的类去继承父类,实现父类的方法。一片和谐,信心向荣。

平滑的破坏

为了扩大业务,现在黑枣玩具公司与红枣遥控公司合作,红枣遥控公司可以使用遥控设备对动物进行嘴巴控制。不过红枣遥控公司的遥控设备是调用的动物的doMouthOpen及doMouthClose方法。黑枣玩具公司的程序员现在必须要做的是对Toy系列类进行升级改造,使Toy能调用doMouthOpen及doMouthClose方法。

考虑实现的方法时,我们很直接地想到,你需要的话我再在我的父类子类里给你添加这么两个方法就好啦。当你一次又一次在父类子类里面重复添加着这两个方法的时候,总会想着如此重复的工作,难道不能解决么?当有数百个子类的时候,程序员会改疯的。程序员往往比的是谁在不影响效率的时候更会“偷懒”。这样做下去程序员会觉得自己很傻。(其实我经常当这样的傻子)

abstract class Toy
{public abstract function openMouth();public abstract function closeMouth();//为红枣遥控公司控制接口增加doMouthOpen方法public abstract function doMouthOpen();//为红枣遥控公司控制接口增加doMouthClose方法public abstract function doMouthClose();
}class Dog extends Toy
{public function openMouth(){echo "Dog open Mouth\n";}public function closeMouth(){echo "Dog open Mouth\n";}//增加的方法public function doMouthOpen(){$this->doMouthOpen();}//增加的方法public function doMouthClose(){$this->closeMouth();}
}class Cat extends Toy
{public function openMouth(){echo "Cat open Mouth\n";}public function closeMouth(){echo "Cat open Mouth\n";}//增加的方法public function doMouthOpen(){$this->doMouthOpen();}//增加的方法public function doMouthClose(){$this->closeMouth();}
}

更加烦躁

程序员刚刚码完代码,喝了口水,突然间另一个消息传来。 黑枣玩具公司也要与绿枣遥控公司合作,因为绿枣遥控公司遥控设备更便宜稳定。不过绿枣遥控公司的遥控设备是调用的动物的operMouth(type)方法来实现嘴巴控制。如果type为0则“闭嘴”,反之张嘴。 这下好了,程序员又得对Toy及其子类进行升级,使Toy能调用operMouth()方法。搁谁都不淡定了。

abstract class Toy
{  public abstract function openMouth();  public abstract function closeMouth();  public abstract function doMouthOpen();  public abstract function doMouthClose();  //为绿枣遥控公司控制接口增加doMouthClose方法  public abstract function operateMouth($type = 0);
}  class Dog extends Toy
{  public function openMouth()  {  echo "Dog open Mouth\n";  }  public function closeMouth()  {  echo "Dog open Mouth\n";  }  public function doMouthOpen()  {  $this->doMouthOpen();  }  public function doMouthClose()  {  $this->closeMouth();  }  public function operateMouth($type = 0)  {  if ($type == 0) {  $this->closeMouth();  } else {  $this->operateMouth();  }  }
}  class Cat extends Toy
{  public function openMouth()  {  echo "Cat open Mouth\n";  }  public function closeMouth()  {  echo "Cat open Mouth\n";  }  public function doMouthOpen()  {  $this->doMouthOpen();  }  public function doMouthClose()  {  $this->closeMouth();  }  public function operateMouth($type = 0)  {  if ($type == 0) {  $this->closeMouth();  } else {  $this->operateMouth();  }  }
}

在这个时候,程序员必须要动脑子想办法了,就算自己勤快,万一哪天紫枣青枣黄枣山枣这些遥控公司全来的时候,忽略自己不断增多的工作量不说,这个Toy类可是越来越大,总有一天程序员不崩溃,系统也会崩溃。

问题出在哪里呢

像上面那样编写代码,代码实现违反了“开-闭”原则,一个软件实体应当对扩展开放,对修改关闭。即在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展。也就是说每个尸体都是一个小王国,你让我参与你的事情这个可以,但你不能修改我的内部,除非我的内部代码确实可以优化。

在这种想法下,我们懂得了如何去用继承,如何利用多态,甚至如何实现“高内聚,低耦合”。

回到这个问题,我们现在面临这么一个问题,新的接口方法我要实现,旧的接口(Toy抽象类)也不能动,那么总得有个解决方法吧。那就是引入一个新的类--我们本文的主角--适配器。 适配器要完成的功能很明确,引用现有接口的方法实现新的接口的方法。更像它名字描述的那样,你的接口不改的话,我就利用现有接口和你对接一下吧。

到此,解决方法已经呼之欲出了,下面贴上代码。

<?php
abstract class Toy
{  public abstract function openMouth();  public abstract function closeMouth();
}  class Dog extends Toy
{  public function openMouth()  {  echo "Dog open Mouth\n";  }  public function closeMouth()  {  echo "Dog close Mouth\n";  }
}  class Cat extends Toy
{  public function openMouth()  {  echo "Cat open Mouth\n";  }  public function closeMouth()  {  echo "Cat close Mouth\n";  }
}//目标角色:红枣遥控公司
interface RedTarget
{  public function doMouthOpen();  public function doMouthClose();
}  //目标角色:绿枣遥控公司及
interface GreenTarget
{  public function operateMouth($type = 0);
}//类适配器角色:红枣遥控公司
class RedAdapter implements RedTarget
{  private $adaptee;  function __construct(Toy $adaptee)  {  $this->adaptee = $adaptee;  }  //委派调用Adaptee的sampleMethod1方法  public function doMouthOpen()  {  $this->adaptee->openMouth();  }  public function doMouthClose()  {  $this->adaptee->closeMouth();  }
}  //类适配器角色:绿枣遥控公司
class GreenAdapter implements GreenTarget
{  private $adaptee;  function __construct(Toy $adaptee)  {  $this->adaptee = $adaptee;  }  //委派调用Adaptee:GreenTarget的operateMouth方法  public function operateMouth($type = 0)  {  if ($type) {  $this->adaptee->openMouth();  } else {  $this->adaptee->closeMouth();  }  }
}class testDriver
{  public function run()  {  //实例化一只狗玩具  $adaptee_dog = new Dog();  echo "给狗套上红枣适配器\n";  $adapter_red = new RedAdapter($adaptee_dog);  //张嘴  $adapter_red->doMouthOpen();  //闭嘴  $adapter_red->doMouthClose();  echo "给狗套上绿枣适配器\n";  $adapter_green = new GreenAdapter($adaptee_dog);  //张嘴  $adapter_green->operateMouth(1);  //闭嘴  $adapter_green->operateMouth(0);  }
}  $test = new testDriver();
$test->run();

更加烦躁
最后的结果就是,Toy类及其子类在不改变自身的情况下,通过适配器实现了不同的接口。

最后的总结

将一个类的接口转换成客户希望的另外一个接口,使用原本不兼容的而不能在一起工作的那些类可以在一起工作.

适配器模式核心思想:把对某些相似的类的操作转化为一个统一的“接口”(这里是比喻的说话)--适配器,或者比喻为一个“界面”,统一或屏蔽了那些类的细节。适配器模式还构造了一种“机制”,使“适配”的类可以很容易的增减,而不用修改与适配器交互的代码,符合“减少代码间耦合”的设计原则。

更加烦躁

php设计模式-适配器相关推荐

  1. Go 语言实现 23 种设计模式适配器

    Go 语言实现 23 种设计模式适配器 将一个类型的接口转换成客户希望的另外一个接口,使原本由于接口不兼容而不能一起工作的类可以一起工作. Example_one package mainimport ...

  2. 设计模式---适配器设计模式

    设计模式---适配器设计模式 什么事适配器: 1. 在使用监听的时候,需要定义一个类事件监听器接口 2. 通常接口中有多个方法,而程序中不一定所有的方法都用到,但又必须重写,很繁琐 3. 适配器简化了 ...

  3. 结构设计模式 - 适配器设计模式

    结构设计模式 - 适配器设计模式 PANKAJ  17评论 适配器设计模式是结构设计模式之一,其使用使得两个不相关的接口可以一起工作.连接这些不相关接口的对象称为适配器. 目录[ 隐藏 ] 1适配器设 ...

  4. 设计模式--适配器1模式实现C++

    /********************************* *设计模式--适配器1模式实现 *C++语言 *Author:WangYong *Blog:http://www.cnblogs. ...

  5. swift date 计算差_[Swift 设计模式] 适配器

    更多内容,欢迎关注公众号:Swift花园 喜欢文章?不如来个 ➕三连?关注专栏,关注我 将一个不兼容的对象转换成目标接口或者类,这是适配器模式的作用. 下面这件东西是适配器模式在现实世界中最贴切的表达 ...

  6. 【Adapter模式】C++设计模式——适配器

    适配器 一.设计流程探讨 二.模式介绍 三.代码实现     C++设计模式大全,23种设计模式合集详解-

  7. 【设计模式-适配器,策略模式,和责任链】

    文章目录 一.适配器模式(Adaptor Pattern) 1. 定义 2. 生活例子(百度) 3. 适配器角色 4. 适配器模式分类 5. 实例 二.策略模式(Strategy Pattern) 1 ...

  8. 设计模式--适配器(Adapter)模式

    模式定义 将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 类图 应用场景 1.当你希望使用某些现有类,但其接口与你的其他代码不兼容时: 2 ...

  9. java设计模式:适配器设计模式

    2019独角兽企业重金招聘Python工程师标准>>> 首先,先来先讲讲适配器.适配就是由"源"到"目标"的适配,而当中链接两者的关系就是适配 ...

  10. java设计模式adapter_Java设计模式--适配器(Adapter)模式

    适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 适配器模式的用途 用电器做例子,笔记本电脑的插头一般都是三相的,即除了阳极.阴极 ...

最新文章

  1. 2018深度学习引用数最高的十大论文
  2. spring集成Apache的ActiveMQ
  3. 判断二叉树是否是平衡二叉树(dp tree)
  4. Python Django 参数解包及代码示例
  5. 跨域失败 过滤器_跨域问题解决方案
  6. mysql创建临时表 分页_Mysql 如何创建一张临时表
  7. Spark-SQL与hive整合【版本spark1.6.0+hive0.14】--Standalone模式
  8. 4. 木马病毒和免杀技术,另一种免杀思路
  9. “革命者”贝壳找房:如何让房产经纪行业进入新大陆?
  10. python字符串中常见的内置方法
  11. 自己使用的文本编辑器全部采用Tahoma字体
  12. winsxs探索之组件的本质:文件与注册表
  13. JINI和java space入门
  14. 互斥锁(mutex lock)
  15. C语言外卖订单管理系统上班,外卖订单管理系统
  16. 那年杏花微雨,你说你是DOM
  17. 距总决赛还有100天!详解沃顿KWHS全球投资挑战赛
  18. 从零开始学习3D可视化之摄像机
  19. VS Code 插件的开发及发布指南
  20. mysql2ora datacopy,oracle的clone及冷迁移(直接拷贝数据文件)

热门文章

  1. 【获奖公布】 我的2016 主题征文活动
  2. pyecharts geo绘制地理信息地图
  3. 猜数字小游戏——算法学习
  4. Serial Programming HOWTO——Linux 串口编程HOWTO
  5. 回头草的爱情,我们还需要吗?
  6. beyond compare linux中文包,linux 下安装 Beyond Compare
  7. PHP - 表单(FORM)实例
  8. k8s_难产的ingress架构初体验(一)
  9. 网狐荣耀需要什么服务器系统,网狐荣耀服务器负载均衡
  10. 你以为大厂的代码就不烂了?烂成一坨屎...