适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)。
简单地说,就是需要的东西就在面前,但却不能使用,而短时间又无法改造它,于是我们就想办法适配它。
适配器分类:
类适配器模式
对象的适配器模式
接口的适配器模式
注: 如果对类图中的箭头有疑惑参考: UML类图中的六种关系(物理设计阶段)
1. 类适配器模式
在Adapter中实现目标接口同时继承待适配类来完成适配:
Target 为目标接口类
Adaptee 为待适配类
Adapter 适配器类: 将Adaptee适配为Target接口
// 已存在的、具有特殊功能,但不符合我们既有的标准接口的类class Adaptee { public void specificRequest() { System.out.println("被适配的类,该类具有特殊功能"); } }// 目标接口interface Target { public void request(); }// 具体目标类,只提供普通功能class ConcreteTarget implements Target { public void request() { System.out.println("普通类,该类具有普通功能"); } }// 适配器类,继承了被适配类,同时实现标准接口class Adapter extends Adaptee implements Target{ public void request() { super.specificRequest(); } }//测试类// 使用普通功能类Target concreteTarget = new ConcreteTarget(); concreteTarget.request(); //输出“普通类,该类具有普通功能”// 使用特殊功能类,即适配类Target adapter = new Adapter(); adapter.request(); //输出“被适配的类,该类具有特殊功能”
2. 对象的适配器模式
与类适配器不同的是,对象适配器持有Adaptee对象而不需要继承它。
//只需要修改适配器类即可//适配器类,只实现标准接口class Adapter implements Target{ private Adaptee adaptee; public Adapter (Adaptee adaptee) { this.adaptee = adaptee; } public void request() { this.adaptee.specificRequest(); } }//测试类Target concreteTarget = new ConcreteTarget(); concreteTarget.request(); //输出“普通类,该类具有普通功能”//Adapter需要先创建一个被适配类的对象作为参数Target adapter = new Adapter(new Adaptee()); adapter.request(); //输出“被适配的类,该类具有特殊功能”--------------------- 作者:SEU_Calvin 来源:CSDN 原文:https://blog.csdn.net/SEU_Calvin/article/details/71126649 版权声明:本文为博主原创文章,转载请附上博文链接!
3. 接口的适配器模式
大话设计模式中没有 接口适配模式,但是很多网上文章中还是提到了接口适配,所以这里也讲解一下:
目的:减少接口实现,Adaptee类只需要实现接口中的一部分
Wrapper:相当于适配器(这里的作用和抽象类功能相同)
Adaptee: 待适配的类,只实现了request接口而不需要实现cancel接口。
总结:
Adapter继承自Adaptee和Target的类来完成适配。
Adapter持有Adaptee对象并实现Target接口来完成适配(java类是单继承,最多只能继承一个类,对象适配器可以继承其它类)。
使用实例
1. Android中ListView通过ListAdapter加载每一条View,而不需要考虑各个view的不同
ListView 是client
ListAdapter 是 Target
BaseAdapter/ArrayAdapter/CursorAdapter 是 适配类
List<T>/Cursor 中保存了列表数据,需要适配成多个view展示到ListView上,它相当于 Adaptee
所以这里使用了: 类适配模式 + 接口适配模式
2.jdk中InputStreamReader/OutputStreamWriter
Reader/Writer : 相当于 Target
InputStreamReader 是 Adapter
InputStrea 是 Adaptee
所以这里使用了: 对象适配模式
3. jdk中Arrays.asList(T …a)
将 数组适配成List对象,这里好像和上面讲的三种模式都不像,它通过一个接口将一种对象类型数据转换为另一种类型数据:
输出类型List 作为 Target
asList接口 作为 Adapter
输入数组 a 是 Adaptee
参考:
《大话设计模式》
https://blog.csdn.net/SEU_Calvin/article/details/71126649
https://www.jianshu.com/p/78f6083ef869
原文出处:https://www.cnblogs.com/NeilZhang/p/10279549.html
作者:NeilZhang