设计模式--代理模式

105 阅读2分钟

1.定义

代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。

2.虚拟代理实现图片预加载

图片预加载:如果直接给某张图片设置src属性,由于图片过大或者是网络不佳,那么web界面会很容易产生留白界面,常用的方法是设置一张loading图片作为占位,等图片加载好了再把他填充到img中去。

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 () {
    myImage.setSrc(this.src);
  };
  return {
    setSrc: function (src) {
      myImage.setSrc("本地图片地址");
      img.src = src;
    },
  };
})();

proxyImage.setSrc("远程图片地址");

不用代理的方式实现图片预加载

const MyImage = (function () {
  const imgNode = document.createElement("img");
  document.body.appendChild(imgNode);
  const img = new Image();
  img.onload = function () {
    imgNode.src = img.src;
  };
  return {
    setSrc: function (src) {
      imgNode.src = "本地图片地址";
      img.src = src;
    },
  };
})();
MyImage.setSrc("远程图片地址");

为什么需要代理?如果有一天网速很快,快到我们根本不需要对图片进行预加载处理这时候来更改代码则还需要更改myImage函数中的逻辑,如果使用代理的方式那我们直接改成请求本体而不是请求代理对象。

4.缓存代理

缓存代理可以为一些开销大的运算结果提供暂时的存储,在下次运算时,如果传递进来的参数和之前一直,则可以直接返回前面储存的运算结果。

//计算乘积
const mult = function () {
  const a = 1;
  for (let i = 0, l = arguments.length; i < l; i++) {
    a = a * arguments[i];
  }
  return a;
};
//计算加和
const plus = function () {
  const a = 0;
  for (let i = 0, l = arguments.length; i < l; i++) {
    a = a + arguments[i];
  }
  return a;
};
//创建缓存代理的工厂
const createProxyFactory = function (fn) {
  const cache = {};
  return function () {
    const args = Array.prototype.join.call(arguments, ",");
    if (args in cache) {
      return cache[args];
    }
    return (cache[args] = fn.apply(this, arguments));
  };
};
const proxyMult = createProxyFactory(mult),
  proxyPlus = createProxyFactory(plus);
console.log(proxyMult(1, 2, 3, 4)); // 输出:24
console.log(proxyMult(1, 2, 3, 4)); // 输出:24
console.log(proxyPlus(1, 2, 3, 4)); // 输出:10
console.log(proxyPlus(1, 2, 3, 4)); // 输出:10