目的

将一个类的接口转换为另一个符合客户期望的接口

达到的目的:

种类

有两种:

  • 对象适配器
  • [ ] 类适配器(嗷~~暂时没有实际场景让自己完全明白嗷?)
  • NOTE: 对象适配器和类适配器使用两种不同的适配方法(分别是组合委托和继承)

举个例子

我这里就拿使用三脚插头充电的苹果手机(港版充电器)来举个例子吧~和图中例子相反

interface IPhoneCharger {chargeWith3Footer(): void;
}// Target
interface PrimaryCharger {chargeWith2Footer(): void;
}// adaptee
// 苹果手机实现苹果手机充电器接口
class IPhone implements IPhoneCharger {chargeWith3Footer() {console.log("苹果手机开始充电啦~~~?")}
}// adapter
// 普通充电器适配器 - 实现普通充电器接口 - 使苹果手机等其他充电器可以适配普通2脚充电器进行充电
class PrimaryChargerAdapter implements PrimaryCharger {private phone: any;constructor(phone: any) {this.phone = phone;}chargeWith2Footer(): void {if (this.phone.constructor === IPhone) {// 适配器在这里适配三脚和二脚充电器接口this.phone.chargeWith3Footer();}}
}function TestDemo() {const iPhone = new IPhone();// iPhone.chargeWith2Foot(); // will fail// 中国大陆一般都是2插口插座~需要使用2脚充电器充电 chargeWith2Footer(),// 但是苹果手机是三脚充电器不支持~~// 通过充电器适配器,实现了chargeWith2Footer(),符合客户期望的接口~~~const adaptedIPhone = new PrimaryChargerAdapter(iPhone);adaptedIPhone.chargeWith2Footer(); // 完美~~
}TestDemo();
  • 在线测试

对号入座

Java中的适配器

客户使用适配器的过程解析:

  1. 客户通过目标接口调用适配器的方法对适配器发起请求
  2. 适配器使用被适配者接口把请求换成被适配者的一个或多个调用接口
  3. 客户收到调用的结果,但未察觉一切是适配器的转换作用。
//  改造成ts形式~~
class OldClassAdapter implements NewInterface {private OldClass ref;constructor(OldClass oc) {this.ref = oc;}public NewMethod(): void {this.ref.OldMethod();}
}
  • 或许结合这一段代码就可以更加理解适配器模式使用的场景

思考 ?

  • 我所认为的适配器模式应该尽量不去修改被适配者。
  • 真正想做的是应该是接口的转换。

优点

对象适配器模式优点:
(1) 一个对象适配器可以把多个不同的适配者适配到同一个目标;
(2) 将目标类和被适配者类解耦,通过引入一个适配器类来重用现有的被适配者类,无须修改原有结构。

缺点

过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现.

适配器模式 VS 外观模式

先看下面这段熟悉的代码~~ 摘自 @远峰

// 统一的接口适配不同类
// Target 客户期望使用的接口
interface ComputerInterface {usb(): void;
}// Adaptee
class HuaweiPhone {huaweiInterface(): void {console.log('华为手机的数据接口');}
}// Adaptee
class Iphone {iphoneInterface(): void {console.log('苹果手机的数据接口');}
}// Class Adapter
class HuaweiDataWireAdapter extends HuaweiPhone implements ComputerInterface {usb(): void {console.log('使用华为数据线连接');super.huaweiInterface();}
}class IphoneDataWireAdapter extends Iphone implements ComputerInterface {usb(): void {console.log('使用苹果数据线连接');super.iphoneInterface();}
}function commonAdapterDemo() {const computer1 = new HuaweiDataWireAdapter();computer1.usb();const computer2 = new IphoneDataWireAdapter();computer2.usb();}
commonAdapterDemo();
  • 有些误解就是一个适配器只用来适配一个类,但其实适配器模式也可以包装多个类。
  • 这个例子就是一个类适配器的应用。客户期望使用他们自己的数据线连接 ~.usb(),然后通过适配器做了一个转换,事实上没有说将华为手机和苹果手机的数据线接口给重新设计了~
  • [ ] 相类似的是外观模式,还没思考(? 狗带了)

NOTE: 外观和适配器模式都可以包装许多类,但是外观模式是为了简化操作,而适配器模式是将接口转换为不同接口

Q & A

  • 一个适配器需要做多少“适配”工作?
    适配器做的工作和目标接口的大小成正比

参考资料

  • Head First 设计模式
  • 原文链接

设计模式 之 适配器模式相关推荐

  1. C#设计模式(7)——适配器模式(Adapter Pattern)

