Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
73 lines (57 sloc) 1.74 KB

代理模式

情景:小明追女生 A

  • 非代理模式:小明 =花=> 女生A
  • 代理模式:小明 =花=> 让女生A的好友B帮忙 =花=> 女生A

代理模式的特点

  • 代理对象和本体对象具有一致的接口,对使用者友好

代理模式的种类有很多,在 JS 中最常用的为虚拟代理和缓存代理。

虚拟代理实现图片预加载

下面这段代码运用代理模式来实现图片预加载,可以看到通过代理模式巧妙地将创建图片与预加载逻辑分离,并且在未来如果不需要预加载,只要改成请求本体代替请求代理对象就行。

const myImage = (function() {
  const imgNode = document.createElement('img')
  document.body.appendChild(imgNode)
  return {
    setSrc: function(src) {
      imgNode.src = src
    }
  }
})()

const proxyImage = (function() {
  const img = new Image()
  img.onload = function() { // http 图片加载完毕后才会执行
    myImage.setSrc(this.src)
  }
  return {
    setSrc: function(src) {
      myImage.setSrc('loading.jpg') // 本地 loading 图片
      img.src = src
    }
  }
})()

proxyImage.setSrc('http://loaded.jpg')

缓存代理实现乘积计算

const mult = function() {
  let a = 1
  for (let i = 0, l; l = arguments[i++];) {
    a = a * l
  }
  return a
}

const proxyMult = (function() {
  const cache = {}
  return function() {
    const tag = Array.prototype.join.call(arguments, ',')
    if (cache[tag]) {
      return cache[tag]
    }
    cache[tag] = mult.apply(this, arguments)
    return cache[tag]
  }
})()

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

小 tip

在开发时候不要先去猜测是否需要使用代理模式,如果发现直接使用某个对象不方便时,再来优化不迟。