1. 适配器模式
##1.1 介绍
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。
适配器模式就是在不改变原有结构和功能前提下,对类进行拓展(满足开闭原则),在继承原有类的基础上生成适配器类并实现对应接口,将现有类不能处理的请求,通过调用适配器类实现接口的方法进行完成。
1.2 优缺点
优点
- 可以让任何两个没有关联的类一起运行。
- 提高了类的复用
- 增加了类的透明度
- 灵活性好
缺点
- 过多地使用适配器,会让系统非常零乱,不易整体进行把握
- 于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类
1.3 使用场景
- 有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。
1.4 注意事项
- 适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。
#2. 案例实现
现在某辆车需要播放CD功能,但是普通的CD播放器无法搭载在车上,因此我们使用了一个适配器类来实现CD接口,通过组合CDPlayer来实现播放功能。
public interface CD {
void play();
}
public class CDPlayer implements CD {
@Override
public void play() {
System.out.println("演唱");
}
}
public class CDPlayerCarAdapter implements CD {
private CDPlayer cdPlayer;
public CDPlayerCarAdapter(CDPlayer cdPlayer) {
this.cdPlayer = cdPlayer;
}
@Override
public void play() {
System.out.println("适配器工作");
cdPlayer.play();
}
}
public class Car {
// 汽车无法使用普通的CDPlay
private CDPlayerCarAdapter cdPlayerCarAdapter;
public Car(CDPlayerCarAdapter cdPlayerCarAdapter) {
this.cdPlayerCarAdapter = cdPlayerCarAdapter;
}
public void playCD(){
cdPlayerCarAdapter.play();
}
}
/** * 适配器模式 * *@Author cly *@Date 2021/08/31 1:52 *@Version 1.0 */
public class Adapter {
public static void main(String[] args) {
CDPlayer cdPlayer = new CDPlayer();
Car car = new Car(new CDPlayerCarAdapter(cdPlayer));
car.playCD();
}
}
3. 源码实现
3.1 java.util.Enumeration
java.util.Enumeration JDK 1.0 提供用于遍历容器类的接口,但是一个公认的设计失误,所以 JDK 1.2 对其进行了重构,新增 Iterator 接口去迭代容器类。
JDK 为了保证向后兼容,就在容器工具类 java.util.Collections 的 enumeration 方法中使用了适配器模式,用 Collection#iterator() 构造 Enumeration 对象,源码如下:
public class Collections {
private Collections() {
}
public static <T> Enumeration<T> enumeration(final Collection<T> c) {
return new Enumeration<T>() {
private final Iterator<T> i = c.iterator();
public boolean hasMoreElements() {
return i.hasNext();
}
public T nextElement() {
return i.next();
}
};
}
}
3.2 Spring AOP
Spring AOP的增强或通知(Advice)使用到了适配器模式,Spring MVC中也是用到了适配器模式适配Controller