前面三篇文章分别学习了单例模式、三种工厂模式和建造者模式,它们都是比较常用的创建型模式,顾名思义就是创建对象的。从这篇文章开始来学习结构型设计模式,今天是第一篇——适配器模式。

适配器模式

首先拿我使用的小米手机为例,它撤销了原来的 Audio 接口,要使用耳机听歌呢,就必须使用 Type-C to Audio 转接线(如下图),一头接上手机,一头接上耳机线。(ps:话说,每次听歌和充电都要换来换去的,好麻烦)

其实,这就是一个实际的适配器,和设计模式中的适配器扮演着同样的角色,将一个接口转换为另一个接口,以符合用户的期望。

改进前

下面我们就将这个例子转换为代码,看它是如何实现的。以前的手机呢,有两个接口,使用 TypeC 接口充电:

public interface TypeCInterface {// 充电void chargeWithTypeC();
}public class TypeCInterfaceImpl implements TypeCInterface {@Overridepublic void chargeWithTypeC() {System.out.println("使用 Type-C 接口充电");}
}
复制代码

使用 Audio 接口听歌:

public interface AudioInterface {// 听歌void listenWithAudio();
}public class AudioInterfaceImpl implements AudioInterface {@Overridepublic void listenWithAudio() {System.out.println("使用 Audio 接口听歌");}
}
复制代码

而我们的手机,同时有这两个接口,用来充电和听歌:

public class XiaomiPhone {private AudioInterface audioInterface;private TypeCInterface typeCInterface;public XiaomiPhone(AudioInterface audioInterface, TypeCInterface typeCInterface) {this.audioInterface = audioInterface;this.typeCInterface = typeCInterface;}public void charge() {typeCInterface.chargeWithTypeC();}public void listen() {audioInterface.listenWithAudio();}
}
复制代码

而我们就可以用手机来边充电,边听歌了:

public class Client {public static void main(String[] args) {AudioInterface audioInterface = new AudioInterfaceImpl();TypeCInterface typeCInterface = new TypeCInterfaceImpl();XiaomiPhone xiaomiPhone = new XiaomiPhone(audioInterface, typeCInterface);xiaomiPhone.charge();xiaomiPhone.listen();}
}
复制代码

改进了

本来这一切都好好的,可是小米手机把 Audio 接口取消了,我们没法直接使用来听歌了。于是,我们只好使用转接线,将 Type-C 接口转为 Audio 接口:

// 需将其转换为 Audio 接口,所以实现了 AudioInterface
public class TypeCToAudioTieline implements AudioInterface {private TypeCInterface typeCInterface;// 另一头是 TypeC,所以传入 TypeCInterfacepublic TypeCToAudioTieline(TypeCInterface typeCInterface) {this.typeCInterface = typeCInterface;}@Overridepublic void listenWithAudio() {// ···typeCInterface.chargeWithTypeC();}
}
复制代码

然后呢,把转接线插入到手机上(把手机和转接线看作一个整体,它只有 Audio 接口了):

public class XiaomiPhone {private AudioInterface audioInterface;public XiaomiPhone(AudioInterface audioInterface) {this.audioInterface = audioInterface;}public void listenWithAudio() {audioInterface.listenWithAudio();}
}
复制代码

于是,现在我们就通过转接线,将 Type-C 接口转换成了 Audio 接口。然后将耳机插在转接线上,就可以听歌了:

public class Client {public static void main(String[] args) {TypeCInterface typeCInterface = new TypeCInterfaceImpl();TypeCToAudioTieline tieline = new TypeCToAudioTieline(typeCInterface);XiaomiPhone xiaomiPhone = new XiaomiPhone(tieline);xiaomiPhone.listenWithAudio();}
}
复制代码

上述模式就是适配器模式,它将一个类的接口转换成用户所需要的另一个接口,使得原本接口不兼容的类可以一起工作。

它的 UML 图如下:

下面我们来总结适配器模式的优点:

  • 它可以通过适配器进行接口的转换,让原本不兼容的类协同工作;
  • 这可以使客户从实现的接口解耦,如果被适配者改变了接口,适配器可以将其封装起来,客户不必跟随其修改;

缺点:

  • 增加一个适配器,可能会增加系统的复杂度。

适配器模式的具体实践

JDK#InputStreamReader

通过 InputStreamReader,可以将 InputStream 字节流转换为字符流进行处理。

public class InputStreamReader extends Reader {private final StreamDecoder sd;// 将 inputStream 转换为 InputStreamReaderpublic InputStreamReader(InputStream in) {super(in);try {sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object} catch (UnsupportedEncodingException e) {throw new Error(e);}}public int read() throws IOException {return sd.read();}
}
复制代码

Spring#AOP/MVC

另外,比如在 Spring AOP 中,将 Advice 封装成对应的拦截器类型。或是在 Spring MVC 中,通过适配器模式,用于执行目标 Controller 中的请求处理方法。

由于对其源码不太熟悉,这里也就不详细说了。感兴趣的小伙伴可以看看这篇文章。

  • 小旋锋:设计模式 | 适配器模式及典型应用

