适配器模式
前言
适配器模式是设计模式中相对简单的一种,它是将原本不同的内层接口通过改装实现统一对外可以实现适配。生活中很多这样的实例,比如usb转接头、万能插座等。
案例
假设我们有使用百度地图系统,但这部分的api不归我们控制,也不允许我们改动,但我们需要进行一次封装来实现对应的功能。
const BaiduMap ={
show:function(){
console.log('百度地图')
}
}
const BaiduMapAdapter = function(){
show:function(){
return BaiduMap.show();
}
}
复制代码
除了这样的例子之外,我们还有案例是基于一些参数的改造的,在装饰者模式中我们讲过可以对参数进行一些改造再返回给对象或者类,而适配器模式本身就是可以做参数的改造,这样一个过程。
比如,非常常见的,后端返回前端的数据,原来的列表格式是{name:'张三',id:1},但是ui控件的要求是希望我们传递的数据对象的字段是{label:'张三',value:1}.很多同学可能不会觉得这个参数改造有多麻烦,但实际上我们缺乏的是设计思想,是把这个参数改造的代码段变成一个可重用的具有设计思想的方法。说的更直白的话,就是这段更改赋值的方法根本不能复用,下次换其他具体的字段,还要写很多类似的方法。
let userList = [{name:'张三',id:1}];
//old codes
//vue methods
changeUserList(userList){
this.userList = userList.reduce((arr,item)=> {
arr.push({
label:item.name,
value:item.id
})
},[])
}
// new codes ,基于需要改造为label/value的组件,提供一个参数改造的工具方法
/**
@param arr 需要改造的数组
@param itemOldKey :[label,value] ,需要改造为label、value的对应的原值
*/
const compParamAdapter = (arr,itemOldKey) => {
if(!Array.isArray(arr) ||!arr.length || !Array.isArray(itemOldKey)) return ;
return arr.reduce((arr,item)=>{
arr.push({
key:itemOldKey[0] ? item[itemOldKey[0]] :item.label,
value:itemOldKey[1] ? item[itemOldKey[1]] :item.value,
})
})
}
// 任何需要类似的改造的使用场景的时候,直接使用适配器适配的结果
//vue methods
changeUserList(userList){
this.userList = compParamAdapter(userList,['name','id'])
}
复制代码
对比
因为到这里,其实已经分享过了较多的设计模式了,相信大家对外观模式、装饰者模式和适配器模式有一定疑惑,因为看代码没什么差别,都是进行一次封装。这里说几点重要的区别。
- 适配器模式主要是用来解决两个接口不匹配的问题,或者也可以扩大为数据不匹配或者不完整的问题,适配器不需要修改原来的接口或者数据,只是依照原来的接口或者数据进行改造,让其符合要求。
- 装饰者模式是为了给对象增加属性或者功能或者改造参数,可能会形成一个长的装饰链,并且需要提供被装饰的对象,而适配器模式不需要知道最终的使用者,再顺便说下代理模式,是为了解决不暴露原对象的其他属性而出发的。
- 外观模式,外观模式是和适配器模式看似差别最小的,两者的最主要的差别是,是否是新写一个接口,还是改造一下还是用原来的第三方数据或者接口。
不管怎么说,其实用哪种设计模式,不用过于计较概念,希望大家工作中更重要的是基于这些设计模式的思想解决实际的问题,以能解决问题为准,具体你解决后的这段代码属于什么设计模式的范畴可能不是那么重要。