代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。

代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对象。替身对象对请求做出一些处理后,再把请求转交给本体对象。

保护代理:代理B可以帮助代理A过滤掉一些请求,这种代理叫保护代理。

虚拟代理:虚拟代理把一些开销很大的对象,延迟到真正需要它的时候才去创建。虚拟代理是最常用的一种代理模式。

1.虚拟代理实现图片预加载

图片预加载是一种常用技术。

常见的做法是先用一张loading图片占位,然后用异步的方式加载图片,等图片加载好了再把它填充到img节点里,这种场景就很适合使用虚拟代理。

    var myImage = (function(){var imgNode = document.createElement('img');document.body.appendChild(imgNode);return {setSrc: function(src){imgNode.src = src;}}})();var proxyImage = (function(){var img = new Image;img.onload = function(){myImage.setSrc(this.src);}return {setSrc: function(src){myImage.setSrc('images/1.jpg');//本地图片img.src = src;}}})();proxyImage.setSrc('http://img04.sogoucdn.com/app/a/100520021/b173203599e22d825c5f905d1da92535');

代理的意义:
单一职责原则:就一个类(通常也包括对象和函数)而言,应该仅有一个引起它变化的原因。职责被定义为"引起变化的原因"。

实际上,我们需要的只是给img节点设置src,预加载图片只是一个锦上添花的功能。于是代理的作用在这里就体现出来了,代理负责预加载图片,预加载的操作完成之后,把请求重新交给本体MyImage。

代理和本体接口的一致性:

上述代码,其中的关键是代理和本体都对外提供了setSrc方法,在客户看来,代理对象和本体是一致的,代理接手请求的过程对于用户来说是透明的,用户不清楚代理和本体的区别。

这样有两个好处:

  1. 用户可以放心的请求代理,他只关心是否能得到想要的结果。
  2. 在任何使用本体的地方都可以替换成使用代理。

另外,如果代理对象和本体都为一个函数(函数也是对象),函数必然都能被执行,则可以认为它们也具有一致的"接口",代码如下:

var myImage = (function(){var imgNode = document.createElement('img');document.body.appendChild(imgNode);return {imgNode.src = src;}})();var proxyImage = (function(){var img = new Image;img.onload = function(){myImage(this.src);}return function(src){myImage.setSrc('images/1.jpg');//本地图片img.src = src;}})();proxyImage.setSrc('http://img04.sogoucdn.com/app/a/100520021/b173203599e22d825c5f905d1da92535');

2.虚拟代理合并HTTP请求

在Web开发中,也许最大的开销就是网络请求。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>虚拟代理合并http请求</title>
</head>
<body><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
</body>
</html>
<script>var synchronousFile = function(id){console.log('开始同步文件,id为:'+id);};var proxySynchronousFile = (function(){var cache = [],//保存一段时间需要同步的IDtimer;//定时器return function (id){cache.push(id);if(timer){    //保证不会覆盖已经启动的定时器return;}timer = setTimeout(function(){synchronousFile(cache.join(','));//两秒后向本体发送需要同步的ID集合clearTimeout(timer);    //清空定时器timer = null;cache.length = 0;//清空ID集合},2000)}})();var checkbox = document.getElementByTagName('input');for(var i=0,c;c=checkbox[i++]; ){c.onclick = function(){if(this.checked === true){proxysynchronousFile(this.id);}}};</script>

3.虚拟代理在惰性加载中的应用

4.缓存代理

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

例子:1.计算乘积

  

    var mult = function(){console.log('开始计算乘积');var a = 1;for( var i=0,l=arguments.length;i<l;i++){a = a*arguments[i];}return a;};mult(2,3);mult(2,3,4);//缓存代理函数var proxyMult = (function(){var cache = {};return function(){var args = Array.prototype.join.call(arguments,',');if(args in cache){return cache[args];}return cache[args] = mult.apply(this,arguments);}})();proxyMult(1,2,3,4);proxyMult(1,2,3,4);//第二次调用proxyMult时,本体mult函数并没有被计算,proxyMult直接返回了之前缓存好的计算结果

2.缓存代理用于ajax异步请求数据

5.用高阶函数动态创建代理

可以为各种方法创建缓存代理。

var mult = function(){var a = 1;for( var i=0,l=arguments.length;i<l;i++){a = a*arguments[i];}return a;};var plus = function(){var a = 0;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,',');if(args in cache){return cache[args];}return cache[args] = fn.apply(this,arguments);}};var proxyMult = createProxyFactory(mult),proxyPlus = createProxyFactory(plus);alert(proxyMult(1,2,3,4));alert(proxyMult(1,2,3,4));alert(proxyPlus(1,2,3,4));alert(proxyPlus(1,2,3,4));

6.其他代理模式

  • 防火墙代理:控制网络资源的访问。
  • 远程代理
  • 保护代理
  • 智能引用代理
  • 写时复制代理:通常用于复制一个庞大对象的情况。

7. 小结

JavaScript开发中最常用的是虚拟代理和缓存代理。

转载于:https://www.cnblogs.com/6489c/p/5936855.html

JavaScript设计模式与开发实践---读书笔记(6) 代理模式相关推荐

  1. javascript设计模式(javascript设计模式与开发实践读书笔记)

    javascript设计模式(javascript设计模式与开发实践读书笔记) 单例模式 策略模式 代理模式 迭代器模式 发布-订阅模式 命令模式 组合模式 模板方法模式 享元模式 职责链模式 中介者 ...

  2. Javascript设计模式与开发实践读书笔记(1-3章)

    第一章 面向对象的Javascript 1.1 多态在面向对象设计中的应用   多态最根本好处在于,你不必询问对象"你是什么类型"而后根据得到的答案调用对象的某个行为--你只管调用 ...

  3. 【夯实基础】《JavaScript设计模式与开发实践》笔记——闭包和高阶函数

    虽然 JavaScript 是一门完整的面向对象的编程语言,但这门语言同时也拥有许多函数式语言的特性. 函数式语言的鼻祖是 LISP,JavaScript 在设计之初参考了 LISP 两大方言之一的 ...

  4. js设计模式与开发实践(读书笔记)

    1 面向对象的js 1.1 动态类型语言和鸭子类型 编程语言按数据类型可分成静态类型和动态类型语言,其中js属于动态类型语言,对一个变量赋值时,不需要考虑其类型. 鸭子类型: 通俗理解,只要走起路来像 ...

  5. JS代理模式《JavaScript设计模式与开发实践》阅读笔记

    代理模式 代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问. 保护代理和虚拟代理 保护代理:当有许多需求要向某对象发出一些请求时,可以设置保护代理,通过一些条件判断对请求进行过滤. 虚拟 ...

  6. JavaScript设计模式与开发实践 | 02 - this、call和apply

    this JavaScript的this总是指向一个对象,至于指向哪个对象,是在运行时基于函数的执行环境的动态绑定的,而非函数被声明时的环境. this的指向 this的指向大致可以分为以下4类: 作 ...

  7. 《JavaScript设计模式与开发实践》模式篇(12)—— 装饰者模式

    在传统的面向对象语言中,给对象添加功能常常使用继承的方式,但是继承的方式并不灵活, 还会带来许多问题:一方面会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之 改变;另一方面,继承这种功能复 ...

  8. JavaScript设计模式与开发实践——JavaScript的多态

    "多态"一词源于希腊文polymorphism,拆开来看是poly(复数)+ morph(形态)+ ism,从字面上我们可以理解为复数形态. 多态的实际含义是:同一操作作用于不同的 ...

  9. 《JavaScript设计模式与开发实践》阅读摘要

    <JavaScript设计模式与开发实践>作者:曾探 系统的介绍了各种模式,以及js中的实现.应用,以及超大量高质量代码,绝对值得一读 面向对象的js 静态类型:编译时便已确定变量的类型 ...

最新文章

  1. UVALive 4318 Navy maneuvers
  2. AIX 下磁盘 I/O 性能分析
  3. Excel XP受损文件的急救三招
  4. NHibernate学习笔记(转载):many-to-one/one-to-many/many-to-many关系映射
  5. Android通过adb命令传参给APP的方法
  6. Java 自动装箱与拆箱
  7. 少儿编程100讲轻松学python(二)-python cv2模块怎么安装
  8. session过期问题
  9. 十二、sed 命令与正则表达式
  10. 201521123014《Java程序设计》第1周学习总结
  11. 电子书的下载与查阅书的源码
  12. 爆赞,java后端开发路线。
  13. 学生网页设计作业源码 HTML+CSS 网上书店网站设计与实现
  14. 第四章 《无冬之夜》
  15. 【U8】固定资产模块卡片管理栏目设置中没有“凭证号”栏目
  16. excel批量生成批处理语句另存为.bat文件批量改名
  17. sd和sem啥区别_生物统计学-标准差(SD)和标准误(SEM)有何区别.pdf
  18. 阿里云open API中的签名算法
  19. 中控服务器PDS系统,bss中控服务器主机
  20. 统计表中百分比的表示方法

热门文章

  1. 学习笔记_vnpy实战培训day03
  2. GBDT(MART) 迭代决策树入门教程
  3. 阿里数据总监手把手教学:如何面向企业做一次有价值的数据分析
  4. 超越Excel、python的数据可视化报表,月薪3W的人都在用
  5. 关于bootstrap的table表显示无法找到匹配内容的问题随笔
  6. rez注入器源码_CF-rez-Tool crossfire的REZ文件全套修改工具 - 下载 - 搜珍网
  7. 设置Visual Studio code停止自动更新
  8. javascript的发展(周边插件的由来)
  9. 安装ipython(一分钟读懂)
  10. wpf datagrid 计算两个列的差值_天体到达指定方位角的时间计算