JavaScript设计模式与开发实践---读书笔记(6) 代理模式
代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。
代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对象。替身对象对请求做出一些处理后,再把请求转交给本体对象。
保护代理:代理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方法,在客户看来,代理对象和本体是一致的,代理接手请求的过程对于用户来说是透明的,用户不清楚代理和本体的区别。
这样有两个好处:
- 用户可以放心的请求代理,他只关心是否能得到想要的结果。
- 在任何使用本体的地方都可以替换成使用代理。
另外,如果代理对象和本体都为一个函数(函数也是对象),函数必然都能被执行,则可以认为它们也具有一致的"接口",代码如下:
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) 代理模式相关推荐
- javascript设计模式(javascript设计模式与开发实践读书笔记)
javascript设计模式(javascript设计模式与开发实践读书笔记) 单例模式 策略模式 代理模式 迭代器模式 发布-订阅模式 命令模式 组合模式 模板方法模式 享元模式 职责链模式 中介者 ...
- Javascript设计模式与开发实践读书笔记(1-3章)
第一章 面向对象的Javascript 1.1 多态在面向对象设计中的应用 多态最根本好处在于,你不必询问对象"你是什么类型"而后根据得到的答案调用对象的某个行为--你只管调用 ...
- 【夯实基础】《JavaScript设计模式与开发实践》笔记——闭包和高阶函数
虽然 JavaScript 是一门完整的面向对象的编程语言,但这门语言同时也拥有许多函数式语言的特性. 函数式语言的鼻祖是 LISP,JavaScript 在设计之初参考了 LISP 两大方言之一的 ...
- js设计模式与开发实践(读书笔记)
1 面向对象的js 1.1 动态类型语言和鸭子类型 编程语言按数据类型可分成静态类型和动态类型语言,其中js属于动态类型语言,对一个变量赋值时,不需要考虑其类型. 鸭子类型: 通俗理解,只要走起路来像 ...
- JS代理模式《JavaScript设计模式与开发实践》阅读笔记
代理模式 代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问. 保护代理和虚拟代理 保护代理:当有许多需求要向某对象发出一些请求时,可以设置保护代理,通过一些条件判断对请求进行过滤. 虚拟 ...
- JavaScript设计模式与开发实践 | 02 - this、call和apply
this JavaScript的this总是指向一个对象,至于指向哪个对象,是在运行时基于函数的执行环境的动态绑定的,而非函数被声明时的环境. this的指向 this的指向大致可以分为以下4类: 作 ...
- 《JavaScript设计模式与开发实践》模式篇(12)—— 装饰者模式
在传统的面向对象语言中,给对象添加功能常常使用继承的方式,但是继承的方式并不灵活, 还会带来许多问题:一方面会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之 改变;另一方面,继承这种功能复 ...
- JavaScript设计模式与开发实践——JavaScript的多态
"多态"一词源于希腊文polymorphism,拆开来看是poly(复数)+ morph(形态)+ ism,从字面上我们可以理解为复数形态. 多态的实际含义是:同一操作作用于不同的 ...
- 《JavaScript设计模式与开发实践》阅读摘要
<JavaScript设计模式与开发实践>作者:曾探 系统的介绍了各种模式,以及js中的实现.应用,以及超大量高质量代码,绝对值得一读 面向对象的js 静态类型:编译时便已确定变量的类型 ...
最新文章
- UVALive 4318 Navy maneuvers
- AIX 下磁盘 I/O 性能分析
- Excel XP受损文件的急救三招
- NHibernate学习笔记(转载):many-to-one/one-to-many/many-to-many关系映射
- Android通过adb命令传参给APP的方法
- Java 自动装箱与拆箱
- 少儿编程100讲轻松学python(二)-python cv2模块怎么安装
- session过期问题
- 十二、sed 命令与正则表达式
- 201521123014《Java程序设计》第1周学习总结
- 电子书的下载与查阅书的源码
- 爆赞,java后端开发路线。
- 学生网页设计作业源码 HTML+CSS 网上书店网站设计与实现
- 第四章 《无冬之夜》
- 【U8】固定资产模块卡片管理栏目设置中没有“凭证号”栏目
- excel批量生成批处理语句另存为.bat文件批量改名
- sd和sem啥区别_生物统计学-标准差(SD)和标准误(SEM)有何区别.pdf
- 阿里云open API中的签名算法
- 中控服务器PDS系统,bss中控服务器主机
- 统计表中百分比的表示方法
热门文章
- 学习笔记_vnpy实战培训day03
- GBDT(MART) 迭代决策树入门教程
- 阿里数据总监手把手教学:如何面向企业做一次有价值的数据分析
- 超越Excel、python的数据可视化报表,月薪3W的人都在用
- 关于bootstrap的table表显示无法找到匹配内容的问题随笔
- rez注入器源码_CF-rez-Tool crossfire的REZ文件全套修改工具 - 下载 - 搜珍网
- 设置Visual Studio code停止自动更新
- javascript的发展(周边插件的由来)
- 安装ipython(一分钟读懂)
- wpf datagrid 计算两个列的差值_天体到达指定方位角的时间计算