聽飛狐聊JavaScript設計模式系列10

本回內容介紹

上一回,聊了代理模式,虛擬代理,圖片懶加載,介一回,也比較容易,適配器模式(Adapter),用一個新的接口對現有類的接口進行包裝,處理類與API的不匹配。使用這種模式的對象又叫作包裝器(wrapper)。先看個簡單的例子,先理解再深刻,走你:javascript

1.適配器模式

先定義一個接口(接收3個參數),再定義一個對象,如何銜接兩者呢,以下:html

// 定義一個接口方法,傳3個參數
function interfaceMethod(a1,a2,a3){
    // 隨便寫個彈出框
    alert(a1+a2+a3+'');
}
    
// 定義一個對象
var o = {
    s1:'飛狐就是帥',
    s2:',擼壕,',
    s3:'大衛'
}
    
// 適配器函數,把傳遞的對象參數轉換爲interfaceMethod函數須要的形式
function adapter(o){
    interfaceMethod(o.s1,o.s2,o.s3);
}
adapter(o);    //飛狐就是帥,擼壕,大衛

這是模擬JS設計模式書上例子,適配器的做用主要是對現有的接口進行包裝,從而實現現有的接口和不兼容的類進行匹配。
這裏不少盆友會疑惑適配器模式與門面模式的區別:
1,門面模式是爲了簡化一個接口,並不提供額外的選擇;
2,適配器則要把一個接口轉換爲另外一個接口,並不會濾除某些能力,也不會簡化接口;
網上最多的一個例子,就是適配不一樣的庫,以下:java

2. 適配不一樣庫

Prototype庫的$函數到YUI的get方法的轉換,網上最多的一個適配器模式的講解,看例子:web

<div id="fox1">飛狐</div><br/>
<div id="fox2">帥狐</div><br/>    
<div id="fox3">主要看氣質</div>
// 模擬Prototype,根據id獲取DOM元素,不須要傳遞任何的形參,一個id寫一個參數,多個id多個參數
function $(){
    // 定義一個結果數組
    var elements = [];
    // 遍歷傳入參數
    for(var i=0;i<arguments.length;i++){
        var element = arguments[i];
        // 判斷是否爲字符串
        if(typeof element =='string'){
            element = document.getElementById(element);
        }
        // 判斷長度,若是是一個,則返回一個
        if(arguments.length==1) return element;
        // 不然加入數組
        elements.push(element);
    }
    // 返回數組
    return elements;
}

// 模擬雅虎
var YAHOO = {};
// YUI中get只接受一個參數,字符串或數組
YAHOO.get = function(el){
    // 判斷是否爲字符串
    if(typeof el == 'string'){
        return document.getElementById(el);
    };
    // 判斷是否爲數組
    if(el instanceof Array){
        var elements = [] ;
        for(var i=0;i<el.length;i++){
            elements[elements.length] = YAHOO.get(el[i]);
        }
        return elements;
    }
    // 若是都不是,直接返回
    if(el){
        return el;
    }
    // 不然返回null
    return null;
}
    
// YUI適配器
YAHOO.get = YUIToPrototypeAdapter;
// 適配器函數
function YUIToPrototypeAdapter(){
    // 對於YUI開發人員來講 永遠傳遞一個參數
    if(arguments.length == 1){
        var el = arguments[0];
        // 這裏判斷是否爲數組,若是是直接返回,不然包裝成數組返回,如:"a",包裝後["a"]
        return $.apply(window,el instanceof Array?el:[el]);
     } else {
         // 若是是多個參數的狀況,這裏只能用apply,不能用call
         return $.apply(window,arguments);
     }
}

// 測試數組的狀況
var arr = YAHOO.get(['fox1','fox2','fox3']);
alert(arr);
// 測試多個參數的狀況
var arr = YAHOO.get('fox1','fox2','fox3');
alert(arr);

這個例子在網上太多了,隨便找了一個來改,目的在於模擬不一樣庫直接的匹配,靈活的轉換,解決與現有API提供的接口不兼容的衝突。設計模式

裝逼圖
裝逼時刻了,老片新看,推薦《重慶森林》,文藝範兒的調調~~數組

這一回聊適配器模式,就倆例子,內容很少,主要是理解。
下面的內容來一個圖片預加載,跟上一回的懶加載湊一對兄弟篇。app

JS圖片預加載

圖片預加載是web開發中一種應用至關普遍的技術,好比圖片翻轉顯示等特效的時候,爲了讓圖片在轉換的時候不出現等待,先讓圖片下載到本地,再繼續執行後續的操做:函數

//要加載的圖片地址,這裏能夠隨便在網上搜點兒圖片測試
var imgs=[
    "xxx.jpg",
    "yyy.jpg",
    "zzz.jpg"
    ];
    
var preload=function(imgs,callback){
    // 判斷傳入的imgs是否爲數組(typeof操做符檢測數組的時候也是object),若不是數組則用[imgs]轉爲數組
    var imgs=(typeof imgs!="object")? [imgs] : imgs;
    // 定義一個圖片數組
    var img = [];
    for(var i=0,len=imgs.length;i<len;i++){
        // 爲每個圖片對象賦值圖片地址
        img[i] = new Image();
        img[i].src = imgs[i];
    }
    
    // 三目運算沒什麼好說的,len-1表示最後一個圖片對象,加載完成執行回調函數,apply還記得吧,使做用域指向img
    img[len-1].onload = callback?callback.apply(img):null;
}
    
// 測試
window.onload=function(){
    preload(imgs,function(){
        var _self = this;
        _self.forEach(function(item){
            alert(item.src);
        })
    });
}

這裏只是簡單的模擬,代碼量少,應該能夠很容易看懂,預加載減去了等待時間提升用戶體驗,不少web應用中普遍運用。測試

這一回,主要聊了適配器模式,圖片預加載,主要仍是理解~~
下一回,聊一聊橋接模式,順便作一作計算題。this

客觀看完點個贊,推薦推薦唄,嘿嘿~~


注:此係飛狐原創,轉載請註明出處

相關文章
相關標籤/搜索