1. 简介
笔记本实际上使用的是 12V 直流电,但是我们电源线是插在 220V 的交流电源上。我们不能把 220V 的交流电源直接改成符合要求的 12V 直流电源,因为不便于运输,也没法让笔记本直接使用 220V 的交流电,因为其元器件无法承担。 220V 交流电源和笔记本本质上是无法直接放到一起工作的,那么就需要电源适配器的辅助。它能够利用 220V 交流电源获取电能,并转换成 12V 直流电输出给笔记本。 这就是适配器模式,将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
2. 角色与分类
角色:
- Target(目标):客户的目标接口,可以是一个抽象类或接口,也可以是具体类。
- Adaptee(适配者):被适配的角色,是一个已有接口,但不符合客户要求。
- Adapter(适配器):将已有接口转换成目标接口
分类:
- 类适配器模式
- 对象适配器模式
- 缺省适配器模式,也叫接口适配器模式
3. 类适配器模式
Adapter 可以继承一个已有的 Adaptee,然后实现 Target。这种情况下只能有一个 Adaptee,且 Target 必须是接口。
image.png
代码语言:javascript复制interface PowerTarget {
output12V(): string;
}
class PowerAdaptee {
output220V() {
return '220V 交流电';
}
}
const adapt = (input) => {
// TODO 具体转换逻辑
console.log(`${input} 被转换成 12V 直流电`);
return '12V 直流电';
};
class PowerAdapter extends PowerAdaptee implements PowerTarget {
public output12V() {
const input = this.output220V();
console.log(`电源适配器开始工作,获取:${input}`);
const output = adapt(input);
console.log(`电源适配器工作完成,输出:${output}`);
return output;
}
}
const target: PowerTarget = new PowerAdapter();
target.output12V();
image.png
4. 对象适配器模式
Adapter 可以关联个已有的 Adaptee,然后实现 Target。这种情况下你要依赖多个 Adaptee 实现也是 okay 的,Target 可以是接口也可以是抽象类甚至是类。 不过这里因为是关联,所以改写关联对象的方法就很麻烦了,不像继承那么简单。
image.png
代码语言:javascript复制interface PowerTarget {
output12V(): string;
}
class PowerAdaptee {
output220V(): string {
return '220V 交流电';
}
}
const adapt = (input) => {
// TODO 具体转换逻辑
console.log(`${input} 被转换成 12V 直流电`);
return '12V 直流电';
};
class PowerAdapter implements PowerTarget {
private powerAdaptee: PowerAdaptee;
constructor() {
this.powerAdaptee = new PowerAdaptee();
}
public output12V(): string {
const input = this.powerAdaptee.output220V();
console.log(`电源适配器开始工作,获取:${input}`);
const output = adapt(input);
console.log(`电源适配器工作完成,输出:${output}`);
return output;
}
}
const target: PowerTarget = new PowerAdapter();
target.output12V();
5. 小结
其实还有一种缺省适配器模式,就是只想实现 target 接口定义的部分方法,那么在 adapter 和 target 之间加一层 defaultAdapter,用空方法实现 target 的所有接口,真正的 adapter 就可以选择性的重写 defaultAdapter 中需要去适配的方法了。本质上还是用的类适配器模式和对象适配器模式。 可以看到,适配器模式,也可以看做是对方法的一种抽象,客户依赖的接口不变,但是接口方法的实现可以用一个或多个现成的类来辅助实现。