适配器模式:将一个类(对象)的接口(方法或者属性)转化成另外一个接口,以满足用户使用,使类(对象)之间的不兼容问题通过适配器得以解决。
需求1:作品的活动页面使用的是公司内部的A框架,但是新来的同事不熟悉A框架,而且A框架能使用的方法有限,想要引入jQuery,但这样以前功能所写的代码要重新写一遍。
A(function(){
A('button').on('click',(e)=>{
//......
})
})
解决办法:A框架与jQuery比较相似,可以简单写个适配器,也就是为两个代码库所写的代码兼容运行而书写的额外代码,这样就不用重写以前的功能代码了
适配器的热媒是适配两种代码库中不兼容的代码
window.A = A = jQuery
如果两个框架不相似,那么对于这种异类框架适配情况就比较复杂,e.g.
定义框架
let A = A||{}
//通过ID获取元素
A.g = function(id){
return document.getElementById(id)
}
//为元素绑定事件
A.on = function(id,type,fn){
//如果传递参数是字符串则以id处理,否则以元素对象处理
const dom = typeof id === 'string'?this.g(id):id
//标准DOM2级添加事件
if(dom.addEventListener){
dom.addEventListener(type,fn,false)
}
//IE DOM2级添加事件方式
else if(dom.attachEvent){
dom.attachEvent('on'+type,fn)
}
//简易添加事件方式
else{
dom['on'+type] = fu
}
}
//完成上面的需求可以这样写
A.on(window,'load',function(){
//按钮点击事件
A.on('mybutton','click',function(){
//do some
})
})
适配器
A.g = function(id){
//通过jQuery获取jQuery对象,然后返回第一个成员
return $(id).get(0)
}
A.on = function(id,type,fn){
//如果传递参数是字符串则以id处理,否则以元素对象处理
const dom = typeof id === 'string'?$('#'+id):$(id)
dom.on(type,fn)
}
扩展1:参数适配器
e.g.
某个方式需要传递多个参数
function doSomeThing(name,title,age,color,size,prize){}
可以改为用对象传递
/**
* object.name
* object.title
* object.age
* object.color
* object.size
* object.prize
***/
function doSomeThing(obj){}
/*
* 问题1:调用该函数时,无法知道传递的参数是否完整,一些必传参数没有传入、一些参数有默认值等
* 优化1:使用适配器来适配传入的这个参数对象
*/
function doSomeThing(ojb){
const _adapter = {
name:'小白',
title:'设计模式',
age:22,
color:'red',
size:100,
prize:50,
}
for(const i in _adapter){
_adapter[i] = obj[i]||_adapter[i]
}
//或者 extend(_adapter,obj) 注意:此时可能会多添加属性
// do some things
}
扩展2:数据适配
e.g.
const arr = ['javascript','book','前端语言','4月10日']
问题:数组中每个成员代表的意义不同,这样的数据结构语义不好
优化:将其适配成对象形式
const obj = {
name:'',
type:'',
title:'',
time:''
}
//按照下面那样适配
function arrToObjAdapter(arr) {
return {
name:arr[0],
type:arr[1],
title:arr[2],
time:arr[3],
}
}
var adaperData = arrToObjAdapter(arr)
console.log(adaperData)//{name:'javascript',type:'book',title:'前端语言',time:'4月10日'}
扩展3:服务端数据适配
解决前后端的数据依赖,前端不再未后端的数据所束缚。
当后端因为架构改变导致传递的数据结构发生变化,写个适配器就可以,将传递过来的数据适配成可用的数据再使用。
为简化模型,这里使用jQuery的ajax方法理想数据是一个二维数组
//处理数据并返回新数据
return [data['key1'],data['key2'],data['key3']
}
$.ajax({
url:'some address',
success(data,status){
if(data){
//使用适配后的数据————返回的对象
doSomeThing(ajaxAdapter(data))
}
}
})
当后端数据有变化时,只需要相应地改变ajaxAdapter适配器转换格式即可
javascript 中适配器的应用,更多应用在对象之间,为使对象可用,用处会对对象拆分并重新包装,当然这也需要了解对象的内部结构,但是适配器模式接口了对象之间的耦合度。包装的适配器代码增加了一些资源开销,但微乎其微。
网友评论