适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一个接口。通过使用适配器模式,原本由于接口不兼容的类可以进行协作。简单来说,适配器模式就是将不兼容的接口连接起来,使得客户端能够与之交互而不需要修改原有代码。
在现实世界中,这就像是一个电压适配器,它将不同电压的插头转化为标准插座的电压和插头,以便设备能够正常使用。
一、适配器模式的结构
适配器模式的结构通常由以下几个部分组成:
- Target(目标接口): 客户端依赖的接口。
- Adapter(适配器): 通过继承或组合将 Adaptee 转换为 Target,使得客户端可以通过目标接口与适配者交互。
- Adaptee(适配者): 需要适配的类,它的接口不能直接与客户端的接口兼容。
二、适配器模式的分类
适配器模式有两种常见的实现方式:
-
类适配器模式(Class Adapter Pattern):
- 使用继承来实现适配。
- 适配器类继承自适配者类,并实现目标接口。
- 这种方式利用了类的继承关系,将适配者类的接口转换为目标接口。
-
对象适配器模式(Object Adapter Pattern):
- 使用组合来实现适配。
- 适配器类包含一个适配者对象,并通过该对象将适配者的接口转换为目标接口。
- 这种方式通过对象组合的方式解决适配问题,相比类适配器模式,它更加灵活且避免了多重继承带来的复杂性。
三、适配器模式的示例
现有一台电脑只能读取SD卡,而要读取TF卡中的内容的话就需要使用到适配器模式。创建一个读卡器,将TF卡中的内容读取出来。
1. 示例一:类适配器模式
- SD卡接口
public interface SDCard { public void readSD(); }
- SD卡实现类
public class SDCardImpl implements SDCard { @Override public void readSD() { System.out.println("正在读取SD卡信息"); } }
- 读卡器
public class TFAdaptCD extends TFCardImpl implements SDCard { @Override public void readSD() { System.out.println("正在通过适配器读取"); readTFCard(); } }
- TF卡接口
public interface TFCard { public void readTFCard(); }
- TF卡实现类
public class TFCardImpl implements TFCard { @Override public void readTFCard() { System.out.println("正在读取TF卡信息"); } }
- 电脑类
public class Computer { public void readSD(SDCard cdCard){ cdCard.readSD(); } }
- 测试类
public class Client { public static void main(String[] args) { Computer computer = new Computer(); computer.readSD(new SDCardImpl()); computer.readSD(new TFAdaptCD()); } }
- 结果
2. 示例二:对象适配器模式
只需要更改适配器类
public class TFAdaptCD implements SDCard {
TFCard tfCard = new TFCardImpl();
@Override
public void readSD() {
System.out.println("正在通过适配器读取");
tfCard.readTFCard();
}
}
客户端类
public class Client {
public static void main(String[] args) {
Computer computer = new Computer();
computer.readSD(new SDCardImpl());
computer.readSD(new TFAdaptCD(new TFCardImpl()));
}
}
四、适配器模式的应用场景
适配器模式的使用场景通常包括以下几种情况:
-
需要使用一个已有的类,但它的接口和客户端需要的接口不兼容。
当你想要复用一个已经存在的类,但它的接口与当前系统的接口不兼容时,适配器模式是一个有效的解决方案。 -
希望通过一个新接口来替代原本的接口,而不修改现有代码。
适配器模式允许你在不改变原有代码的情况下,将现有的接口转化为你期望的接口。 -
希望让某个类与其他类协同工作,而它们的接口不兼容。
适配器模式为不同的类提供了一个桥梁,使得它们能够协同工作。 -
希望对某个类的接口进行改造,但不想修改原类的实现。
在这种情况下,适配器模式通过封装原有类的功能,提供一个新的接口,避免修改原始类的代码。 -
第三方库的接口不符合需求时。
当你使用第三方库时,它的接口可能无法满足当前系统的需求。适配器模式可以帮助你对这些接口进行适配,使它们能够与现有系统兼容。
五、适配器模式的优缺点
优点:
- 解耦合: 客户端与适配者之间通过适配器进行交互,客户端不需要知道适配者的实现细节。客户端依赖于目标接口,而不是适配者的实现,增强了系统的灵活性。
- 复用性: 通过适配器模式,可以将多个不兼容的接口组合在一起进行复用,使系统具备更高的可复用性。
- 灵活性: 如果需要改变适配的类,适配器模式允许你不修改客户端代码,只需要更换适配器即可。
- 增强了系统的扩展性: 适配器模式可以帮助系统扩展新的功能,而不会影响现有的接口或系统。
缺点:
- 增加了额外的类: 适配器模式引入了额外的适配器类,这可能会使得系统的复杂性增加,尤其是当使用适配器类的数量较多时。
- 性能开销: 适配器类通常会做一些额外的转换工作,因此可能会带来一些性能开销,尤其是在高频次的调用场景中。
- 难以管理复杂的适配器: 当系统中需要适配的接口较多时,适配器的数量会增加,这可能会导致管理上的困难。