前言
适配器模式的定义很简单,就是做一个中间转换,类似港版的 iPad,iPhone 等电源插头,需要一个转换器,才能使用大陆的插座。
直接上代码,很简单,不多总结了。
类的适配器
被适配的类,可以看成是一个旧系统里的稳定的类
public class Adaptee { // 被适配的类 public void request() { System.out.println("被适配的类:request"); } }
下面的是新的接口,或者说需要适配的目标接口
public interface ITarget { // 新的接口 void doTargetRequest(); } ////////////////////////////////////////////////////// public class NewTarget implements ITarget { @Override public void doTargetRequest() { System.out.println("NewTarget的目标方法:doRequest"); } }
类的适配器,通过类的继承实现,下面是适配器类 Adapter,通过继承被适配者—— Adaptee,把被适配者的 API—— request 适配给目标接口—— ITarget 的 API—— doTargetRequest
public class Adapter extends Adaptee implements ITarget { // 类的适配器:Adapter(通过继承实现) @Override public void doTargetRequest() { // 这里可以写一些业务代码,如果有参数,就是对参数的转换过程 super.request(); // 通过 Adapter,把被适配者的API——request,适配给了目标接口——doTargetRequest。实现了对既有代码的复用 // 这里可以写一些业务代码 } }
客户端调用
public class Main { public static void main(String[] args) { ITarget target = new NewTarget(); target.doTargetRequest(); // NewTarget的目标方法:doRequest ITarget iTarget = new Adapter(); iTarget.doTargetRequest(); // 被适配的类:request } }
类适配器的类图
对象的适配器
类适配器通过继承被适配的类实现,而对象的适配器,通过组合被适配的类的引用实现
Itarget接口,Adaptee 类都不变,适配器类如下:
public class Adapter2 implements ITarget { private Adaptee adaptee; // 通过组合的方式 public Adapter2(Adaptee adaptee) { this.adaptee = adaptee; } @Override public void doTargetRequest() { // 这里可以写一些业务代码,如果有参数,就是对参数的转换过程 this.adaptee.request(); // 实现了对既有代码的复用,通过 Adapter,把被适配者的API——request,适配给了目标接口——doTargetRequest // 这里可以写一些业务代码 } }
客户端调用
public class Main2 { public static void main(String[] args) { ITarget target = new NewTarget(); target.doTargetRequest(); // NewTarget的目标方法:doRequest Adaptee adaptee = new Adaptee(); ITarget iTarget = new Adapter2(adaptee); iTarget.doTargetRequest(); // 被适配的类:request } }
对象适配器的类图
适配器使用场景
如果一个类已经稳定存在了,不想修改它,但是还要为其增加新需求,且这个需求和类的现有接口不能完全匹配,那么就可以使用适配器模式实现接口的转换以便满足新需求。
或者是为两个已有的接口提供一种协同工作方式。
还有一种使用情况,比如软件版本的升级和向后兼容,一些 API都会用到适配器模式。
这也是标题的意思——接口转换的利器。
适配器优缺点
优点很直接,就是提高类的的稳定性,增强其复用性,在不改变现有类的前提下,拓展类的功能,且能解耦目标类和适配器类,符合了开闭原则。
缺点就是会增加系统复杂度,其实我个人觉得微不足道
适配器模式和外观模式很像
外观模式是为旧接口(一般是比较复杂的接口),提供一个对外的简单接口,或者说更方便使用的访问入口。外观模式参考:为复杂系统提供一个对外窗口的方案——外观模式总结
适配器模式是让两个已有的接口协同工作
更一般的看,外观模式也是一种特殊的适配器,只不过它适配的是整个系统(粒度更大一些),为一个系统提供一个方便访问的对外接口。
适配器模式和装饰模式的区别
适配器模式用来转换不同接口,使旧接口和新接口能无缝衔接
装饰模式不会改变接口,只是给接口增加新功能
JDK 中使用适配器的类
最常见的有 I/O 包里的字符包装流,InputStreamReader、OutputStreamWriter 等,还有util 包里的Arrays.asList() 方法。
欢迎关注
dashuai的博客是终身学习践行者,大厂程序员,且专注于工作经验、学习笔记的分享和日常吐槽,包括但不限于互联网行业,附带分享一些PDF电子书,资料,帮忙内推,欢迎拍砖!