JavaScript 设计模式 : 生活中的'适配器'和'装饰者'模式

首先很抱歉近期公务繁忙没来得及更新...... 为了适应节奏,先先抛出两个我认为相对简单、经常使用的用来节省开发效率的模式,使用的场景也是不少的,相对没有什么难点,这里结合场景我总结了一下。(本章适合快速阅读)javascript


适配器模式

  • 组建与组件间的适配
  • 类与类之间的适配
  • 方法与方法间的适配
  • 数据结构和数据结构之间的适配

举个栗子:

usb目前已经不知足咱们主流手机的快充功能了,须要用到type-c接口,咱们确定不会把线剪短换上一个type-c的头的,咱们彻底能够经过买一个usb转type-c的转接头来解决咱们这个问题。 再多的例子就不讲了:)前端

underscore适配器

假设,注意是假设,公司有一个框架NB.js,他的语法以及实现形式基本和underscore.js类似,例如each操做:java

//NB.js
NB.each([1,2,3],function(key,value){
    console.log(this.location.href + '?'+value)
},window)
复制代码
//underscore.js
_.each([1,2,3],function(value,key){
    console.log(this.location.href + '?'+value)
},window)
复制代码

两个框架的key,value顺序是不同的。 公司新招了一批同事,他们用过underscore.js可是彻底没据说过NB.js,公司时间紧任务重,领导决定,先让公司同事使用underscore的方式使用内部的框架,逐步完善NB.js文档。ajax

这个任务交给你,但总不能对NB.js进行大量的修改,就像上面转接头的问题,咱们换一个转接头就行了:后端

window.NB = NB = _ ; //underscore转NB适配器。
复制代码

参数适配器

function doSomeThing(name,id,color,height,width){
    
}
doSomeThing('input1','99899','red','200','200')
复制代码

这样的一个函数有多个固定顺序的参数,咱们知道显然是不友好的,咱们写函数的时候必定要避免这样的问题,这样会显得很low,首先就要想到适配设计模式

function doSomeThing(obj){
    var adapter = {
        name:'name',
        id:'001',
        color:'yellow',
        height:'100',
        width:'100'
    };
    for(var i in adapter){
        adapter[i] = obj[i] || adapter[i];
    }
    console.log(adapter);
}

var obj = {color:'red'}
doSomeThing(obj)
//object {name: "name", id: "001", color: "red", height: "100", width: "100"}
复制代码

上面的问题其实不少同窗早就知道了,还有一种状况就是,先后分离的开发过程当中,后台人员习惯返回的格式跟全端人员预期的不同,咱们也能够进行适配。bash

// 后端返回Object,前端须要Array

$.ajax({
    url:xxx.action,
    success:function(data){
        doSomeThing(dataAdapter(data));
    }
})

function dataAdapter(obj){
    return [obj['name],obj['id'],obj['color'],obj['height'],obj['width']]; } 复制代码

像这样,后端有任何变化咱们只须要修改dataAdapter函数就好,其余的通途你们自行脑补:), 其实各类设计模式的宗旨都是低耦合,易维护数据结构

装饰模式

在原型不变的基础是,经过对他进行包装,附加属性,附加方法,使原有的对象、函数能知足更复杂的需求。由于已经说了装饰,因此只是添加新功能时候能够用。框架

举个最简单的例子: 系统中有 一些 按钮,目前每一个按钮点击后弹出你好,如今须要在弹出你好过5秒以后在弹出再见更具体的你们本身脑补,很常见的需求。 有的人开始立刻动手写了:dom

<button id="A"></button>
//原来的
 var A = document.getElementById('A');
    A.onclick = function(){
        alert(1)
    };
//修改后的
 var A = document.getElementById('A');
    A.onclick = function(){
        alert(1);
        setTimeout(function(){
            alert(2)
        },5000)
    };
    
复制代码

当你沾沾自喜时,你发现还有99个按钮要改......当你真的完成了这个难以想象的任务后,你发现需求变了......好那咱们仍是尽快使用装饰者模式吧:

var A = document.getElementById('A');
    A.onclick = function(){
        alert(1)
    }
    //装饰者
    var decorator = function (id,fn){
        var dom = document.getElementById(id);
        if(typeof dom.onclick === 'function'){
            var oldClickFn = dom.onclick;
            dom.onclick = function(){
                oldClickFn();
                fn();
            }
        }else{
            dom.onclick = fn;
        }
    }
    //利用装饰者对元素增长事件。
    decorator('A',function(){
        setTimeout(function(){
            alert(2)
        },5000)
    })
    
复制代码

这样需求改了也不怕了,咱们只要修改decorator函数就行了。 固然随手写的也有缺点,咱们的参数仍是按照顺序来排列的,同窗们能够参考上面讲的适配器模式,方便之后维护增长代码!decorator是全局的,有兴趣能够参考javascript命名空间问题,总之,代码是越写越优雅的。

适配器和装饰器的不一样之处

  • 适配器的方法是对原有对象进行适配,添加的方法与原有方法功能大体类似,只是换了一种更加便利与咱们开发的形式,可是装饰者提供的方法是有区别的,通常都是比以前的更加丰满,弥补以前的不足之处。
  • 装饰者模式中能够不了解原有功能,而且原有的方法照样能够原封不动的使用,若是原有的方法不能用了,说明你的模式有问题,是不可取的。

PS:

最近私事比较多,设计模式的文章之后的更新频率是一周一章,比较复杂的单独一章,比较简单或关联较大的两章并一章,本章5分钟阅读流水帐,但愿你们共同努力。


相关文章
相关标签/搜索