zoukankan      html  css  js  c++  java
  • 设计模式-代理模式

    举个例子,如果想请明星来办一场商业演出,你是无法直接联系到本人的,只能联系他的经纪人(明星本人的时间比较宝贵),经纪人会把商业演出的细节和报酬都谈好之后,再把合同交给明星签,经纪人就是代理。在程序中,代理可以看做是一个对象,这个对象是一个占位符

    虚拟代理

    在Web开发中,也许最大的开销就是网络请求。假设我们在做一个文件同步的功能,当我们选中一个 checkbox 的时候,它对应的文件就会被同步到另外一台备用服务器上面,如图所示

    一般的做法是先获取到所有的checkbox,然后给他们绑定点击事件,并且在点击的同时往另一台服务器同步文件,这种做法有什么问题?如果用户在2s内选中了4个文件,需要向服务器发送4次HTTP请求,如此频繁的网络请求将会带来相当大的开销。

    解决方案是,我们可以通过一个代理函数proxySynchronousFile来收集一段时间之内的请求,最后一次性发送给服务器

    <input type="checkbox" id="1"></input>1
    <input type="checkbox" id="2"></input>2
    <input type="checkbox" id="3"></input>3
    <input type="checkbox" id="4"></input>4
    <input type="checkbox" id="5"></input>5
    <input type="checkbox" id="6"></input>6
    <input type="checkbox" id="7"></input>7
    <input type="checkbox" id="8"></input>8
    <input type="checkbox" id="9"></input>9
    
    var synchronousFile = function(id) {
      console.log('开始同步文件,id 为: ' + id);
    };
    
    var proxySynchronousFile = (function() {
      var cache = [], // 保存一段时间内需要同步的 ID
        timer; // 定时器
      return function(id) {
        cache.push(id);
        if (timer) { // 保证不会覆盖已经启动的定时器
          return;
        }
        timer = setTimeout(function() {
          synchronousFile(cache.join(',')); // 2 秒后向本体发送需要同步的 ID 集合
          clearTimeout(timer);
          timer = null;
          cache.length = 0;
        }, 2000);
      }
    })();
    
    var checkbox = document.getElementsByTagName('input');
    for (var i = 0, c; c = checkbox[i++];) {
      c.onclick = function() {
        if (this.checked === true) {
          proxySynchronousFile(this.id);
        }
      }
    };
    

    缓存代理

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

    下面用计算乘积的例子演示如何使用缓存代理,实际开发中应该是开销较大的运算,这里仅作演示

    // 计算乘积
    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 createProxyFactory = function(fn) {
      var cache = {};
      return function() {
        var args = Array.prototype.join.call(arguments, ','); // '1,2,3,4'
        if (args in cache) {
          return cache[args];
        }
        // {'1,2,3,4': 24}
        return cache[args] = fn.apply(this, arguments);
      }
    };
    
    var proxyMult = createProxyFactory(mult);
    
    console.log(proxyMult(1, 2, 3, 4));
    console.log(proxyMult(1, 2, 3, 4));
    

    代理模式的变体种类非常多,比较常用的是虚拟代理和缓存代理,其他还有防火墙代理、远程代理、保护代理、智能引用代理和写时复制代理

    常用网站: SegmentFault | GitHub | 掘金社区
  • 相关阅读:
    RHEL因为selinux设置失误,无法重启问题。(centos适用)
    Linux系统忘记管理员密码(CentOS、RHEL、Ubuntu)
    cobbler PXE 安装系统时出现的问题
    虚拟机ping 不通主机,主机可ping 虚拟机解决方法
    CentOS7系统更改网卡名为eth0
    PXE-cobbler 无人值守装机------续
    PXE-cobbler 无人值守装机
    DELL PowerEdge R410系统日志满报错
    matlab添加toolbox失败的解决办法
    vs2017+opencv3.4.0的配置方法
  • 原文地址:https://www.cnblogs.com/yesyes/p/15375964.html
Copyright © 2011-2022 走看看