美文网首页
适配器模式

适配器模式

作者: helloyoucan | 来源:发表于2019-06-07 18:00 被阅读0次

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

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

    相关文章

      网友评论

          本文标题:适配器模式

          本文链接:https://www.haomeiwen.com/subject/peqvxctx.html