代理模式是非常常见的模式,比如我们使用的VPN工具,明星的经纪人,都是代理模式的例子。但是,有人会疑问,明明可以直接访问对象,为什么中间还要加一个壳呢?这也就说到了代理模式的好处。在我看来,代理模式最大的好处,就是在不动原有对象的同时,可以给原有对象增加一些新的特性或者行为。
/** * pre:代理模式 * 小明追求A,B是A的好朋友,小明比较腼腆,不好意思直接将花交给A, * 于是小明将花交给B,再由B交给A. */ //----------- 示例1 --------- // 不使用代理 var Flower = function() {}; var xiaoming = { sendFlower: function(target) { var flower = new Flower(); target.receiveFlower(flower); } }; var A = { receiveFlower: function(flower) { console.log("收到花:" + flower); } }; xiaoming.sendFlower(A); // ----------- 示例2 -------------- // 使用代理1 var Flower = function() {}; var xiaoming = { sendFlower: function(target) { var flower = new Flower(); B.receiveFlower(flower); } }; var B = { receiveFlower: function(flower) { A.receiveFlower(flower); } }; var A = { receiveFlower: function(flower) { console.log("收到花:" + flower); } }; xiaoming.sendFlower(B); //------------- 示例3 --------------- /* * 使用代理2 * 从示例1和示例2,看不出使用代理有什么用处,B只不过是从中间转手了一次。 * 接下来,我们想一下。给喜欢的人送花,怎样才能提高成功率呢? * 我们都知道,人有心情好和心情差的时候,当美女心情好的时候,送花成功的概率自然要大些。 * 于是,我们将代理升级,监听美女的心情,心情好的时候再给她送花。 * 为了演示,我们假设2秒后,A的心情变好。 */ var Flower = function() {}; var xiaoming = { sendFlower: function(target) { var flower = new Flower(); B.receiveFlower(flower); } }; var B = { receiveFlower: function(flower) { A.listenGoodMood(function() { A.receiveFlower(flower); }); } }; var A = { receiveFlower: function(flower) { console.log("收到花:" + flower); }, listenGoodMood: function(fn) { setTimeout(function() { fn.apply(this, arguments); }, 2000); } }; xiaoming.sendFlower(B); // ---------- 示例4 --------------- /* * 【代理模式用处】:虚拟代理 * 这里以加载图片为例,我们都知道当网络不畅以及图片过大时,图片加载都比较慢, * 为了更好的用户体验,我们都会在原图片未加载完成前,加上loading图片。 * */ //--4 _01未使用代理-- var myImage = (function() { var imgNode = document.createElement("img"); document.body.appendChild(imgNode); return { setSrc: function(src) { this.imgNode.src = src; } } })(); myImage.setSrc("xxx"); //--4_02使用代理-- var proxyMyImage = (function() { var img = new Image(); img.onload = function() { myImage.setSrc(this.src); }; return { setSrc: function(src) { myImage.setSrc("loading.jpg"); img.src = src; } } })(); proxyMyImage.setSrc("xxx"); /* * [注]:这里可以看到代理模式的好处:在不改变原有接口的同时,可以为系统添加新的行为。 */ //--------- 示例5--------------- /* * 【代理模式用处】:合并http请求 * 这里以选择文件同步为例。 * 以往用户同步文件,在用户选中的时候就触发,这种方法做到了实时性,但无疑增加了网络的开销。 * 实际在使用的过程中,往往并不需要立刻就同步。 * 以下通过代理模式,将在用户选中文件2秒后进行同步请求。 * */ // --- 包含一段html代码,请自行添加到一个文件中 ------ <html> <body> <button id="input">点我上传</button> <input type="checkbox" id="1"></input>1 <input type="checkbox" id="2"></input>2 <input type="checkbox" id="3"></input>3 <input type="checkbox" id="4"></input>4 <input type="checkbox" id="5"></input>5 <input type="checkbox" id="6"></input>6 <input type="checkbox" id="7"></input>7 <input type="checkbox" id="8"></input>8 <input type="checkbox" id="9"></input>9 </body> </html> // -- 上传文件 -- var synchronizeFile = function(id) { console.log("开始同步文件:" + id); }; var proxySynchronizeFiles = (function() { var fileCache = [], timer; return function(id) { fileCache.push(id); if(timer) { return; } timer = setTimeout(function() { synchronizeFile(fileCache.join(",")); clearTimeout(timer); timer = null; checkArr.length = 0; }, 2000); } })(); var checkArr = document.getElementsByTagName("input"); for(var i = 0, c; c = checkArr[i++];) { c.onclick = function() { if(this.checked == true) { proxySynchronizeFiles(this.id); } } } // ------------ 示例6 ----------------- /* * 【代理模式用处】:缓存代理 * 以计算器为例,比如计算某些数的乘积,当参数重复时,我们希望不用重复计算,直接返回结果。 * 以下用到代理模式做缓存。 */ var mult = function() { if(!arguments) { console.log("请输入参数"); return; } var a = 1; for(var i = 0, b; b = arguments[i++];) { a = a * b; } return a; }; var proxyMult = (function() { var cache = {}; return function() { var str = Array.prototype.join.call(arguments, ","); if(str in cache) { console.log("重复return."); return cache[str]; } return cache[str] = mult.apply(this, arguments); } })(); console.log(proxyMult(2, 3, 4)); console.log(proxyMult(2, 3, 4)); //------------ 示例7 -------------- /* * 缓存代理升级 - 通用版计算 * */ var mult = function() { if(!arguments) { return; } var t = 1; for(var i = 0, a; a = arguments[i++];) { t = t * a; } return t; }; var plus = function() { if(!arguments) { return; } var t = 0; for(var a of arguments) { t += a; } return t; }; var createProxyCaculate = function(fn) { var cache = {}; return function() { var str = Array.prototype.join.call(arguments, ","); if(str in cache) { console.log("重复return" + str); return cache[str]; } return cache[str] = fn.apply(this, arguments); } }; var proxyMult = createProxyCaculate(mult); var proxyPlus = createProxyCaculate(plus); console.log(proxyMult(2, 3, 4)); console.log(proxyMult(2, 3, 4));
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍详解javascript设计模式三:代理模式,包括了详解javascript设计模式三:代理模式的使用技巧和注意事项,需要的朋友参考一下 代理模式是一种对程序对象进行控制性访问的一类解决方案。 引入代理模式,其实是为了实现单一职责的面向对象设计原则。 单一职责其实就是指在一个类中(js中通常指对象和函数等),应仅有一个引起它变化的原因。这样会帮助程序设计具有良好的健壮和高内聚特性,从
介绍 代理,顾名思义就是帮助别人做事,GoF对代理模式的定义如下: 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。 代理模式使得代理对象控制具体对象的引用。代理几乎可以是任何对象:文件,资源,内存中的对象,或者是一些难以复制的东西。 正文 我们来举一个简单的例子,假如dudu要送酸奶小妹玫瑰花,却不知道她的联系方式或者不好意思,想委托大叔去送这些玫瑰,那大叔就是个代理(其实
本文向大家介绍学习JavaScript设计模式之代理模式,包括了学习JavaScript设计模式之代理模式的使用技巧和注意事项,需要的朋友参考一下 明星都有经纪人作为代理。如果请明星办一场商演,只能联系其经纪人,经纪人会把商演的细节和报酬谈好,再把合同交给明星签。 一、定义 代理模式:为一个对象提供一个代用品或占位符,以便控制对它的访问。 代理分为:保护代理和虚拟代理 保护代理:用于控制不同权限的
本文向大家介绍JavaScript设计模式之代理模式介绍,包括了JavaScript设计模式之代理模式介绍的使用技巧和注意事项,需要的朋友参考一下 代理模式说明 说明:顾名思义就是用一个类来代替另一个类来执行方法功能,这个模式跟装饰模式有点相似,不一样的是,代理模式是代替客户初始化被代理对象类,而装饰模式采用接口或初装饰者参数引用的方式来执行的。 在动态面向对象语言里,代理模式即起到控制修饰被代理
本文向大家介绍Python设计模式之代理模式实例详解,包括了Python设计模式之代理模式实例详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python设计模式之代理模式。分享给大家供大家参考,具体如下: 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问 运行结果: jiaojiao 送你洋娃娃 jiaojiao 送你花 jiaojiao 送你巧克
本文向大家介绍C++设计模式之代理模式,包括了C++设计模式之代理模式的使用技巧和注意事项,需要的朋友参考一下 前言 青春总是那样,逝去了才开始回味;大学生活也是在不经意间就溜走了,现在上班的时候,偶尔还会怀念大学时,大家在一起玩游戏的时光。大学喜欢玩游戏,但是可悲的校园网,速度能把人逼疯了;还好,后来搞了一个游戏代理,总算能勉勉强强的玩了两年。时至今日,敲起键盘写设计模式的时候,又想起了那些美好