一,初始适配器模式
包括:定义,结构,参考实现
二,体会适配器模式
包括:场景问题,不用模式的解决方案,使用模式的解决方案
三,理解适配器模式
包括:认识适配器模式,适配器模式的实现,双向适配器,对象适配器,类适配器,适配器模式的优缺点
四,思考适配器模式
包括:适配器模式的本质,何时选用
一,初始适配器模式
1,定义
将一个类的接口转换成客户希望的接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起使用。(除了转换,不会带来新的功能)
2,结构和说明
Client:客户端,调用自己的领域接口Target
Target:定义客户端需要的跟特定领域相关的接口
Adaptee:已经存在的接口,但与客户端要求的特定领域接口不一致,需要适配(能够提供的接口)
Adapter:适配器,把Adapte适配成为Client需要的Target
3,参考实现git@github.com:qinixiangyang111/design.git 的adapter中example1
二,体会适配器模式
1,装配电脑 例子
旧的硬盘和电源,多个充电器
新的硬盘,一个转换线就可以了
有何问题?
如何让原有的电源类接口能够适应新的硬盘类的电源接口的需要呢?
2,如何解决
采用一个转接线的类,转接线可以把电源的接口是配成新的硬盘所需要的接口,那么这个转换线类就类似本节的主角–适配器
3,实际开发的问题:同时支持数据库和文件的日志管理
a,日志管理第一版
用户要求日志以文件的形式记录
b,要采用数据库管理日志
不用模式的解决方案
参考实现git@github.com:qinixiangyang111/design.git 的adapter中example2
存在的问题
现在的客户端,无法以同样的方式来直接使用第一版(因为两版的接口不一致,LogDbOperateApi,LogOperateApi,)
使用模式解决方案
总结:
a,原有的方式存取日志方式,运行的很好
b,现在有了基于数据库的实现,新的实现有自己的接口
c,想要在第二版中兼容第一版,那么就应该有一个类实现第二版的接口,然后在这个类中去调用已有的功能实现这个类就是适配器
三,理解适配器模式
1,适配器模式的功能
进行转换匹配,目的是复用已有的功能(功能已经存在,不想从新开发,。新的功能用旧的功能去实现),而不是实现新的接口。
适配器也可以实现功能,称这种适配器为智能适配器。
2,Adaptee(被适配的接口)和Target(适配成为的接口)的关系
没有关联的。
3,对象组合
适配器的实现方式,依靠对象的组合方式(需要持有被适配的接口对象,用构造方法传入)。
优先使用对象组合,而不使用对象继承(单继承)
4,调用顺序示意图
5,适配器的实现
a,通常是一个类,实现Target接口,然后在适配器类中具体实现里面调用Adaptee
b,智能适配器
可以在适配器的实现里面,加入新功能的实现(也有可能完全重新实现(原有的逻辑有缺陷))
c,适配多个Adaptee
d,适配器实现的复杂度
取决于Adaptee和Target的相似度
e,缺省适配
为一个接口缺省实现,代码详见 example4 DefaultAdapter
四, 理解适配器模式
1,双向适配器
适配器实现双向适配,也就是说适配器可以同时当做Target和Adaptee来使用
2,对象适配器和类适配器
对象适配器:依赖于对象组合
类适配器:采用多重继承对一个接口与另一个接口进行匹配,由于java不支持,
类似实现类适配器
3,类适配器和对象适配器的权衡
4,适配器的优缺点
a,更好的复用性(调用以前的代码)
b,更好的可扩展性(智能适配器,可以扩展其他的功能)
c,过多的使用适配器,会让系统非常零乱,不容易进行整体把握(比如本来调用数据库,时间是操作文件)
5,适配器的本质
转换匹配(接口转换,),复用功能(目的)
6,何时选用适配器
- 如果想要使用一个存在的类,但是他的接口不符合你的需求,这种情况可以使用适配器模式,已有的实现转换成你需要的接口
- 如果你想创建一个可以复用的类,这个类可能和一些不兼容的类一起工作,需要什么适配什么
- 如果你想使用一些已经存在的子类,但是不可能对每一个子类进行适配,直接适配这些子类的父类就可以了