类结构的适配器模式 和 对象结构的适配器模式 有什么区别
适配器模式的核心是 "接口转换",让原本不兼容的接口可以协同工作。类结构适配器和对象结构适配器的核心区别在于适配方式:前者用继承,后者用组合。
先看一个生活场景
假设我们有一个 "旧设备"(比如老式充电器,输出 220V),但现在需要一个 "新接口"(比如手机需要 5V 充电)。我们需要一个 "适配器" 来完成 220V 到 5V 的转换。
1. 类结构的适配器模式(用继承实现)
类适配器通过继承旧设备类,同时实现新接口,来完成适配。
// 目标接口(新需求:需要5V电压)
interface Target {
int output5V();
}
// 被适配者(旧设备:只能输出220V)
class Adaptee {
public int output220V() {
return 220;
}
}
// 类适配器:继承旧设备,实现新接口
class ClassAdapter extends Adaptee implements Target {
@Override
public int output5V() {
// 调用父类(旧设备)的方法,再转换
int src = super.output220V();
return src / 44; // 220V转5V
}
}
// 客户端使用
public class Client {
public static void main(String[] args) {
Target adapter = new ClassAdapter();
System.out.println("类适配器输出电压:" + adapter.output5V() + "V"); // 输出5V
}
}
2. 对象结构的适配器模式(用组合实现)
对象适配器不继承旧设备,而是持有旧设备的实例,通过组合来调用其方法。
// 目标接口(同上:需要5V)
interface Target {
int output5V();
}
// 被适配者(同上:输出220V)
class Adaptee {
public int output220V() {
return 220;
}
}
// 对象适配器:持有旧设备实例,实现新接口
class ObjectAdapter implements Target {
private Adaptee adaptee; // 组合旧设备
// 通过构造器传入旧设备实例
public ObjectAdapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public int output5V() {
// 调用持有的旧设备实例的方法,再转换
int src = adaptee.output220V();
return src / 44; // 220V转5V
}
}
// 客户端使用
public class Client {
public static void main(String[] args) {
Adaptee oldDevice = new Adaptee();
Target adapter = new ObjectAdapter(oldDevice); // 传入旧设备实例
System.out.println("对象适配器输出电压:" + adapter.output5V() + "V"); // 输出5V
}
}
核心区别总结
| 维度 | 类结构适配器 | 对象结构适配器 |
|---|---|---|
| 实现方式 | 继承被适配者 + 实现目标接口 | 持有被适配者实例 + 实现目标接口 |
| 灵活性 | 低(只能适配特定类,不能适配子类) | 高(可适配任意被适配者及其子类) |
| 耦合度 | 高(与被适配者类强绑定) | 低(仅与被适配者接口 / 方法绑定) |
| 适用场景 | 被适配者类稳定,且不需要适配其子类 | 被适配者可能变化,或需要适配多种实现 |
实际开发中,对象适配器更常用,因为它遵循 "组合优于继承" 的设计原则,灵活性更高。
浙公网安备 33010602011771号