概念

适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一个接口

适配器模式通过引入一个适配器对象来实现这一点


在适配器模式中,通常存在三个核心角色:目标接口(Target)、适配器(Adapter)和被适配者(Adaptee)

目标接口定义了客户端所期望的接口,适配器类实现了目标接口,并在内部持有一个被适配者对象,通过调用被适配者对象的方法来实现目标接口的方法


适配器模式的核心思想是将一个类的接口转换成另一个接口,使得原本由于接口不兼容而无法一起工作的类可以协同工作

这种模式的优点在于,可以使得原本不兼容的类能够协同工作,同时也可以使得客户端代码与具体实现类解耦,提高系统的灵活性和可维护性


适配器模式适用于以下情况:

  1. 需要将一个类的接口转换成另一个客户端所期望的接口
  2. 需要复用一些现有的类,但是其接口与系统要求的不兼容


举个简单的例子,考虑一个英文翻译系统

系统中有一个英文翻译器类,但是客户端需要使用一个中文翻译器

这时可以引入一个适配器类,将中文翻译器的接口适配成英文翻译器的接口,使得客户端能够通过适配器类来调用中文翻译器的方法,从而实现了英文翻译系统和中文翻译器的协同工作


实现条件

  • 存在至少两个不兼容的接口

    一个是客户端期望的接口,另一个是已经存在的接口

  • 不想或不能修改现有的代码

    可能是因为你不拥有那部分代码的源代码,或者任何修改都会涉及大量的依赖和复杂性


优点

  • 接口兼容性

    使原本由于接口不兼容而不能一起工作的类可以一起工作

  • 代码解耦

    可以将程序的业务逻辑和具体实现解耦,提高代码的可用性

  • 灵活性和扩展性

    适配器模式提高了现有代码的灵活性和扩展性,特别是在开发过程中需要引入新的类或组件时


缺点

  • 代码复杂性

    在某些情况下,引入适配器会使系统的代码更加复杂

  • 过多使用

    过多地使用适配器可能会让系统变得零碎和难以理解


实现方式

已存在的旧接口

1
2
3
4
5
6
7
8
9
// 旧的数据库接口
class OldDatabase {
constructor() {
this.operate = function() {
// 旧的数据库操作
console.log('Operation on old database');
};
}
}

新增加的接口

1
2
3
4
5
6
7
8
9
// 新的数据库接口
class NewDatabase {
constructor() {
this.request = function() {
// 新的数据库操作
console.log('Operation on new database');
};
}
}

基本的适配器

1
2
3
4
5
6
7
8
9
10
// 适配器
class DatabaseAdapter {
constructor(newDatabase) {
this.database = newDatabase;
}

operate() {
this.database.request();
}
}

怎么使用

1
2
3
4
5
6
7
8
// 使用旧的数据库接口
const oldDB = new OldDatabase();
oldDB.operate(); // 输出: Operation on old database

// 使用适配器与新的数据库接口
const newDB = new NewDatabase();
const adaptedDB = new DatabaseAdapter(newDB);
adaptedDB.operate(); // 输出: Operation on new database

DatabaseAdapter 类充当适配器

NewDatabase 类的 request 方法适配为 OldDatabase 类的 operate 方法

这样,即使客户端代码期望使用 operate 方法,也可以无缝地切换到使用新的数据库接口


场景

  • 数据库适配器

    许多数据库库(如 Sequelize 或 TypeORM)提供了统一的接口来连接不同的数据库系统

  • 服务器端适配器

    Express 或 Koa 中间件经常用于将不同的服务或框架接口适配为统一的中间件接口

  • 前端框架与第三方库

    Vue.js、React 或 Angular等前端框架经常使用适配器模式来整合第三方库(如路由、状态管理库等)

  • API适配器

    当你的应用程序需要与第三方服务通信时,你可能会写一个适配器来适配第三方API的接口


源代码