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分鐘閱讀流水帳,但願你們共同努力。


相關文章
相關標籤/搜索