《设计模式》-- 适配器模式
来源:互联网 发布:linux下串口调试助手 编辑:程序博客网 时间:2024/05/15 14:41
适配器模式
- 适配器模式
- 认识
- 思考
- 使用场景
- 优缺点
- UML图
- 类适配器
- 对象适配器
- 缺省适配
- 代码实现
- 类适配器
- 对象适配器
- 缺省适配
认识
适配器模式是将一个类的接口变为客户端想要的另外一个接口,从而使原本因接口不匹配无法在一起工作的两个类能够在一起工作。适配器的目的是复用已有的功能。
适配器分为类适配器和对象适配器两种
缺省适配:为一个接口提供缺省实现,一般是一个抽象类
适配器模式跟代理模式的不同之处:适配器模式中适配器和被适配对象中的接口方法不一致,适配器对被适配对象中的接口进行了改造或者扩展。代理模式中代理对象和被代理对象实现同一个接口,可以相互替换,代理对象只是对被代理对象中接口方法中的逻辑进行了改变,如添加权限控制。
思考
适配器模式可以对一个接口的所有子类进行适配,对象适配器中持有一个父类指针。不需要单独去对每个子类建立适配器。
适配器模式实质:转换接口,复用功能,通过适配器将老的接口实现类中的方法转换为新的接口中的方法
优先使用对象适配器,多用合成/聚合,少用继承。
使用场景
如果定义了新的接口跟已存在一个实现类不兼容,但是又在新的接口中又想使用实现类中方法,这时使用适配器模式实现复用实现类中的功能。
优缺点
优点
- 更好的复用性:能够兼容使用老的接口
- 开闭原则:避免了对老接口的修改,通过添加适配器实现兼容,达到更好的扩展性
缺点
- 过多的使用适配器模式,会导致调用零乱,明明调用A接口,在A接口中实际调用的是B接口,脱离控制。如果不是很有必要,可以不使用适配器,而是对系统进行重构。
UML图
类适配器:
采用继承方式,即适配器继承被适配类
- 目标接口(Target):客户端真正想要的接口
- 被适配接口(Adaptee):已有的接口实现类,与客户端最新需要的接口不兼容
- 适配器(Adapter):适配器,实现Target和继承Adaptee,客户端调动Adapter,既可以调用Target中的接口方法,也可以调用Adapter继承Adaptee中老的方法
对象适配器:
使用对象动态组合方式,即适配器持有一个被适配对象
- 目标接口(Target):客户端真正想要的接口
- 被适配接口(Adaptee):已有的接口实现类,与客户端最新需要的接口不兼容
- 适配器(Adapter):适配器,实现Target,持有一个Adaptee对象,对于新的接口,调用Adapter中实现的方法,对于老的方法,使用Adaptee对象进行调用
缺省适配
很多情况下,接口中定义了特别多方法,而一个类去实现一个接口,必须要实现所有的方法,但是有些类只是使用到了接口中很少的方法,对于不使用的方法就只能空着,这样会对客户端的调用造成困扰。这时就需要使用一个抽象类去实现接口,在抽象类中给出所有方法的”平庸”实现。从这个抽象类再继承下去的子类就不必实现所有的方法了。,在java源码中很多地方都使用到了这种处理,如List中等。缺省适配的用意是为了避免子类去处理自己不关注的接口方法
代码实现
类适配器:
适配器继承被适配对象,实现目标接口,客户端使用适配器进行调用,对于目标接口中新的方法,适配器进行实现,对于老的接口方法,调用适配器继承而来的被适配类中的方法,从而实现接口兼容。
/** * 客户端需要的接口 */public interface Target { /** * 这是源类Adaptee也有的方法 */ public void sampleOperation1(); /** * 这是源类Adapteee没有的方法 */ public void sampleOperation2(); }/** * 已经存在的接口实现,这个接口实现需要被适配 */public class Adaptee { public void sampleOperation1(){}}/** * 适配器,继承被适配类,实现目标接口 */public class Adapter extends Adaptee implements Target { /** * 由于源类Adaptee没有方法sampleOperation2() * 因此适配器补充上这个方法 */ @Override public void sampleOperation2() { //写相关的代码 }}
对象适配器:
适配器实现目标对象,通过构造方法持有一个被适配对象,客户端使用适配器进行调用,对于新的接口调用适配器中的方法,对于老的接口实现,适配器使用被适配对象调用被适配对象中的方法,从而实现接口兼容。
/** * 客户端需要的接口 */public interface Target { public void request1(); public void request2();}/** * 已经存在的接口,这个接口需要被适配 */public class Adaptee { /** * 示意方法,原本已经存在,已经实现的方法 */ public void request1() { //具体的功能处理 }}/** * 适配器 */public class Adapter implements Target { /** * 持有需要被适配的接口对象 */ private Adaptee adaptee; /** * 构造方法,传入需要被适配的对象 * @param adaptee 需要被适配的对象 */ public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } public void request1() { //可能转调已经实现了的方法,进行适配 adaptee.request1(); } public void request2() { //业务代码 }}/** * 使用适配器的客户端 */public class Client { public static void main(String[] args) { //创建需被适配的对象 Adaptee adaptee = new Adaptee(); //创建客户端需要调用的接口对象 Target target = new Adapter(adaptee); //请求处理 target.request(); }}
缺省适配:
使用抽象类实现接口,对接口中方法进行默认实现。
- 设计模式:适配器模式
- 设计模式------适配器模式
- 设计模式:适配器模式
- 设计模式---适配器模式
- 设计模式 适配器模式
- 设计模式 - 适配器模式
- 设计模式--适配器模式
- 设计模式-适配器模式
- 设计模式------适配器模式
- 设计模式---适配器模式
- 设计模式- 适配器模式
- 设计模式 - 适配器模式
- 设计模式:适配器模式
- 适配器模式--设计模式
- 设计模式 - 适配器模式
- 设计模式-适配器模式
- 设计模式---适配器模式
- 设计模式-适配器模式
- C++多态
- Java中关于函数回调和反射机制的介绍
- 大话消息队列的流派之争
- SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
- Dockerfile 指令和结构
- 《设计模式》-- 适配器模式
- 安卓图片加载库
- 本节将演示在3D空间中绘制图形的几个简单实例:
- 渲染管线
- [BZOJ3040][STL配对堆]最短路(road)
- C++使用复制构造函数的情况
- 二维码生成
- RMQ问题之ST算法
- 2016网易招聘-暗黑的字符串