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


Posted in Javascript onMarch 25, 2019

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

引入代理模式,其实是为了实现单一职责的面向对象设计原则。

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

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

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

虚拟代理

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

虚拟代理示例demo1: 图片loading预加载

//通过虚拟代理实现图片预加载
//代理模式进行图片预加载的实现思路是: 通过代理对象获取实际显示图片地址并进行加载,同时先让本体对象显示预加载图片,待代理对象将实际图片地址加载完毕后传递给本体对象进行显示即可。

//本体对象
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加载真实图片src完成后将src传递给本体对象显示
    myImage.setSrc(this.src)
  }
  return {
    setProxySrc: function(src){
      myImage.setSrc('../images/loding.gif') //2、代理对象控制本体对象使用加载图片src
      img.src = src          //3、代理对象的img对象获取将要传递给本体对象的真实图片src
    }
  }
})()

//通过代理对象来对本体对象进行访问
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可以为任意需要进行代理的函数,除了上述计算乘积的本体对象函数外,还可以是计算加减或进行其他操作的本体函数
  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>

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

以上所述是小编给大家介绍的javascript设计模式三:代理模式详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
javascript编程起步(第六课)
Jan 10 Javascript
用JavaScript实现单继承和多继承的简单方法
Mar 29 Javascript
javascript 打印内容方法小结
Nov 04 Javascript
解析jquery获取父窗口的元素
Jun 26 Javascript
javascript 操作符(~、&amp;、|、^、)使用案例
Dec 31 Javascript
jquery判断至少有一个checkbox被选中的方法
Jun 05 Javascript
Vue结合Video.js播放m3u8视频流的方法示例
May 04 Javascript
JQuery中queue方法用法示例
Jan 31 jQuery
微信小程序引入Vant组件库过程解析
Aug 06 Javascript
微信小程序webview组件交互,内联h5页面并网页实现微信支付实现解析
Aug 16 Javascript
jquery实现进度条状态展示
Mar 26 jQuery
基于JavaScript实现大文件上传后端代码实例
Aug 18 Javascript
js实现鼠标拖拽缩放div实例代码
Mar 25 #Javascript
Vue框架下引入ActiveX控件的问题解决
Mar 25 #Javascript
9102了,你还不会移动端真机调试吗
Mar 25 #Javascript
详解原生JS回到顶部
Mar 25 #Javascript
javascript验证form表单数据的案例详解
Mar 25 #Javascript
elementUI select组件默认选中效果实现的方法
Mar 25 #Javascript
详解javascript函数写法大全
Mar 25 #Javascript
You might like
40个迹象表明你还是PHP菜鸟
2008/09/29 PHP
php数组函数序列之array_key_exists() - 查找数组键名是否存在
2011/10/29 PHP
PHP基于yii框架实现生成ICO图标
2015/11/13 PHP
javascript克隆对象深度介绍
2012/11/20 Javascript
Extjs 3.3切换tab隐藏相应工具栏出现空白解决
2013/04/02 Javascript
alert中断settimeout计时功能
2013/07/26 Javascript
Js获取下拉框选定项的值和文本的实现代码
2014/02/26 Javascript
简述Matlab中size()函数的用法
2016/03/20 Javascript
jquery easyUI中ajax异步校验用户名
2016/08/19 Javascript
JavaScript通过filereader接口读取文件
2017/05/10 Javascript
Vue上传组件vue Simple Uploader的用法示例
2017/08/25 Javascript
微信小程序:数据存储、传值、取值详解
2019/05/07 Javascript
vue项目中使用AES实现密码加密解密(ECB和CBC两种模式)
2019/08/12 Javascript
[02:41]DOTA2英雄基础教程 谜团
2013/12/10 DOTA
[01:58]2018DOTA2亚洲邀请赛趣味视频——交流
2018/04/03 DOTA
Python实现以时间换空间的缓存替换算法
2016/02/19 Python
Python两个内置函数 locals 和globals(学习笔记)
2016/08/28 Python
Python与Java间Socket通信实例代码
2017/03/06 Python
Python tkinter模块中类继承的三种方式分析
2017/08/08 Python
Django学习笔记之为Model添加Action
2019/04/30 Python
Django框架实现分页显示内容的方法详解
2019/05/10 Python
python使用pandas处理excel文件转为csv文件的方法示例
2019/07/18 Python
关于python中plt.hist参数的使用详解
2019/11/28 Python
Python2与Python3的区别点整理
2019/12/12 Python
推荐技术人员一款Python开源库(造数据神器)
2020/07/08 Python
python解压zip包中文乱码解决方法
2020/11/27 Python
python利用后缀表达式实现计算器功能
2021/02/22 Python
Superdry极度乾燥官网:日本街头风格,纯英国制造品牌
2016/10/31 全球购物
招商经理岗位职责
2013/11/16 职场文书
高中打架检讨书
2014/02/13 职场文书
人力资源经理的岗位职责
2014/03/02 职场文书
2014年车间工作总结
2014/11/21 职场文书
2014初中数学教研组工作总结
2014/12/19 职场文书
幼儿教师辞职信范文
2015/03/02 职场文书
自主招生专家推荐信
2015/03/26 职场文书
西安事变观后感
2015/06/12 职场文书