《JavaScript設計模式與開發實踐》模式篇(3)—— 代理模式

代理模式是爲一個對象提供一個代用品或佔位符,以便控制對它的訪問設計模式

故事背景:

假設當 A 在心情好的時候收到花,小明表白成功的概率有 60%,而當 A 在心情差的時候收到花,小明表白的成功率無限趨近於 0。 小明跟 A 剛剛認識兩天,還沒法辨別 A 何時心情好。若是不合時宜地把花送給 A,花 被直接扔掉的可能性很大,這束花但是小明吃了 7 天泡麪換來的。 可是 A 的朋友 B 卻很瞭解 A,因此小明只管把花交給 B,B 會監聽 A 的心情變化,而後選 擇 A 心情好的時候把花轉交給 Abash

代碼實現:

var Flower = function(){};
var xiaoming = {
    sendFlower: function( target){
        var flower = new Flower();
        target.receiveFlower( flower ); 
    }
};
var B = {
    receiveFlower: function( flower ){
        A.listenGoodMood(function(){ 
            var flower = new Flower(); 
            A.receiveFlower( flower );
        }); 
    }
};
var A = {
    receiveFlower: function( flower ){
        // 監聽 A 的好心情
        console.log( '收到花 ' + flower ); 
    },
    listenGoodMood: function( fn ){
        setTimeout(function(){ // 假設 10 秒以後 A 的心情變好
            fn(); 
        }, 10000 );
    } 
};
xiaoming.sendFlower( B );
複製代碼

由上面的例子能夠引出兩種代理模式服務器

  • 保護代理 代理 B 能夠幫助 A 過濾掉一些請求,好比送花的人中年齡太大的或者沒有寶馬的,這種請求就能夠直接在代理 B 處被拒絕掉
  • 虛擬代理 假設現實中的花價格不菲,致使在程序世界裏,new Flower 也是一個代價昂貴的操做, 那麼咱們能夠把 new Flower 的操做交給代理 B 去執行,代理 B 會選擇在 A 心情好時再執行 new Flower

應用場景

  • 虛擬代理實現圖片預加載
var myImage = (function(){
    var imgNode = document.createElement( 'img' );     
    document.body.appendChild( imgNode );
    return {
        setSrc: function( src ){
             imgNode.src = src; 
        }
    } 
})();
var proxyImage = (function(){ 
    var img = new Image; 
    img.onload = function(){
        myImage.setSrc( this.src ); 
    }
    return {
        setSrc: function( src ){
             myImage.setSrc( 'file:// /C:/Users/svenzeng/Desktop/loading.gif' );
             img.src = src;  
        }
    } 
})();
proxyImage.setSrc('http://imgcache.qq.com/music/photo/k/000GGDys0yA0Nk.jpg' );
複製代碼
  • 虛擬代理合並HTTP請求 假設咱們在作一個文件同步的功能,當咱們選中一個 checkbox 的時候,它對應的文件就會被同 步到另一臺備用服務器上面。當一次選中過多時,會產生頻繁的網絡請求。將帶來很大的開銷。能夠經過一個代理函數 proxySynchronousFile 來收集一段時間以內的請求, 最後一次性發送給服務器
var synchronousFile = function( id ){ 
    console.log( '開始同步文件,id 爲: ' + id );
};
var proxySynchronousFile = (function(){
    var cache = [], // 保存一段時間內須要同步的 ID
    timer; // 定時器
    return function( id ){
        cache.push( id );
            if ( timer ){ // 保證不會覆蓋已經啓動的定時器
                 return; 
            }
        timer = setTimeout(function(){ 
            synchronousFile( cache.join( ',' ) ); 
            clearTimeout( timer ); // 清空定時器 
            timer = null;
            cache.length = 0; // 清空 ID 集合
        }, 2000 ); 
    }// 2 秒後向本體發送須要同步的 ID 集合
})();

var checkbox = document.getElementsByTagName( 'input' );
   for ( var i = 0, c; c = checkbox[ i++ ]; ){
      c.onclick = function(){
      if ( this.checked === true ){
          proxySynchronousFile( this.id ); }
      }
};
複製代碼

系列文章:

《JavaScript設計模式與開發實踐》最全知識點彙總大全網絡

相關文章
相關標籤/搜索