浅谈代理模式

260 阅读1分钟

代理模式

续更...

一、缓存代理

  1. 这里进行描述:
/**
 * 缓存代理可以为一些开销大的运算结果提供暂时的存储,
 * 下次运算的时候,如果传进来的参数跟之前一致,则可以直接返回前面存储的运算结果。
 */
const mult = function () {
  let a = 1;
  for (let i = 0; i < arguments.length; i++) {
    a = a * arguments[i];
  }
  console.log('a=', a);
  return a;
}

定义好这个函数以后,我们分别调用两次:

    mult(1,2,3); // a= 6
    mult(1,2,3,4); // a= 24
  1. 现在再写一个缓存代理函数:
/**
 * 现在我们加入缓存代理
 * 这样的话,在调用缓存函数时,先执行缓存代理,再执行原函数
 */
const proxyMult = (function () {
  const cache = {};  // 对象缓存
  console.log('obj0', cache);
  return function () {
    const args = Array.prototype.join.call(arguments, ',');
    if (args in cache) {
      console.log('打印此处说明执行了缓存!!!');
      console.log('obj1', cache);
      return cache[args]
    }
    return cache[args] = mult.apply(this, arguments);
  }
})()

这时候我们就不用直接调用原函数,而是调用代理函数即可。 调用:

proxyMult(2, 3, 4); // a= 24
proxyMult(2, 3, 4);  // 执行缓存
proxyMult(2, 3, 4);  // 执行缓存

来看看打印的结果:

obj0 {}
a= 24
打印此处说明执行了缓存!!!
obj1 { '2,3,4': 24 }
打印此处说明执行了缓存!!!
obj1 { '2,3,4': 24 }

结论:a 只打印了一次,obj 执行了2次调用。所以我们代理的目的达到了,当运算的开销变得非常大的时候,使用缓存代理可以减少不必要的重复性计算

  1. 这里也可以使用 ES6 中的 Map:
const proxyMult = (function () {
  const cache = new Map(); // Map 缓存
  console.log('map0', cache);
  return function () {
    const args = Array.prototype.join.call(arguments, ',');
    if (cache.has(args)) {
      console.log('打印此处说明执行了缓存!!!');
      console.log('map1', cache);
      return cache.get(args)
    }
    return cache.set(args, mult.apply(this, arguments))
  }
})()
proxyMult(2, 3, 4);
proxyMult(2, 3, 4);
proxyMult(2, 3, 4);

来看一下打印结果:

map0 Map(0) {}
a= 24
打印此处说明执行了缓存!!!
map1 Map(1) { '2,3,4' => 24 }
打印此处说明执行了缓存!!!
map1 Map(1) { '2,3,4' => 24 }

同样的,arguments 也可以用 ...rest 参数去进行改进... 推荐使用 ES6 新增的 Map 数据结构。

const proxyMult = () => {
  const cache = new Map();
  return (...rest) => {
    if (cache.has(rest.toString())) {
      return cache.get(rest.toString())
    }
    return cache.set(rest.toString(), mult(...rest));
    // or
    return cache.set(rest.toString(), mult.apply(this, rest));
  }
}

参考来源 《JavaScript 设计模式与开发实践》

第一篇文字,还望各位大佬不吝指点一二 ~