目的

将一个类的接口转换成客户希望的另外一个接口,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. PyTorch-Adam优化算法原理,公式,应用
  2. 14-flutter Animation 动画
  3. Android ViewPager使用具体解释
  4. python 序列化函数_python – 如何序列化sympy lambdified函数?
  5. Silverlight中本地化的实现(语言切换)
  6. c语言结构体如何定义字母,c语言中定义结构体如何定义?
  7. elasticsearch-jdbc同步myslq数据到elasticsearch
  8. php性能需求,PHP语言性能考察
  9. ServletContextListener在Springboot中的使用
  10. axios队列 vue_vue axios全攻略
  11. lbp matlab程序,求教大神给解释一下LBP特征提取每部分程序是干什么的
  12. php日志数据统计,awk 进行php日志累计报错统计
  13. Linux 下的静态(函数)库、动态(函数)库
  14. java mail使用qq邮箱发邮件的配置方法
  15. keras 多分类一些函数参数设置
  16. Atitit. 注册表操作查询 修改 api与工具总结 java c# php js python 病毒木马的原理
  17. python外星人游戏最高得分永久储存_用python编写外星人入侵中为什么消除第一个外星人得分100,而且最高分和当前分数不匹配?...
  18. 毕业设计之 --- 新闻分类系统
  19. 【Redis】Redis缓存穿透和雪崩
  20. html5魔塔样板快速上手,《梦幻模拟战》魔塔攻略|先人一步,快速上手梦战自走棋指南...

热门文章

  1. DynamicDto链式实现动态数据传输对象
  2. mt4 python神经网络_用Python写MT4自动交易策略来炒外汇
  3. 钱宝网500亿的“庞氏骗局”崩塌始末
  4. centos6/7 vault源使用
  5. win10系统查看组件服务器,win10系统查看邮箱服务器信息的技巧介绍
  6. 五姐妹因没嫁妆集体自杀 绝望跳河
  7. 抖音seo搜索是什么?源码部署-seo排名系统源码分析
  8. 富芮坤蓝牙FR801xH开发环境搭建
  9. python import turtle as t_Python编程小记:turtle库
  10. 《微观经济学》 第三章