Javascript設計模式(五)代理模式

使用者無權訪問目標對象,經過代理作受權和控制

代理模式是一種很是有意義的模式。在生活中也能找到代理模式的情景,好比,明星都有經紀人做爲代理,若是想請明星來辦一場商業演出,只能聯繫他的經紀人,經紀人會把商業演出的細節和報酬都談好以後,再將合同交給明星籤。前端

代理實現圖片懶加載

在前端開發中,圖片懶加載是一項很是實用的技術。爲了性能優化,咱們經常在圖片加載以前用一張圖片佔位,等圖片加載完成以後再將圖片填充到src上,這種場景就很容易實用代理模式。web

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(img.src)
    }
    return {
        setSrc: function(src) {
            myImage.setSrc('./loading.gif')
            img.src = src
        }
    }
})()

proxyImage.setSrc('https://user-gold-cdn.xitu.io/2016/11/29/805fd2776ae656464329c04f63181266?imageView2/1/w/180/h/180/q/85/format/webp/interlace/1')

經過proxyImage間接訪問MyImage。proxyImage控制來客戶對MyImage的訪問,而且在此過程當中加入一些額外的操做,好比在圖片加載前,先將src設置爲本地的loading圖。緩存

緩存代理

緩存代理能夠爲一些開銷較大的運算結果暫時的存儲,在下次運算時,若是傳遞的值一致,則能夠直接返回前面存儲的結果。性能優化

// 建立一個乘積函數
var mult = function() {
    console.log('開始計算乘積')
    var a = 1
    for(var i = 0, l = arguments.length; i<l ; i++) {
        a = a*arguments[i]
    }
    return a
}
// 加入緩存代理函數
var proxyMult = (function(){
    var cache = {}
    return function() {
        var args = Array.prototype.join.call(arguments, ',')
        if (args in cache) {
            return cache[args]
        }
        return cache[args] = mult.apply(this, arguments)
    }
})()

proxyMult(1,2,3,4) //24
proxyMult(1,2,3,4) //24

當第二次調用proxyMult的時候,本體mult並無直接計算,proxyMult直接返回以前的結果app

引入代理的意義

爲了說明代理的意義,下面引入一個面向對象的設計原則:單一職責原則函數

  1. 一個類(對象或者函數)而言,應該只能有一個引發它變化的緣由。若是一個對象承擔了多項職責,那麼引發變化的緣由可能就有多個。
  2. 實際上增長懶加載圖片只是一個景上添花的行爲。縱觀整個程序,咱們並無改變myImage的接口,可是經過代理,給接口添加了新的行爲,若是某天不須要了,也不用修改本體。
相關文章
相關標籤/搜索