代理模式是非常常见的模式,比如我们使用的VPN工具,明星的经纪人,都是代理模式的例子。但是,有人会疑问,明明可以直接访问对象,为什么中间还要加一个壳呢?这也就说到了代理模式的好处。在我看来,代理模式最大的好处,就是在不动原有对象的同时,可以给原有对象增加一些新的特性或者行为。

  1. /**
  2. * pre:代理模式
  3. * 小明追求A,B是A的好朋友,小明比较腼腆,不好意思直接将花交给A,
  4. * 于是小明将花交给B,再由B交给A.
  5. */
  6. //----------- 示例1 ---------
  7. // 不使用代理
  8. var Flower = function() {};
  9. var xiaoming = {
  10. sendFlower: function(target) {
  11. var flower = new Flower();
  12. target.receiveFlower(flower);
  13. }
  14. };
  15. var A = {
  16. receiveFlower: function(flower) {
  17. console.log("收到花:" + flower);
  18. }
  19. };
  20. xiaoming.sendFlower(A);
  21.  
  22. // ----------- 示例2 --------------
  23. // 使用代理1
  24. var Flower = function() {};
  25. var xiaoming = {
  26. sendFlower: function(target) {
  27. var flower = new Flower();
  28. B.receiveFlower(flower);
  29. }
  30. };
  31. var B = {
  32. receiveFlower: function(flower) {
  33. A.receiveFlower(flower);
  34. }
  35. };
  36. var A = {
  37. receiveFlower: function(flower) {
  38. console.log("收到花:" + flower);
  39. }
  40. };
  41. xiaoming.sendFlower(B);
  42.  
  43. //------------- 示例3 ---------------
  44. /*
  45. * 使用代理2
  46. * 从示例1和示例2,看不出使用代理有什么用处,B只不过是从中间转手了一次。
  47. * 接下来,我们想一下。给喜欢的人送花,怎样才能提高成功率呢?
  48. * 我们都知道,人有心情好和心情差的时候,当美女心情好的时候,送花成功的概率自然要大些。
  49. * 于是,我们将代理升级,监听美女的心情,心情好的时候再给她送花。
  50. * 为了演示,我们假设2秒后,A的心情变好。
  51. */
  52.  
  53. var Flower = function() {};
  54. var xiaoming = {
  55. sendFlower: function(target) {
  56. var flower = new Flower();
  57. B.receiveFlower(flower);
  58. }
  59. };
  60. var B = {
  61. receiveFlower: function(flower) {
  62. A.listenGoodMood(function() {
  63. A.receiveFlower(flower);
  64. });
  65. }
  66. };
  67. var A = {
  68. receiveFlower: function(flower) {
  69. console.log("收到花:" + flower);
  70. },
  71. listenGoodMood: function(fn) {
  72. setTimeout(function() {
  73. fn.apply(this, arguments);
  74. }, 2000);
  75. }
  76. };
  77. xiaoming.sendFlower(B);
  78. // ---------- 示例4 ---------------
  79. /*
  80. * 【代理模式用处】:虚拟代理
  81. * 这里以加载图片为例,我们都知道当网络不畅以及图片过大时,图片加载都比较慢,
  82. * 为了更好的用户体验,我们都会在原图片未加载完成前,加上loading图片。
  83. * */
  84. //--4 _01未使用代理--
  85. var myImage = (function() {
  86. var imgNode = document.createElement("img");
  87. document.body.appendChild(imgNode);
  88. return {
  89. setSrc: function(src) {
  90. this.imgNode.src = src;
  91. }
  92. }
  93. })();
  94. myImage.setSrc("xxx");
  95. //--4_02使用代理--
  96. var proxyMyImage = (function() {
  97. var img = new Image();
  98. img.onload = function() {
  99. myImage.setSrc(this.src);
  100. };
  101. return {
  102. setSrc: function(src) {
  103. myImage.setSrc("loading.jpg");
  104. img.src = src;
  105. }
  106. }
  107. })();
  108. proxyMyImage.setSrc("xxx");
  109. /*
  110. * [注]:这里可以看到代理模式的好处:在不改变原有接口的同时,可以为系统添加新的行为。
  111. */
  112. //--------- 示例5---------------
  113. /*
  114. * 【代理模式用处】:合并http请求
  115. * 这里以选择文件同步为例。
  116. * 以往用户同步文件,在用户选中的时候就触发,这种方法做到了实时性,但无疑增加了网络的开销。
  117. * 实际在使用的过程中,往往并不需要立刻就同步。
  118. * 以下通过代理模式,将在用户选中文件2秒后进行同步请求。
  119. * */
  120. // --- 包含一段html代码,请自行添加到一个文件中 ------
  121. <html>
  122. <body>
  123. <button id="input">点我上传</button>
  124. <input type="checkbox" id="1"></input>1
  125. <input type="checkbox" id="2"></input>2
  126. <input type="checkbox" id="3"></input>3
  127. <input type="checkbox" id="4"></input>4
  128. <input type="checkbox" id="5"></input>5
  129. <input type="checkbox" id="6"></input>6
  130. <input type="checkbox" id="7"></input>7
  131. <input type="checkbox" id="8"></input>8
  132. <input type="checkbox" id="9"></input>9
  133. </body>
  134. </html>
  135. // -- 上传文件 --
  136. var synchronizeFile = function(id) {
  137. console.log("开始同步文件:" + id);
  138. };
  139. var proxySynchronizeFiles = (function() {
  140. var fileCache = [],
  141. timer;
  142. return function(id) {
  143. fileCache.push(id);
  144. if(timer) {
  145. return;
  146. }
  147. timer = setTimeout(function() {
  148. synchronizeFile(fileCache.join(","));
  149. clearTimeout(timer);
  150. timer = null;
  151. checkArr.length = 0;
  152. }, 2000);
  153. }
  154. })();
  155. var checkArr = document.getElementsByTagName("input");
  156. for(var i = 0, c; c = checkArr[i++];) {
  157. c.onclick = function() {
  158. if(this.checked == true) {
  159. proxySynchronizeFiles(this.id);
  160. }
  161. }
  162. }
  163. // ------------ 示例6 -----------------
  164. /*
  165. * 【代理模式用处】:缓存代理
  166. * 以计算器为例,比如计算某些数的乘积,当参数重复时,我们希望不用重复计算,直接返回结果。
  167. * 以下用到代理模式做缓存。
  168. */
  169. var mult = function() {
  170. if(!arguments) {
  171. console.log("请输入参数");
  172. return;
  173. }
  174. var a = 1;
  175. for(var i = 0, b; b = arguments[i++];) {
  176. a = a * b;
  177. }
  178. return a;
  179. };
  180.  
  181. var proxyMult = (function() {
  182. var cache = {};
  183. return function() {
  184. var str = Array.prototype.join.call(arguments, ",");
  185. if(str in cache) {
  186. console.log("重复return.");
  187. return cache[str];
  188. }
  189. return cache[str] = mult.apply(this, arguments);
  190. }
  191. })();
  192.  
  193. console.log(proxyMult(2, 3, 4));
  194. console.log(proxyMult(2, 3, 4));
  195. //------------ 示例7 --------------
  196. /*
  197. * 缓存代理升级 - 通用版计算
  198. *
  199. */
  200. var mult = function() {
  201. if(!arguments) {
  202. return;
  203. }
  204. var t = 1;
  205. for(var i = 0, a; a = arguments[i++];) {
  206. t = t * a;
  207. }
  208. return t;
  209. };
  210. var plus = function() {
  211. if(!arguments) {
  212. return;
  213. }
  214. var t = 0;
  215. for(var a of arguments) {
  216. t += a;
  217. }
  218. return t;
  219. };
  220. var createProxyCaculate = function(fn) {
  221. var cache = {};
  222. return function() {
  223. var str = Array.prototype.join.call(arguments, ",");
  224. if(str in cache) {
  225. console.log("重复return" + str);
  226. return cache[str];
  227. }
  228. return cache[str] = fn.apply(this, arguments);
  229. }
  230. };
  231. var proxyMult = createProxyCaculate(mult);
  232. var proxyPlus = createProxyCaculate(plus);
  233. console.log(proxyMult(2, 3, 4));
  234. console.log(proxyMult(2, 3, 4));
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

