js设计模式——代理模式

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

关键:当客户不方便直接访问一个对象或者不满足需求的时候,提供一个替身对象来控制这个对象的访问。客户实际上访问的是替身对象。替身对象对请求作出一些请求之后,再把请求交给本体对象。

 

 

 

保护代理用于控制不同权限的对象对目标对象的访问,但在 JavaScript 并不容易实现保护代理,因为我们无法判断谁访问了某个对象。
而虚拟代理是最常用的一种代理模式。
下面是一个图片预加载的代码,这里的代理起到了占位的作用。
 
<!DOCTYPE html>
<html>
<head>
 <title>图片预加载</title>
</head>
<body>

</body>
<script type="text/javascript">
 var myImage=(function () {
  // body...
  var imgNode=document.createElement('img');
  document.body.appendChild(imgNode);
  console.log(3)
  return {
   setSrc:function(src){
    console.log(4)
    imgNode.src=src;
   }
  }
 })();

 var proxyImage=(function(){
  var img=new Image;
  img.onload=function(){
   console.log(this.src)
   myImage.setSrc(this.src);
  }
  console.log(1)
  return {
   setSrc:function(src){
    console.log(2)
    myImage.setSrc('./loading.jpg');
    img.src=src;
   }
  }
 })();

 proxyImage.setSrc("https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=716310665,173562528&fm=26&gp=0.jpg");
</script>
</html>

 

 
图片预加载为什么要使用代理呢,是因为要遵循单一职责原则。
 
单一职责原则指的是,就一个类(通常也包括对象和函数等)而言,应该仅有一个引起它变化的原因。如果一个对象承担了多项职责,就意味着这个对象将变得巨大,引起它变化的原因可能会有多个。面向对象设计鼓励将行为分布到细粒度的对象之中,如果一个对象承担的职责过多,等于把这些职责耦合到了一起,这种耦合会导致脆弱和低内聚的设计。当变化发生时,设计可能会遭到意外的破坏。
 
 
代理和本体接口一致性。加载图片的myImage和proxyImage都使用的是setSrc接口。这样做有两个好处:
 用户可以放心地请求代理,他只关心是否能得到想要的结果。
 在任何使用本体的地方都可以替换成使用代理。 
 
下面是代理模式下的求乘积,也是一个动态创建代理的例子
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>代理模式-求乘积</title>
  </head>
  <body></body>
  <script>
    //计算乘积的函数
    var mult = function () {
      console.log("开始计算乘积");
      var a = 1;
      for (let i = 0; i < arguments.length; i++) {
        a = a * arguments[i];
      }
      return a;
    };

    var plus = function () {
      var a = 0;
      console.log("开始计算加法");
      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));
      };
    })();

    var createProxyFactory = function (fn) {
      var cache = {};
      return function () {
        var args = Array.prototype.join(arguments, ",");
        if (args in cache) {
          return cache[args];
        }
        return (cache[args] = fn.apply(this, arguments));
      };
    };

    var proxyPlus = createProxyFactory(plus);

    console.log(proxyMult(1, 2, 3, 4));
    console.log(proxyMult(1, 2, 3, 4));
    console.log(proxyPlus(1, 2, 3, 4));
    console.log(proxyPlus(1, 2, 3, 4));
  </script>
</html>

 

 
 
 

 

posted @ 2020-09-17 10:27  ellenxx  阅读(340)  评论(0编辑  收藏  举报