    一.引言 在实际的开发过程中,由于应用环境的变化(例如使用语言的变化),我们需要的实现在新的环境中没有现存对象可以满足,但是其他环境却存在这样现存的对象.那么如果将"将现存的对象" ...

  2. 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)

    [索引页] [源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabcd 介绍 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本 ...

  3. 跟JBPM学设计模式之适配器模式

    跟JBPM学设计模式之适配器模式 模式简介 适配器模式(Adapter),将一个类的接口转换成客户希望的另一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 说起适配器模式 ...

  4. python适配器模式角色_Python设计模式之适配器模式原理与用法详解

    本文实例讲述了Python设计模式之适配器模式原理与用法.分享给大家供大家参考,具体如下: 适配器模式(Adapter Pattern):将一个类的接口转换成为客户希望的另外一个接口. 下面是一个适配 ...

  5. 【设计模式】—— 适配器模式Adapter

    模式意图 如果已经有了一种类,而需要调用的接口却并不能通过这个类实现.因此,把这个现有的类,经过适配,转换成支持接口的类. 换句话说,就是把一种现有的接口编程另一种可用的接口. 模式结构 [类的适配器 ...

  6. 设计模式适配器模式_21世纪的设计模式:适配器模式

    设计模式适配器模式 这是我的演讲的第三部分," 21世纪的设计模式" . 适配器模式桥接世界. 在一个世界中,我们有一个概念的界面. 在另一个世界,我们有不同的界面. 这两个接口有 ...

  7. Java面试题:单例设计模式、适配器模式的不同方式

    QUESTION:单例设计模式.适配器模式的不同方式? ANSWER: 1.单例设计模式,适配器设计模式     单利设计模式:             在java中,单例模式是指为了保证类在内存中只 ...

  8. [学习笔记]设计模式[6]-{适配器模式外观模式}

    设计原则 最少知识原则:只和你的密友谈话 这个原则的意思是,在系统设计的过程中,不要让太多的类耦合在一起,免得对系统一部分的修改会影响到其他部分.在设计系统之前,应该首先注意对象与对象之间的交互关系, ...

  9. 适配器模式_21世纪的设计模式:适配器模式

    适配器模式 这是我的演讲的第三部分," 21世纪的设计模式" . 适配器模式桥接世界. 在一个世界中,我们有一个概念的界面: 在另一个世界中,我们有不同的界面. 这两个接口有不同的 ...

  10. 设计模式回顾——适配器模式(C++)

    文章目录 1 前言 2 什么是适配器模式 2.1 生活中的适配器 2.2 适配器模式含义 2.3 适配器模式作用 3 适配器模式优缺点 3.1 适配器优缺点 3.2 类适配器优缺点 3.3 对象适配器 ...

最新文章

  1. RocEDU.课程设计2018 第二周进展 博客补交
  2. Unity 2D游戏开发教程之游戏中精灵的跳跃状态
  3. 忙~~~~~~~~~~~~~~~~~
  4. eclipse java混淆打包_eclipse proguard怎么混淆jar包
  5. C++中使用new和delete运算符实现二维数组的操作
  6. keil5中文乱码的解决
  7. Qt之水平/垂直布局(QBoxLayout、QHBoxLayout、QVBoxLayout)
  8. Cron表达式、定时任务
  9. 信息学奥赛C++语言:调整试题顺序
  10. python机器学习彩票_Python机器学习及实战kaggle从零到竞赛PDF电子版分享
  11. 微信x漫威首款小程序公开!揭露未来“看展”趋势
  12. python pip升级报错
  13. 统计面要素中点要素的个数.
  14. 云原生时代,需要什么样的数据库?
  15. 鸡啄米vc++2010系列25(滚动条控件Scroll Bar)
  16. ARM基础相关寄存器的讲解-LPC21XX
  17. Cinnamon Applet 入门
  18. hadoop kerberos java_hadoop kerberos认证
  19. 程序员快速记忆英文单词的专属诀窍
  20. 重磅!上海出落户新政:双一流应届硕士可直接落户!

热门文章

  1. 关于数据库性能优化小经验
  2. python 在 eclipse 上的编码配置问题
  3. Oracle数据库空间管理
  4. 【转】 Android - LayoutInflate用法
  5. 精品思维导图,流程图模板分享
  6. vuex状态管理简单入门
  7. [RabbitMQ]RabbitMQ原理与相关操作(一)
  8. 99% 的新移动恶意程序是针对 Android
  9. Spring学习总结(18)——Spring整合Mysql数据库一主多从、多主多从配置
  10. BufferedReader 和BufferedWriter