详解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 相关文章推荐
Jquery 常用方法经典总结
Jan 28 Javascript
javascript循环变量注册dom事件 之强大的闭包
Sep 08 Javascript
jquery mobile实现拨打电话功能的几种方法
Aug 05 Javascript
正负小数点后两位浮点数实现原理及代码
Sep 06 Javascript
使用indexOf等在JavaScript的数组中进行元素查找和替换
Sep 18 Javascript
js简单的弹出框有关闭按钮
May 05 Javascript
js获取鼠标点击的对象,点击另一个按钮删除该对象的实现代码
May 13 Javascript
Node.js 日志处理模块log4js
Aug 28 Javascript
JavaScript文本特效实例小结【3个示例】
Dec 22 Javascript
Vue自定义指令写法与个人理解
Feb 09 Javascript
mapboxgl实现带箭头轨迹线的代码
Jan 04 Javascript
手写Spirit防抖函数underscore和节流函数lodash
Mar 22 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
CI框架学习笔记(二) -入口文件index.php
2014/10/27 PHP
浅析PHP关键词替换的类(避免重复替换,保留与还原原始链接)
2015/09/22 PHP
深入理解PHP内核(二)之SAPI探究
2015/11/10 PHP
Thinkphp5.0 框架视图view的比较标签用法分析
2019/10/12 PHP
js no-repeat写法 背景不重复
2009/03/18 Javascript
Jquery解析json数据详解
2013/12/26 Javascript
javascript中match函数的用法小结
2014/02/08 Javascript
让html页面不缓存js的实现方法
2014/10/31 Javascript
jQuery中parentsUntil()方法用法实例
2015/01/07 Javascript
TypeOf这些知识点你了解吗
2016/02/21 Javascript
mvc 、bootstrap 结合分布式图简单实现分页
2016/10/10 Javascript
Vue 仿百度搜索功能实现代码
2017/02/16 Javascript
利用HBuilder打包前端开发webapp为apk的方法
2017/11/13 Javascript
浅谈vue-cli 3.0.x 初体验
2018/04/11 Javascript
layui中table表头样式修改方法
2018/08/15 Javascript
移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能
2019/06/10 Javascript
Vue中错误图片的处理的实现代码
2019/11/07 Javascript
微信小程序新闻网站详情页实例代码
2020/01/10 Javascript
JSONP 的原理、理解 与 实例分析
2020/05/16 Javascript
vue循环中点击选中再点击取消(单选)的实现
2020/09/10 Javascript
python 中文乱码问题深入分析
2011/03/13 Python
Python正则表达式匹配HTML页面编码
2015/04/08 Python
Python实现读取字符串按列分配后按行输出示例
2018/04/17 Python
解决Python下json.loads()中文字符出错的问题
2018/12/19 Python
Python模块的加载讲解
2019/01/15 Python
在pyqt5中QLineEdit里面的内容回车发送的实例
2019/06/21 Python
详解HTML5通讯录获取指定多个人的信息
2016/12/20 HTML / CSS
DOUGLAS波兰:在线销售香水和化妆品
2020/07/05 全球购物
开工庆典邀请函范文
2014/01/16 职场文书
建筑个人求职信范文
2014/01/25 职场文书
2014年办公室文员工作总结
2014/11/12 职场文书
2014社区健康教育工作总结
2014/12/16 职场文书
高考诚信考试承诺书
2015/04/29 职场文书
用Python监控你的朋友都在浏览哪些网站?
2021/05/27 Python
python的列表生成式,生成器和generator对象你了解吗
2022/03/16 Python
我家女友可不止可爱呢 公开OP主题曲无字幕动画MV
2022/04/11 日漫