适配器模式

2019-06-07  本文已影响0人  helloyoucan

适配器模式:将一个类(对象)的接口(方法或者属性)转化成另外一个接口,以满足用户使用,使类(对象)之间的不兼容问题通过适配器得以解决。

需求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 中适配器的应用,更多应用在对象之间,为使对象可用,用处会对对象拆分并重新包装,当然这也需要了解对象的内部结构,但是适配器模式接口了对象之间的耦合度。包装的适配器代码增加了一些资源开销,但微乎其微。

上一篇下一篇

猜你喜欢

热点阅读