适配器模式:将不兼容的接口转换为可兼容的接口
什么是适配器模式?
适配器模式是一种结构型设计模式,用于将一个类的接口转换为客户端所期望的另一个接口
。它允许不兼容的类能够合作,使得原本由于接口不匹配而无法工作的类能够一起工作
。
适配器模式通过创建一个适配器类,将原本不兼容的接口转换为目标接口,从而使得客户端能够使用目标接口来调用适配器类。适配器类实现了目标接口,并在内部持有一个原本不兼容的类的实例,通过适配器类的方法来调用原本不兼容类的方法。
优缺点
优点
- 兼容性:适配器模式可以解决不同类之间接口不兼容的问题,使得原本无法合作的类能够一起工作。
- 复用性:适配器模式可以复用已有的类,通过适配器类来使用这些类,而无需修改原有代码。
- 灵活性:适配器模式可以在不修改原有代码的情况下,通过适配器类来扩展功能或修改行为。
缺点: 过多地使用适配器,会让系统非常零乱,不易整体进行把握
。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
示例
假设我们要给手机充电,该手机充电的电压只支持4v,现在电源电压是220v,为了能够给手机充电,我们可以使用适配器模式,将电压转为为4v。
目标类:手机
public class Phone {
// 充电
public void chargin(IVoltage5V iVoltage5V) {
if (iVoltage5V.output5V() == 5) {
System.out.println("电压为5V,可以充电~");
} else if (iVoltage5V.output5V() > 5) {
System.out.println("电压大于5V,不能充电");
}
}
}
原本不兼容的类:220V电源插座
// 被适配器类
public class Voltage220V {
public int output220V() {
int src = 220;
System.out.println("电压=220V");
return src;
}
}
适配器接口
public interface IVoltage5V {
public int output5V();
}
适配器类:220V电源适配器
// 适配器类
public class VotageAdapter extends Voltage220V implements IVoltage5V{
@Override
public int output5V() {
int srcV = output220V(); // 获取220V电压
int dstV = srcV / 44; // 转成5V电压
return dstV;
}
}
客户端代码
public class Client {
public static void main(String[] args) {
System.out.println("-------使用类适配器------------");
Phone phone = new Phone();
phone.chargin(new VotageAdapter());
}
}
源码分析
Java IO中,InputStreamReader
和 OutputStreamWriter
就是两个适配器(Adapter),它们两个是字节流和字符流之间的桥梁。InputStreamReader
使用 StreamDecoder
(流解码器)对字节进行解码,实现字节流到字符流的转换, OutputStreamWriter
使用StreamEncoder
(流编码器)对字符进行编码,实现字符流到字节流的转换。
// InputStreamReader 是适配器,FileInputStream 是被适配的类
InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName), "UTF-8");
InputStreamReader部分源码:
public class InputStreamReader extends Reader {
//用于解码的对象
private final StreamDecoder sd;
public InputStreamReader(InputStream in) {
super(in);
try {
// 获取 StreamDecoder 对象
sd = StreamDecoder.forInputStreamReader(in, this, (String)null);
} catch (UnsupportedEncodingException e) {
throw new Error(e);
}
}
// 使用 StreamDecoder 对象做具体的读取工作
public int read() throws IOException {
return sd.read();
}
}
总结
适配器模式是一种非常有用的设计模式,它可以解决不兼容的接口问题,使得原本无法合作的类能够一起工作。通过创建一个适配器类,将原本不兼容的接口转换为目标接口,适配器模式提供了一种灵活、可复用的方式来扩展功能或修改行为。在实际开发中,适配器模式经常被用于集成不同系统或库之间的接口,以实现系统的互操作性和可扩展性。