详解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 相关文章推荐
extjs 列表框(multiselect)的动态添加列表项的方法
Jul 31 Javascript
为超链接加上disabled后的故事
Dec 10 Javascript
用js来定义浏览器中一个左右浮动元素相对于页面主体宽度的位置的函数
Jan 21 Javascript
Extjs4.0设置Ext.data.Store传参的请求方式(默认为GET)
Apr 02 Javascript
JQuery each打印JS对象的方法
Nov 13 Javascript
js判断鼠标位置是否在某个div中的方法
Feb 26 Javascript
使用snowfall.jquery.js实现爱心满屏飞的效果
Jan 05 Javascript
NestJs 静态目录配置详解
Mar 12 Javascript
jQuery中DOM常见操作实例小结
Aug 01 jQuery
webpack 如何同时输出压缩和未压缩的文件的实现步骤
Jun 05 Javascript
基于javascript的无缝滚动动画实现2
Aug 07 Javascript
vue打开其他项目页面并传入数据详解
Nov 25 Vue.js
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
PHP中使用imagick实现把PDF转成图片
2015/01/26 PHP
PHP重定向与伪静态区别
2017/02/19 PHP
mapper--图片热点区域高亮组件官方站点
2007/12/22 Javascript
一组JS创建和操作表格的函数集合
2009/05/07 Javascript
Javascript 继承实现例子
2009/08/12 Javascript
基于jquery的表格排序
2010/09/11 Javascript
jquery ajax提交整个表单元素的快捷办法
2013/03/27 Javascript
JS格式化数字金额用逗号隔开保留两位小数
2013/10/18 Javascript
JQuery的$命名冲突详细解析
2013/12/28 Javascript
用JavaScript实现PHP的urlencode与urldecode函数
2015/08/13 Javascript
基于JS实现的笛卡尔乘积之商品发布
2016/05/13 Javascript
get  post jsonp三种数据交互形式实例详解
2017/08/25 Javascript
浅谈目前可以使用ES10的5个新特性
2019/06/25 Javascript
layui form表单提交之后重新加载数据表格的方法
2019/09/11 Javascript
vue实现评论列表功能
2019/10/25 Javascript
react 原生实现头像滚动播放的示例
2020/04/21 Javascript
python读取csv文件示例(python操作csv)
2014/03/11 Python
Python实现在matplotlib中两个坐标轴之间画一条直线光标的方法
2015/05/20 Python
TensorFlow实现Softmax回归模型
2018/03/09 Python
python 类的继承 实例方法.静态方法.类方法的代码解析
2019/08/23 Python
django框架中间件原理与用法详解
2019/12/10 Python
Python pandas库中的isnull()详解
2019/12/26 Python
python3 字符串知识点学习笔记
2020/02/08 Python
python 带时区的日期格式化操作
2020/10/23 Python
Pycharm-community-2020.2.3 社区版安装教程图文详解
2020/12/08 Python
Python爬虫自动化获取华图和粉笔网站的错题(推荐)
2021/01/08 Python
大学生物业管理求职信
2013/10/24 职场文书
竞聘医务工作人员的自我评价分享
2013/11/04 职场文书
社区志愿者心得体会
2014/01/03 职场文书
公司成立感言
2014/01/11 职场文书
交通事故协议书范文
2014/10/23 职场文书
意向协议书
2015/01/27 职场文书
大专护理专业自荐信
2015/03/25 职场文书
二十年同学聚会感言
2015/07/30 职场文书
公司规章制度范本
2015/08/03 职场文书
环保建议书作文500字
2015/09/14 职场文书