转载于:https://juejin.im/post/5cd8e85ce51d453afd3be787

适配器模式:我真的不难相关推荐

  1. Jquery真的不难~第八回 JS的闭包问题

    百度百科中对闭包的定义: 闭包是可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义."闭包" 一词来源 ...

  2. axure删除的页面怎么恢复_微信删除好友怎么找回?快速恢复,真的不难

    微信删除好友怎么找回?生活中经常会因为一些鸡毛蒜皮的小事和好友发生争吵,或者是因为一些三观和见解不同会发生一些小矛盾,然后就删除了好友.其实过了很长时间以后再想起这档事情,觉得完全没有必要,一时的生气 ...

  3. 月薪30k真的不难,不信你看

    看完标题后,你肯定想,老师你是不是又恰饭了,还真不是,你往下看就知道了. 要我说,月薪30k真的不难,不是我站着说话不腰疼,你看看招聘的 JD: 月薪能上30k的,比例绝对不低,如果你还没达到,那你工 ...

  4. 相信我,SDRAM真的不难(二)----初始化操作

    写在前面 本文是SDRAM系列文章的第二篇,对SDRAM的初始化操作进行了详细介绍.代码编写与仿真验证. 其他博文链接:相信我,SDRAM真的不难----汇总篇(电梯直达) 1.初始化 SDRAM 的 ...

  5. 相信我,SDRAM真的不难(九)----基于SDRAM缓存的串口传图综合实战(UART + SDRAM + VGA)

    写在前面 本文是SDRAM系列文章的第九篇,前面八篇已经实现了一个简单的SDRAM控制器.正所谓光说不练云玩家,接下来我们搞搞实战,真正把SDRAM给用起来. 本文将结合UART模块.VGA模块.SD ...

  6. 相信我,SDRAM真的不难(四)----写操作(页突发模式)

    写在前面 本文是SDRAM系列文章的第四篇,对SDRAM的突发写操作进行了详细介绍.代码编写与仿真验证. 其他博文链接:相信我,SDRAM真的不难----汇总篇(电梯直达) 1.写操作 SDRAM提供 ...

  7. 相信我,SDRAM真的不难(一)----初识SDRAM

    写在前面 本文是SDRAM系列文章的第一篇,旨在对SDRAM做一个初步的介绍与认识. 其他博文链接:相信我,SDRAM真的不难----汇总篇(电梯直达) 1.什么是SDRAM SDRAM(Synchr ...

  8. Java真的不难(三十五)适配器模式

    适配器模式 哈喽大家好,四月份啦!!!很高兴在这里与大家再次相遇,我相信大家都是热爱技术的伙计们,也正是因为有你们的支持和陪伴,小应学长在2022年第三季新星计划内获得Java后端Top3,这也是导师 ...

  9. dnf超时空漩涡副本路线流程图_DNF超时空漩涡真的不难,掌握这些技巧和打法,自己开团当团长!...

    爱玩游戏,分享快乐,我是欢乐Tree. DNF经历了95级版本全职业改之后,阿拉德勇士们的输出能力得到了一次史诗级的加强,所以现在的超时空漩涡也不是那么遥不可及.但是现在超时空漩涡有很多"潜 ...

最新文章

  1. 打开线程 | 进程 | 协程的大门
  2. SEO优化可以从这几个方面着手
  3. mysql hostname uroot_CACTI网络流量监控
  4. 微信好友特征数据分析及可视化
  5. 操作系统——CPU、计算机的构成
  6. 《高级软件测试》实践作业4学习记录12月25日
  7. php 导出csv文件
  8. oracle 日志 LogMiner
  9. 计算机考试忘记备注班级了,2012年计算机二级Access第二十五套上机试题及答案详解...
  10. android组建之间通信_android组件间通信有哪些方式
  11. 2018 OpenInfra Days China官方盛典邀您莅临!文末有福利!
  12. Qt公有槽和私有槽的区别
  13. 统计数据会说谎_统计数据对您说谎的三种方式
  14. twaver html5 2d demo,TWaver 2D+GIS+3D的试用和在线Demo
  15. 对二分法的理解和结对编程情况
  16. 基础图像处理 python+opencv
  17. h5php大转盘抽奖,html5的非常简单圆形转盘抽奖代码
  18. 与我一起学习微服务架构设计模式1—逃离单体地狱
  19. VMware虚拟机去虚拟化完整版教程|永久过强壳VMP、SE壳、GK盾、TMD教程|VMware去虚拟化吾爱汇编论坛教程完整版
  20. Java的System.currentTimeMillis()的性能问题

热门文章

  1. office2003计算机考试,计算机考试Office2003应用.doc
  2. java 自动装箱自动拆箱_自动装箱和自动拆箱
  3. mysql与access数据库_mysql数据库和access数据库有什么不同吗?
  4. 实用的bit 位操作
  5. 如何搭建一个你喜欢的工作环境
  6. linux内核经常用到的 一个概念“原子操作“
  7. 为什么集群要奇数_面试系列 redis数据删除amp;集群
  8. mysql session 最大值_session 存储最大值
  9. python小知识_python-小知识点积累(持续更新)
  10. matlab--矩阵运算