适配器模式(Adapter Pattern)
适配器模式(Adapter Pattern)
适配器模式是一种结构型设计模式,它通过将一个类的接口转换成客户端期望的另一个接口,使得原本接口不兼容的类可以协同工作。适配器模式的核心是接口转换,它充当两个不兼容接口之间的桥梁。
模式结构
- 目标接口(Target)
定义客户端需要的接口方法。 - 适配者类(Adaptee)
现有的类,其接口与客户端需求不兼容,需要被适配。 - 适配器类(Adapter)
实现目标接口,并通过继承或组合的方式调用适配者类的方法,完成接口转换。
适配器模式有两种实现方式:
- 类适配器:通过继承适配者类实现目标接口。
- 对象适配器:通过组合适配者类的实例实现目标接口。
代码示例
1. 目标接口(Target)
// 目标接口:定义客户端需要的电压获取方法
interface SocketAdapter {
Volt get120Volt();
Volt get12Volt();
Volt get3Volt();
}
2. 适配者类(Adaptee)
// 适配者类:现有插座类,仅支持120V电压
class Socket {
public Volt getVolt() {
return new Volt(120);
}
}
3. 类适配器(Class Adapter)
// 类适配器:通过继承适配者类实现目标接口
class SocketClassAdapterImpl extends Socket implements SocketAdapter {
@Override
public Volt get120Volt() {
return super.getVolt();
}
@Override
public Volt get12Volt() {
return convertVolt(super.getVolt(), 10);
}
@Override
public Volt get3Volt() {
return convertVolt(super.getVolt(), 40);
}
private Volt convertVolt(Volt volt, int divisor) {
return new Volt(volt.getVolts() / divisor);
}
}
4. 对象适配器(Object Adapter)
// 对象适配器:通过组合适配者类的实例实现目标接口
class SocketObjectAdapterImpl implements SocketAdapter {
private final Socket socket;
public SocketObjectAdapterImpl(Socket socket) {
this.socket = socket;
}
@Override
public Volt get120Volt() {
return socket.getVolt();
}
@Override
public Volt get12Volt() {
return convertVolt(socket.getVolt(), 10);
}
@Override
public Volt get3Volt() {
return convertVolt(socket.getVolt(), 40);
}
private Volt convertVolt(Volt volt, int divisor) {
return new Volt(volt.getVolts() / divisor);
}
}
5. 调用示例
public class AdapterPattern {
public static void main(String[] args) {
// 使用类适配器
SocketAdapter classAdapter = new SocketClassAdapterImpl();
System.out.println("类适配器输出:");
System.out.println("3V电压:" + classAdapter.get3Volt().getVolts());
System.out.println("12V电压:" + classAdapter.get12Volt().getVolts());
// 使用对象适配器
SocketAdapter objectAdapter = new SocketObjectAdapterImpl(new Socket());
System.out.println("\n对象适配器输出:");
System.out.println("3V电压:" + objectAdapter.get3Volt().getVolts());
System.out.println("12V电压:" + objectAdapter.get12Volt().getVolts());
}
}
输出结果
类适配器输出:
3V电压:3
12V电压:12
对象适配器输出:
3V电压:3
12V电压:12
应用场景
- 集成第三方库或旧系统
当需要复用已有的类,但其接口与当前系统不兼容时,可以使用适配器模式。 - 统一多个类的接口
当多个类提供类似功能但接口不同时,适配器模式可以统一接口调用方式。 - 接口版本升级
在新接口需要兼容旧接口时,适配器可以作为中间层平滑过渡。
在Java中的应用
java.io.InputStreamReader
和OutputStreamWriter
这两个类将字节流(InputStream
/OutputStream
)适配为字符流(Reader
/Writer
)。- 集合框架
java.util.Collections.list(Enumeration)
方法将旧的Enumeration
接口适配为List
接口。 - GUI事件处理
Java Swing中的事件监听器适配器类(如WindowAdapter
)提供默认实现,简化事件处理。
优缺点
优点
- 解耦
客户端代码与适配者类解耦,只需依赖目标接口。 - 复用性
可以复用现有的类,无需修改其代码。 - 灵活性
对象适配器支持动态组合,适用于需要适配多个类的场景。
缺点
- 复杂性增加
引入适配器类会增加代码结构的复杂度。 - 过度适配
如果滥用适配器模式,可能导致系统层次过多,难以维护。
总结
适配器模式通过接口转换,解决了不兼容类之间的协作问题。它适用于集成第三方库、复用旧代码或统一多个接口的场景。类适配器通过继承实现,简单但受限于单继承;对象适配器通过组合实现,更灵活且符合合成复用原则。在Java中,适配器模式广泛应用于IO流、集合框架和GUI开发中,是解决接口兼容性问题的经典方案。