模式定义:适配器模式是一种结构型设计模式,它允许不兼容的接口之间能够协同工作;适配器充当两个不兼容接口之间的桥梁,将一个类的接口转换成客户期望的另一个接口;
模式特点:
- 接口转换:将一个接口转换成另一个接口;
- 解耦:使原本不兼容的类可以一起工作;
- 透明性:对客户端隐藏了转换细节;
模式类型,适配器模式有两种实现方式:
- 类适配器:通过多重继承实现(TypeScript/JavaScript不支持多重继承,但可以通过混入实现)
- 对象适配器:通过组合实现(更常用)
类图
代码
// 需要适配的类
class Power {
charge() {
return '220V';
}
}
// 适配器
class Adapter {
constructor() {
this.power = new Power();
}
charge() {
let power = this.power.charge();
return `${power} => 12V`;
}
}
// 客户端
class Client {
constructor() {
this.adapter = new Adapter();
}
use() {
console.log(this.adapter.charge());
}
}
new Client().use();
// 220V => 12V
经典场景
适配第三方库的版本差异
// 统一的图表接口
interface Chart {
render(data: any[], container: HTMLElement): void;
update(data: any[]): void;
}
// v1版本的图表库
class ChartV1 {
constructor(private type: string) {}
draw(data: any[], element: HTMLElement) {
console.log(`使用v1绘制${this.type}图表`, data, element);
}
refresh(data: any[]) {
console.log(`刷新v1的${this.type}图表`, data);
}
}
// v2版本的图表库
class ChartV2 {
constructor(private chartType: string) {}
display(dataPoints: any[], target: HTMLElement) {
console.log(`使用v2显示${this.chartType}图表`, dataPoints, target);
}
modify(dataPoints: any[]) {
console.log(`修改v2的${this.chartType}图表`, dataPoints);
}
}
// v1适配器
class ChartV1Adapter implements Chart {
private chart: ChartV1;
constructor(type: string) {
this.chart = new ChartV1(type);
}
render(data: any[], container: HTMLElement): void {
this.chart.draw(data, container);
}
update(data: any[]): void {
this.chart.refresh(data);
}
}
// v2适配器
class ChartV2Adapter implements Chart {
private chart: ChartV2;
constructor(type: string) {
this.chart = new ChartV2(type);
}
render(data: any[], container: HTMLElement): void {
this.chart.display(data, container);
}
update(data: any[]): void {
this.chart.modify(data);
}
}
// 使用示例
function createChart(version: 'v1' | 'v2', type: string): Chart {
switch (version) {
case 'v1':
return new ChartV1Adapter(type);
case 'v2':
return new ChartV2Adapter(type);
default:
throw new Error('不支持的版本');
}
}
const container = document.createElement('div');
const data = [10, 20, 30];
// 使用v1版本的图表
const v1Chart = createChart('v1', 'bar');
v1Chart.render(data, container);
v1Chart.update([...data, 40]);
// 使用v2版本的图表
const v2Chart = createChart('v2', 'pie');
v2Chart.render(data, container);
v2Chart.update([...data, 50]);
单例模式
上一篇