目录
- 一、 啥是适配器模式?
- 二、 为什么要用适配器模式?
- 三、 适配器模式的实现方式
- 1. 类适配器模式(继承插座 👨👩👧👦)
- 2. 对象适配器模式(插座转换器 🔌)
- 3. 接口适配器模式(万能插座 🗜️)
- 四、 三种适配器的对比
- 五、 适配器模式的优缺点
- 六、 适配器模式的应用场景
- 七、 总结
🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!
🌟了解代理模式请看: (六)趣学设计模式 之 代理模式!
这篇文章带你详细认识一下设计模式中的适配器模式
一、 啥是适配器模式?
想象一下,你买了一个新的电器 💡,但是插头和家里的插座不匹配 😫,怎么办? 这时候就需要一个插座转换器 🔌,把电器的插头转换成家里的插座可以使用的类型 💡。
适配器模式,就是用来解决接口不兼容的问题! 它可以将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 🤝。
简单来说,就是把不兼容的接口转换成兼容的接口!
- 你想使用一个类,但是它的接口和你需要的接口不一样: 就像你想用一个旧的类库,但是它的接口和你的代码不兼容 😫!
- 你想让两个接口不兼容的类一起工作: 就像你想让一个美国的插头和一个中国的插座一起工作 🔌!
- 你想重用一些现有的类,但是它们的接口不符合你的要求: 就像你想用一个旧的算法,但是它的输入输出格式和你的代码不兼容 😫!
二、 为什么要用适配器模式?
用适配器模式,好处多多 👍:
- 提高类的复用性: 可以将一些现有的类适配成新的接口,方便重用 ♻️!
- 提高系统的灵活性: 可以动态地选择不同的适配器,使得系统更加灵活 🤸!
- 符合开闭原则: 可以在不修改现有代码的情况下,增加新的适配器,扩展功能 🆕!
- 解耦: 将客户端和目标类解耦,降低系统的耦合度 🔗!
三、 适配器模式的实现方式
适配器模式主要分为三种:
- 类适配器模式: 通过继承来实现适配,就像继承了插座的类 👨👩👧👦!
- 对象适配器模式: 通过组合来实现适配,就像用一个插座转换器 🔌!
- 接口适配器模式: 通过实现一个抽象类来实现适配,就像万能插座 🗜️!
1. 类适配器模式(继承插座 👨👩👧👦)
类适配器模式,通过继承来实现适配,就像继承了插座的类,拥有了插座的功能 🔌!
案例:电压适配器(经典案例 ⚡)
假设你有一个 220V 的电源 🔌,但是你需要给一个 5V 的设备充电 📱,怎么办? 这时候就需要一个电压适配器,把 220V 的电压转换成 5V 的电压 ⚡!
代码示例:
// 目标接口:5V 电压
public interface Voltage5V {int output5V(); // 输出 5V 电压
}// 需要适配的类:220V 电压
public class Voltage220V {public int output220V() {int src = 220;System.out.println("我是220V电压");return src;}
}// 适配器类:电压适配器
public class VoltageAdapter extends Voltage220V implements Voltage5V {@Overridepublic int output5V() {// 获取 220V 电压int srcV = output220V();// 转换成 5V 电压int dstV = srcV / 44;return dstV;}
}// 客户端
public class Client {public static void main(String[] args) {VoltageAdapter adapter = new VoltageAdapter(); // 创建适配器对象int voltage = adapter.output5V(); // 获取 5V 电压System.out.println("输出电压为:" + voltage + "V"); // 输出电压}
}
分析:
Voltage5V
是目标接口,客户端需要使用 5V 电压。Voltage220V
是需要适配的类,它只能输出 220V 电压。VoltageAdapter
是适配器类,它继承了Voltage220V
类,并实现了Voltage5V
接口,将 220V 电压转换成 5V 电压。
输出结果:
我是220V电压
输出电压为:5V
2. 对象适配器模式(插座转换器 🔌)
对象适配器模式,通过组合来实现适配,就像用一个插座转换器,把电器的插头转换成家里的插座可以使用的类型 🔌!
案例:还是电压适配器(对象版⚡)
还是上面的电压适配器的例子,但是这次我们使用对象适配器模式来实现 🚀!
代码示例:
// 目标接口:5V 电压
public interface Voltage5V {int output5V(); // 输出 5V 电压
}// 需要适配的类:220V 电压
public class Voltage220V {public int output220V() {int src = 220;System.out.println("我是220V电压");return src;}
}// 适配器类:电压适配器
public class VoltageAdapter implements Voltage5V {private Voltage220V voltage220V; // 组合 220V 电压对象public VoltageAdapter(Voltage220V voltage220V) {this.voltage220V = voltage220V;}@Overridepublic int output5V() {// 获取 220V 电压int srcV = voltage220V.output220V();// 转换成 5V 电压int dstV = srcV / 44;return dstV;}
}// 客户端
public class Client {public static void main(String[] args) {Voltage220V voltage220V = new Voltage220V(); // 创建 220V 电压对象VoltageAdapter adapter = new VoltageAdapter(voltage220V); // 创建适配器对象int voltage = adapter.output5V(); // 获取 5V 电压System.out.println("输出电压为:" + voltage + "V"); // 输出电压}
}
分析:
Voltage5V
是目标接口,客户端需要使用 5V 电压。Voltage220V
是需要适配的类,它只能输出 220V 电压。VoltageAdapter
是适配器类,它组合了Voltage220V
类,并实现了Voltage5V
接口,将 220V 电压转换成 5V 电压。
输出结果:
我是220V电压
输出电压为:5V
3. 接口适配器模式(万能插座 🗜️)
接口适配器模式,通过实现一个抽象类来实现适配,就像万能插座,可以兼容各种类型的插头 🗜️!
案例:USB 接口适配器(万能接口 💻)
假设你有一个 USB 设备 💾,但是你的电脑只有 Type-C 接口 💻,怎么办? 这时候就需要一个 USB 接口适配器,把 USB 接口转换成 Type-C 接口 💻!
代码示例:
// 目标接口:USB 接口
public interface Usb {void read(); // 读取数据void write(); // 写入数据void connect(); // 连接设备void disconnect(); // 断开连接
}// 抽象适配器类:USB 适配器
public abstract class UsbAdapter implements Usb {@Overridepublic void read() {// 默认实现,可以不实现}@Overridepublic void write() {// 默认实现,可以不实现}@Overridepublic void connect() {// 默认实现,可以不实现}@Overridepublic void disconnect() {// 默认实现,可以不实现}
}// 需要适配的类:Type-C 设备
public class TypeCDevice extends UsbAdapter {@Overridepublic void read() {System.out.println("Type-C 设备读取数据");}@Overridepublic void write() {System.out.println("Type-C 设备写入数据");}
}// 客户端
public class Client {public static void main(String[] args) {TypeCDevice typeCDevice = new TypeCDevice(); // 创建 Type-C 设备对象typeCDevice.connect(); // 连接设备typeCDevice.read(); // 读取数据typeCDevice.write(); // 写入数据typeCDevice.disconnect(); // 断开连接}
}
分析:
Usb
是目标接口,客户端需要使用 USB 接口。UsbAdapter
是抽象适配器类,它实现了Usb
接口,但是提供了默认实现,子类可以选择性地实现需要的方法。TypeCDevice
是需要适配的类,它继承了UsbAdapter
类,并实现了read
和write
方法,实现了 USB 接口的功能。
输出结果:
Type-C 设备读取数据
Type-C 设备写入数据
四、 三种适配器的对比
特性 | 类适配器模式 | 对象适配器模式 | 接口适配器模式 |
---|---|---|---|
实现方式 | 继承 | 组合 | 抽象类 |
优点 | 简单易用 | 灵活,可以适配多个类 | 可以选择性地实现接口方法 |
缺点 | 只能适配一个类,耦合度较高 | 需要持有目标类的对象,增加了对象的数量 | 需要定义抽象类,增加了类的数量 |
适用场景 | 目标类接口比较稳定,不需要经常修改 | 需要适配多个类,或者目标类接口经常修改 | 只需要使用接口中的部分方法 |
五、 适配器模式的优缺点
优点:
- 提高类的复用性 ♻️!
- 提高系统的灵活性 🤸!
- 符合开闭原则 🆕!
- 解耦 🔗!
缺点:
- 增加了系统的复杂度 😫!
- 可能会降低性能 🐌!
六、 适配器模式的应用场景
- 接口转换: 将一个类的接口转换成客户希望的另外一个接口 🔌!
- 数据转换: 将一种格式的数据转换成另外一种格式的数据 🗂️!
- 遗留系统集成: 将新的系统和旧的系统集成在一起 🤝!
- 第三方库集成: 将第三方库集成到你的项目中 📚!
七、 总结
- 适配器模式就像插座转换器,让不兼容的接口也能愉快玩耍! 🔌
- 主要分为类适配器模式、对象适配器模式和接口适配器模式三种! 🤸
- 优点是提高类的复用性、提高系统的灵活性、符合开闭原则、解耦! 👍
- 缺点是增加复杂度、可能降低性能! 👎
- 适用于需要解决接口不兼容的问题的场景! 🎯
希望这篇文章能让你彻底理解适配器模式! 💯 祝你学习愉快! 😄
看完请看:(八)趣学设计模式 之 装饰器模式!