JavaScript设计模式_03_代理模式的更多相关文章

  1. JavaScript设计模式之代理模式

    一.代理模式概念 代理,顾名思义就是帮助别人做事,GoF对代理模式的定义如下: 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问.代理模式使得代理对象控制具体对象的引用.代理几乎可 ...

  2. JavaScript 设计模式之代理模式

    一.代理模式概念解读 1.代理模式概念文字解读 代理,顾名思义就是帮助别人做事,GOF对代理模式的定义如下: 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问.代理模式使得代理对象 ...

  3. 第三章 --- 关于Javascript 设计模式 之 代理模式

    第一.定义: 代理模式是为一个对象提供代用品或者占位符,以便控制对它的访问. 比如说,某男生小明想向他的女神 A 表白,刚好小明认识的一个女生B 和 女神A 是好朋友,那么小明就想让 女生B 帮忙送花 ...

  4. 学习javascript设计模式之代理模式

    1.代理模式为一个对象提供一个代用品或占位符,以便控制对它的访问. 2.不用代理模式: 客户 -> 本体  使用代理模式:  客户 -> 代理 -> 本体 3.例子场景1 点击操作与 ...

  5. JavaScript设计模式(代理模式)

    一.简单的单例模式: 1.未使用代理模式的情况:小明直接给女神送花 var Flower = function() {} var xiaoming = { sendFlower: function( ...

  6. JavaScript设计模式-19.代理模式

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. C#设计模式(13)——代理模式(Proxy Pattern)

    一.引言 在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访问到这些对象,如果直接访问对象给系统带来不必要的复杂性,这时候可以在客户端和目标对象之间增加一层中间层,让代 ...

  8. 乐在其中设计模式(C#) - 代理模式(Proxy Pattern)

    原文:乐在其中设计模式(C#) - 代理模式(Proxy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 代理模式(Proxy Pattern) 作者:webabcd 介绍 为 ...

  9. JavaScript设计模式之----组合模式

    javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...

随机推荐

  1. view测量

    一.测规格是由测量模式mode和测量大小size组成的,size好说,那测量模式mode代表什么含义呢.由上面的代码可知,测量模式有三类:    UNSPECIFIED    父控件不对你有任何限制, ...

  2. JAVA常用集合源码解析系列-ArrayList源码解析(基于JDK8)

    文章系作者原创,如有转载请注明出处,如有雷同,那就雷同吧~(who care!) 一.写在前面 这是源码分析计划的第一篇,博主准备把一些常用的集合源码过一遍,比如:ArrayList.HashMap及 ...

  3. LeetCode 376. Wiggle Subsequence 摆动子序列

    原题 A sequence of numbers is called a wiggle sequence if the differences between successive numbers s ...

  4. Python全栈之路-Day33

    1 time模块 #!/usr/bin/env python # __Author__: "wanyongzhen" # Date: 2017/4/7 import time # ...

  5. 利用子集构造法实现NFA到DFA的转换

    概述 NFA非有穷自动机,即当前状态识别某个转换条件后到达的后继状态不唯一,这种自动机不便机械实现,而DFA是确定有限状态的自动机,它的状态转换的条件是确定的,且状态数目往往少于NFA,所以DFA能够 ...

  6. DOS(Disk Operation System:磁盘操作系统)常见命令

    学习Java语言的第一节课总是练习DOS命令,用记事本敲出自己的第一个Java语言的HelloWorld程序案例,在此特意总结一下基本的DOS命令以作记录和分享. Windows+R快捷键---> ...

  7. 从零开始构建一个的asp.net Core 项目

    最近突发奇想,想从零开始构建一个Core的MVC项目,于是开始了构建过程. 首先我们添加一个空的CORE下的MVC项目,创建完成之后我们运行一下(Ctrl +F5).我们会在页面上看到"He ...

  8. H5 canvas圆形的时钟

    今天用H5中的canvas标签做一个时钟,H5中有很多好用的新增标签,真的很不错. 1.canvas标签介绍 <canvas> 标签定义图形,比如图表和其他图像,你必须使用脚本来绘制图形. ...

  9. linux服务器远程链接排错

    查看服务器是否能正常访问: xshell下本地shell操作: ping <ip> 关闭服务器iptables防火墙: 查看服务器端口是否正常开启: telnet <ip> & ...

  10. jQuery之文档处理

    jQuery 文档处理 1)内部插入 2)外部插入 3)包裹 4)替换 5)删除 6)复制 1.内部插入 append(content|fn) 向每个匹配的元素内部追加内容. 向所有段落中追加一些HT ...