持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
适配器模式(Adapter): 将一个类(对象)的接口(方法或者属性)转化成另一个接口,以满足用户需求,使类(对象)之间接口的不兼容问题通过适配器得到解决。
适配器,在我们生活中也很常见,我们有时称为转换器,比如说有些电脑没有HDMI接口,想要连接HDMI口的显示器,就需要用到TypeC转HDMI适配器了。
适配器的主要任务是适配两种代码库中不兼容的代码。
异类框架适配器
比如说我们现在有两个框架,一个是我们自己写的A框架,一个是JQuery。
var A = A || {} // 定义A框架
// 通过ID获取元素
A.g = function (id) {
return document.getElementById(id)
}
// 为元素绑定事件
A.on = function (id, type, fn) {
// 若传递参数是字符串,则以id处理,否则以元素对象处理
var dom = typeof id === 'string' ? this.g(id) : id
// 标准DOM2级添加事件方式
if (dom.addEventListener) {
dom.addEventListener(type, fn, false)
}
// 兼容IE
else if (dom.attachEvent) {
dom.attachEvent('on' + type, fn)
}
// 简易添加事件
else {
dom[on + 'type'] = fn
}
}
假设我们现在有个需求,实现一个页面加载事件,加载完成后实现一个点击事件,通过上面的代码我们可以如下所示
// 窗口加载完成事件
A.on(window, 'load', function () {
// 按钮点击事件
A.on('mybtn', 'click', function () {
// code....
})
})
那么假如我们说A框架不再维护了,我们要改用JQuery,我们要怎么办呢?很明显,逐个逐个用JQuery去替换原来的A框架是不现实的,这个时候我们就可以在A框架和JQ之间加上一层适配器了。
我们只需要像下面这样去重写A框架中的代码即可:
A.g = function (id) {
return $(id).get(0) // 通过JQ获取JQ对象,然后返回第一个成员
}
A.on = function (id, type, fn) {
var dom = typeof id === 'string' ? $('#' + id) : $(id)
dom.on(type, fn)
}
这种重写的复杂度跟两个框架的相似程度有关,血缘相差越远的两个框架,适配器的复杂度越高,因此 尽量引入相似框架。
参数适配器
有时候一个方法会需要有很多个参数,比如下面这样
function M(p1, p2, p3, p4, p5, p6) {
}
我们要记住这些参数的顺序是很折磨人的,而且一般这种情况我们都会选择以 一个参数对象的形式 传入。
/**
* obj.p1:p1,
* obj.p2:p2,
* ...
* obj.p6:p6
*/
function M(obj) {
}
但是这样又带来一个问题,我们不知道传递的参数是否完整,一些参数可能是必传的,还有一些参数可能是有默认值的,像这种情况,就可以使用参数适配器了。
function M(obj) {
var _adapter = {
p1: '我是p1',
p2: 666,
p3: {},
p4: [],
p5: '我是p5',
p6: '我是老六'
}
for (const key in _adapter) {
// 进行参数适配
_adapter[key] = obj[key] || _adapter[key]
}
// 下面是代码逻辑
}
上面这种方式就是很多插件参数配置的方法。
数据适配器
上面参数适配器又衍生出来一种数据适配器,它的作用是 把一种格式的数据转换成另一种格式的数据。比如说下面的这个将数组转换成对象的适配器
const arr = ['JavaScript', 'book', '前端编程语言', '8月1日']
// 数据适配器
function arr2ObjAdapter(arr) {
return {
name: arr[0],
type: arr[1],
title: arr[2],
time: arr[3]
}
}
上面这种数据适配器使得我们的数据能够被更加灵活的使用
服务端数据适配
适配器最重要的一点,其实就是 解决了前后端的依赖,前端用的数据不再和后端传递来的数据紧密耦合,这样就算后端因为架构改变了导致传递的数据结构发生了变化,我们只需要写一个适配器即可。
本来我们是请求后端,然后直接使用后端返回来的数据,但是现在我们在中间加上一层数据适配器,让后端传递来的数据经过适配后再为前端所用,这样哪怕后端的数据结构改变了,我们也只需要更改适配器部分即可。