一、简单介绍
适配器模式比较简单,是对接口或者数据的一个转换。与之前介绍的代理模式和装饰器模式有些相似的地方。不同之处在于,适配器模式主要用来解决两个接口之间不匹配的问题,相当于一个转换层,控制粒度是接口,装饰者模式的目的是给对象添加功能,代理模式的作用是控制对某个对象的所有访问,粒度是对象。
二、使用场景
在开发时,可能有些功能已经开发完成,现在要兼容第三方的接口,但是第三方返回的数据格式与原接口不同,或者第三方接口需要的参数与之前我们写好的接口定义的参数不一致,这时我们就需要一个适配器用于转换参数/数据。
三、示例
假如我们原来有一个一维数组的数据,用它来处理一些逻辑。现在数据变成了树形结构,如果要改动页面的渲染方式及相关的逻辑,那么可能会比较麻烦。这时候我们写一个转换数据格式的方法,对新数据进行转换,就能用我们原来的页面和逻辑了(具体哦要不要修改逻辑和还是看项目情况,如果全部的数据格式都改成了新格式且时间充足,我建议还是修改页面和逻辑好一点,如果只是部分接口修改且时间不算充足,那么还是用适配器做兼容好一点)
//旧的数据格式
const oldData = [
{
nodeId: 1,
parentId: 0,
name: "1"
},
{
nodeId: 2,
parentId: 0,
name: "12"
},
{
nodeId: 3,
parentId: 1,
name: "123"
},
{
nodeId: 4,
parentId: 3,
name: "1234"
},
{
nodeId: 5,
parentId: 2,
name: "12345"
}
];
//新的数据格式
const newData = [
{
nodeId: 1,
parentId: 0,
name: "1",
children: [
{
nodeId: 3,
parentId: 1,
name: "123",
children: [
{
nodeId: 4,
parentId: 3,
name: "1234"
}
]
}
]
},
{
nodeId: 2,
parentId: 0,
name: "12",
children: [
{
nodeId: 5,
parentId: 2,
name: "12345"
}
]
}
];
function fn(data) {
/// do something
console.log(data);
}
function newFn(data) {
fn(adapter(data));
}
function adapter(data) {
//一般来说不要修改源数据
const cloneData = JSON.parse(JSON.stringify(data)).map(item => ({
...item,
children: []
}));
const dataMap = cloneData.reduce((res, item) => {
res[item.nodeId] = item;
return res;
}, {});
return cloneData.reduce((res, item) => {
if (dataMap[item.parentId]) {
dataMap[item.parentId].children.push(item);
} else {
res.push(item);
}
return res;
}, []);
}
现在,我们只需要在使用新数据格式的地方将fn替换成newFn就可以了