设计模式之适配器模式
1. 定义
将一个类的接口转换成客户端所期望的另一个接口
2. 口语化举例
适配器,生活中常见的适配器典型如手机充电器,其实它的正式名字应是“电源适配器”
充电器的作用,就是将生活电(220V交流电)转换为手机所接受的直流电(常规为5V,2A)
所以,电源适配器,就是将生活电与直流电适配,使手机能使用220V交流电
进一步地,适配器,就是将两者不能直接相互作用的对象,进行转换适配
(下面的描述会沿用这个上述这个场景)
3. 源码示例
AntV L7 是一个空间数据可视化 JS 库,空间数据,必然设计各种底图,目前常见的地图底图有高德地图、百度地图、天地图、Mapbox 等
每一家地图或多或少都不一样,如何将各家地图接入到 L7 中,就必然需要做适配工作
浏览 L7 的地图源码部分:L7/packages/maps/src at master · antvis/L7 (github.com)
可以看到 L7 基本每个地图都做了一个适配器
flowchart LR
BaiduMap --> Map
GaodeMap --> Map
MapLibre --> Map
Mapbox --> Map
TencentMap --> Map
例如高德地图AMap的部分源码:
import { IAMapInstance } from '../../typings/index';
import BaseMapWrapper from '../utils/BaseMapWrapper';
import AMapService from './map';
export default class AMapWrapper extends BaseMapWrapper<AMap.Map & IAMapInstance> {
protected getServiceConstructor() {
return AMapService;
}
}
而AMapService
就是配置高德地图使之转换为通用的Map
对象
这样设计的好处是,后续新添加一个地图服务时,只需要新增一个地图与地图适配器即可,当某个地图服务变更时,也只需要修改适配器即可
4. 总结
4.1 设计原则
-
单一职责原则
充电器(电源适配器)只负责转换电流,生活电依旧还是220V,手机依旧还是使用直流电
-
开闭原则
假如以后手机不使用原来的5V、2A直流电了,换个充电器就行
4.2 适用场景
-
使用某个类、模块或者函数时,其接口与原有代码不兼容
创建一个中间层类,其可作为代码与遗留 类、第三方类或提供怪异接口的类之间的转换器