JavaScript設計模式——代理模式

  • 2019 年 10 月 21 日
  • 筆記

  代理模式屬於設計模式中結構型的設計模式;

  定義:

  顧名思義就是為一個對象提供一個代用品或佔位符,以便控制對它的訪問!

  白話解釋:

    很多明星都是有經紀人的,如果要聯繫明顯進行商演或者開演唱會之類的商業活動通過是需要先跟經紀人取得聯繫的,跟經紀人談好了合作事宜之後經紀人再轉達給某明星,然後某明星才會去參加活動;同樣租房也是一個同樣的道理,我們不管是租房還是買房,第一反應肯定是找鏈家這類的平台,因為我們只需要跟鏈家進行溝通,而鏈家去跟房東溝通,省去了我們直接和房東溝通的步驟;因為鏈家就是一個代理模式,它代理了這個房東的房源;

  舉個例子:

    你作為一個追星狂魔,是某明星的忠誠粉絲;剛好某明星近期要過生日了,你準備送上禮物代表你的心意,正常的流程:

    var Fans = {          flower(){              star.reception("花");          }      }        var star = {          reception:function(gift){              console.log("收到粉絲的:"+gift);          }      }        Fans.flower();   //收到粉絲的:花

  你選擇了買花寄給她,希望她能感受到你的心意;但是往往理想很豐滿,現實很骨感!別忘了還有經紀人,因為簽收你的禮物的往往不是明星本人而是經紀人:

    var Fans = {          flower(){              Agent.reception("花");          }      }        var Agent = {          reception:function(gift){              console.log("粉絲送的:"+gift);   //粉絲送的:花              star.reception("花");          }      }      var star = {          reception:function(gift){              console.log("收到粉絲的:"+gift);          }      }        Fans.flower();    //收到粉絲的:花

  這裡的經紀人就是一個簡單的代理了,粉絲需要先把禮物給經紀人,經紀人再轉給明星本人;

  保護代理:

    明星滿心歡喜的看到粉絲寄過來的包裹的時候,拆開一看,原來是花!明星很不屑,所以告訴經紀人,以後凡是給我寄花的,通通不要給我了,你自己看著處理:

  

    var Fans = {          flower(){              Agent.reception("花");          }      }        var Agent = {          reception:function(gift){              console.log("粉絲送的:"+gift);  //粉絲送的:花              if(gift != "花"){                  star.reception("花");              }            }      }      var star = {          reception:function(gift){              console.log("收到粉絲的:"+gift);          }      }        Fans.flower();

  上面的程式中明星根本就沒有收到粉絲寄過來的花,因為在經紀人那裡就已經攔截處理了;通過經紀人來過濾掉一部分禮物,這種模式叫做保護代理;

  

  虛擬代理:

    粉絲送花明星收不到,那粉絲就轉換一下思路,送點錢自己去買想要的東西吧!於是找到經紀人,給了經紀人一百萬現金,讓經紀人轉達給明星本人;

 

    function Money(){          this.total = "一百萬現金"         return this.total;      }      var Fans = {          flower(){              Agent.reception();          }      }        var Agent = {          reception:function(){              // console.log("粉絲送的:"+gift);              let money = new Money();              star.reception(money.total);            }      }      var star = {          reception:function(gift){              console.log("收到粉絲的:"+gift);  //收到粉絲的:一百萬現金          }      }        Fans.flower();

  明星收到了一百萬就很開心;這一百萬因為不是花,沒有被經紀人攔截過濾;所以明星本人就直接收到了,這種模式我們稱為虛擬代理模式;

 

  虛擬代理實現圖片懶載入:

   沒用代理的時候我們的程式碼是這樣的:

// 創建一個本體對象  var myImage = (function(){    // 創建標籤    var imgNode = document.createElement( 'img' );    // 添加到頁面    document.body.appendChild( imgNode );    return {      // 設置圖片的src      setSrc: function( src ){        // 更改src        imgNode.src = src;      }    }  })();    myImage.setSrc( 'http:// image.qq.com/music/photo/k/000GGDys0yA0Nk.jpg' );

 

   虛擬代理:

// 創建一個本體對象  var myImage = (function(){    // 創建標籤    var imgNode = document.createElement( 'img' );    // 添加到頁面    document.body.appendChild( imgNode );    return {      // 設置圖片的src      setSrc: function( src ){        // 更改src        imgNode.src = src;      }    }  })();    // 創建代理對象  var proxyImage = (function(){    // 創建一個新的img標籤    var img = new Image;    // img 載入完成事件    img.onload = function(){      // 調用 myImage 替換src方法      myImage.setSrc( this.src );    }    return {      // 代理設置地址      setSrc: function( src ){        // 預載入 loading        myImage.setSrc( 'file:// /C:/Users/svenzeng/Desktop/loading.gif' );        // 賦值正常圖片地址        img.src = src;      }    }  })();    proxyImage.setSrc( 'http:// image.qq.com/music/photo/k/000GGDys0yA0Nk.jpg' );

  上面這段程式碼運用代理模式來實現圖片預載入,可以看到通過代理模式巧妙地將創建圖片與預載入邏輯分離,並且在未來如果不需要預載入,只要改成請求本體代替請求代理對象就行。