- 适配器模式的应用场景:当我们需要修改一个
已经投产中的接口
时,适配器模式此时最合适- 适配器模式最好在开发阶段或者详细设计时
不要考虑
,适配器模式不是为了解决还处于开发阶段的问题,而是解决正在服役的项目问题
,当时自己也学得不精,自认为看了一点适配器模式学到了一点点就想着在项目中用用,后来用了一个周左右才知道方向跑偏了,一直想着吧两个无关的类联系在一起,提高我们当时所谓的复用性,所以就基本上白花了一个周左右的时间 - 适配器(Adapter Pattern)模式
主要用于接口互不兼容的类的协调工作
,你可以将其联想到我们日常经常使用的电源适配器- 适配器模式中存在被适配的对象或者类称为 适配者(Adaptee) ,
作用于适配者的对象或者类称为适配器(Adapter)
。适配器分为对象适配器和类适配器
。类适配器使用继承关系来实现,对象适配器使用组合关系来实现
。 - IO 流中的字符流和字节流的接口不同,
IO 流中的字符流和字节流的接口之间可以协调工作就是基于适配器模式来做的,更准确点来说是对象适配器
。通过适配器,我们可以将字节流对象适配成一个字符流对象,这样我们可以直接通过字节流对象来读取或者写入字符数据。InputStreamReader 和 OutputStreamWriter 就是两个适配器(Adapter)
, 同时,它们两个也是字节流和字符流之间的桥梁
。InputStreamReader 使用 StreamDecoder (流解码器)对字节进行解码,实现字节流到字符流的转换, OutputStreamWriter 使用StreamEncoder(流编码器)对字符进行编码,实现字符流到字节流的转换。
- InputStream 和 OutputStream 的子类是被适配者, InputStreamReader 和 OutputStreamWriter是适配器
- 除了IO中,FutrueTask 类使用了适配器模式,Executors 的内部类 RunnableAdapter 实现属于适配器,
用于将 Runnable 适配成 Callable
public FutureTask(Runnable runnable, V result) { // 调用 Executors 类的 callable 方法 this.callable = Executors.callable(runnable, result);//Executors中对应的方法和适配器 this.state = NEW; } // 实际调用的是 Executors 的内部类 RunnableAdapter 的构造方法 public static <T> Callable<T> callable(Runnable task, T result) { if (task == null) throw new NullPointerException(); return new RunnableAdapter<T>(task, result); } // 适配器 static final class RunnableAdapter<T> implements Callable<T> { final Runnable task; final T result; RunnableAdapter(Runnable task, T result) { this.task = task; this.result = result; } public T call() { task.run(); return result; } }
- 适配器模式和装饰器模式有什么区别:
- 装饰器模式 更侧重于
动态地增强原始类的功能
,装饰器类需要跟原始类继承相同的抽象类或者实现相同的接口。并且,装饰器模式支持对原始类嵌套使用多个装饰器。 - 适配器模式 更侧重于
让接口不兼容而不能交互的类可以一起工作
,当我们调用适配器对应的方法时,适配器内部会调用适配者类或者和适配类相关的类的方法,这个过程透明的。就比如说 StreamDecoder (流解码器)和StreamEncoder(流编码器)就是分别基于 InputStream 和 OutputStream 来获取 FileChannel对象并调用对应的 read 方法和 write 方法进行字节数据的读取和写入。并且适配器和适配者两者不需要继承相同的抽象类或者实现相同的接口
。
- 装饰器模式 更侧重于
- 适配器模式中存在被适配的对象或者类称为 适配者(Adaptee) ,
- 适配器模式最好在开发阶段或者详细设计时
未完待续…