1. 详解javascript设计模式三:代理模式

     更新时间:2019年03月25日 16:11:41   作者:一期一会   我要评论

    这篇文章主要介绍了javascript设计模式三:代理模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    代理模式是一种对程序对象进行控制性访问的一类解决方案。

    引入代理模式,其实是为了实?#20540;?#19968;职责的面向对象设计原则。

    单一职责其实就是指在一个类中(js中通常指对象和函数等),应仅有一个引起它变化的原因。这样会帮助程序设计具有良好的健壮和高内聚特性,从而当变化发生时,程序设计会尽量少的受到意外破坏。

    代理模式有多种方法,保护代理、远程代理、虚拟代理、缓存代理等。

    但在javascript中,代理模式最常用到的两种方法是虚拟代理和缓存代理。

    虚拟代理

    在理解虚拟代理时,可以将其想象为一个经纪人,客户程序需要通过这个虚拟代理(经纪人)来调用本体对象的方法。

    虚拟代理示例demo1: ?#35745;琹oading预加载

    //通过虚拟代理实现?#35745;?#39044;加载
    //代理模式进行?#35745;?#39044;加载的实现思路是: 通过代理对象获取?#23548;?#26174;示?#35745;?#22320;址并进行加载,同时先让本体对象显示预加载?#35745;?#24453;代理对象将?#23548;釋计?#22320;址加载完毕后传递给本体对象进行显示即可。
    
    //本体对象
    var myImage = (function(){
      var imgNode = new Image()
      document.body.appendChild(imgNode)
    
      return {
        setSrc: function(src){
          imgNode.src = src
        }
      }
    })()
    
    //代理对象
    var proxyImage = (function(){
      var img = new Image();     //1、代理对象新建一个img对象
      img.onload = function(){    //4、代理对象img加载真实?#35745;瑂rc完成后将src传递给本体对象显示
        myImage.setSrc(this.src)
      }
      return {
        setProxySrc: function(src){
          myImage.setSrc('../images/loding.gif') //2、代理对象控制本体对象使用加载?#35745;瑂rc
          img.src = src          //3、代理对象的img对象获取将要传递给本体对象的真实?#35745;瑂rc
        }
      }
    })()
    
    //通过代理对象来对本体对象进行访问
    proxyImage.setProxySrc('https://p1.ssl.qhimgs1.com/t0153297036f4471d81.jpg')
    

    虚拟代理示例demo2:合并HTTP请求,减少网络请求资源消耗

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>代理模式 虚拟代理合并HTTP请求</title>
    </head>
    <body>
      <div>
        <input type="checkbox" id="1" />1
        <input type="checkbox" id="2" />2
        <input type="checkbox" id="3" />3
        <input type="checkbox" id="4" />4
        <input type="checkbox" id="5" />5
        <input type="checkbox" id="6" />6
        <input type="checkbox" id="7" />7
        <input type="checkbox" id="8" />8
        <input type="checkbox" id="9" />9
      </div>  
    </body>
    <script>
      //使用
    
      //本体对象
      var synchornurFile = function(id){
        console.log('开始同步:' + id);
      }
    
      var proxySynchornurFile = (function(){
        var cache = [],   //集合一段时间内需要同步的id
          timer;   //定时器
    
        return function(id){
          cache.push(id)
    
          if(timer){   //保证不会覆盖已经启动的定时器
            return
          }
          timer = setTimeout(function(){
            synchornurFile(cache.join(','))
            clearTimeout(timer)
            timer = null
            cache.length = 0
          }, 2000)
        }
      })()
    
      var check = document.getElementsByTagName('input')
      for(var i=0; i<check.length; i++){
        check[i].onclick = function(){
          if(this.checked === true){
            proxySynchornurFile(this.id)
          }
        }
      }
    </script>
    </html>
    

    缓存代理

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

    缓存代理示例demo: 计算乘积

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>代理模式-缓存代理</title>
    </head>
    <body>
      <input type="text" id="input1">*
      <input type="text" id="input2">
      <div id="result"></div>
      <button type="button" id="btn">计算</button>
    </body>
    <script>
    
      //缓存代理示例: 计算乘积
      //本体对象
      var calculate = function(){
        var a = 1;
        for(var i=0; i<arguments.length; i++){
          a = a*arguments[i]
        }
        return a;
      }
    
      //代理对象,创建缓存代理的工厂,参数fn可以为?#25105;?#38656;要进行代理的函数,除了上述计算乘积的本体对象函数外,还可以是计算加减或进行其他操作的本体函数
      var proxyCalculate = function(fn){
        var resultCache = {};
    
        return function(){
          var args = Array.prototype.join.call(arguments, ',')
          if(args in resultCache){    //测试对象中是否有对应的name,有则直接返回该name的值
            return resultCache[args]
          }
          return resultCache[args] = fn.apply(this, arguments)
        }
      }
    
    
      document.getElementById('btn').onclick = function(){
        var v1 = document.getElementById('input1').value
        var v2 = document.getElementById('input2').value
        var result = proxyCalculate(calculate)(v1, v2)
    
        document.getElementById('result').innerHTML = result
      }
    
      //总结: 代理模式还有多种,比如保护代理、远程代理等,但js中常用的代理模式有虚拟代理和缓存代理两种。
    </script>
    </html>
    

    在编写业务代码时,并不需要一开始就考虑是否使用代理模式,只要当发?#36136;?#29992;代理模式更方便时,再编写代理对象即可。

    以上所述是小编给大家介绍的javascript设计模式三:代理模式详解整合,希望对大家有所帮助,如果大家有任?#25105;?#38382;请给我留言,小编会及时回复大家的。在此也非常?#34892;?#22823;家对脚本之家网站的支持!

    相关文章

    最新评论

    山东群英会开奖查询