JavaScript设计模式_03_代理模式
代理模式是非常常见的模式,比如我们使用的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设计模式_03_代理模式的更多相关文章
- JavaScript设计模式之代理模式
一.代理模式概念 代理,顾名思义就是帮助别人做事,GoF对代理模式的定义如下: 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问.代理模式使得代理对象控制具体对象的引用.代理几乎可 ...
- JavaScript 设计模式之代理模式
一.代理模式概念解读 1.代理模式概念文字解读 代理,顾名思义就是帮助别人做事,GOF对代理模式的定义如下: 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问.代理模式使得代理对象 ...
- 第三章 --- 关于Javascript 设计模式 之 代理模式
第一.定义: 代理模式是为一个对象提供代用品或者占位符,以便控制对它的访问. 比如说,某男生小明想向他的女神 A 表白,刚好小明认识的一个女生B 和 女神A 是好朋友,那么小明就想让 女生B 帮忙送花 ...
- 学习javascript设计模式之代理模式
1.代理模式为一个对象提供一个代用品或占位符,以便控制对它的访问. 2.不用代理模式: 客户 -> 本体 使用代理模式: 客户 -> 代理 -> 本体 3.例子场景1 点击操作与 ...
- JavaScript设计模式(代理模式)
一.简单的单例模式: 1.未使用代理模式的情况:小明直接给女神送花 var Flower = function() {} var xiaoming = { sendFlower: function( ...
- JavaScript设计模式-19.代理模式
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- C#设计模式(13)——代理模式(Proxy Pattern)
一.引言 在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访问到这些对象,如果直接访问对象给系统带来不必要的复杂性,这时候可以在客户端和目标对象之间增加一层中间层,让代 ...
- 乐在其中设计模式(C#) - 代理模式(Proxy Pattern)
原文:乐在其中设计模式(C#) - 代理模式(Proxy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 代理模式(Proxy Pattern) 作者:webabcd 介绍 为 ...
- JavaScript设计模式之----组合模式
javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...
随机推荐
- 149_best-time-to-buy-and-sell-stock
/*@Copyright:LintCode@Author: Monster__li@Problem: http://www.lintcode.com/problem/best-time-to-b ...
- C#数据结构之串
串(string)是n(n>=0)个字符组成的有限序列. 由于串中的字符都是连续存储的,在C#中有恒定不变的特性.一经创建就保持不变. 为了区别C#中的string,因此以stringDS类模拟 ...
- 单片机下载芯片max232,ch340,pl2303,hl340与下载接线
开发板上的下载口位置一般都有很多 340,232等芯片,这些芯片都是干嘛用的呢? 普及:TTL电平 : 二进制电平,+5V等价于逻辑"1",0V等价于逻辑"0&qu ...
- HashMap 构造函数
HashMap总共提供了三个构造函数 /** * Constructs an empty <tt>HashMap</tt> with the default initial c ...
- selenium IDE的3种下载安装方式
第一种方式: 打开firefox浏览器-----点击右上角-----附加组件----插件----搜索框输入“selenium”-----搜索的结果中下拉到页面尾部,点击“查看全部的37项结果”---进 ...
- js正则表达式详解
一.正则的两种写法: var re = /a/; //一般情况下都用简写的方式 性能好 var re = new RegExp('a'); //需要传入参数的时候用 二.转义字符: \n 换行 \r ...
- 用Redis存储Tomcat集群的Session
作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 前段时间,我花了不少时间来寻求一种方法,把新开发的代码推送到到生产系统中部署,生产系统要能够零宕机.对使用 ...
- SVN常见问题总结一
注意 转载须保留原文链接(http://www.cnblogs.com/wzhiq896/p/6828776.html ) 作者:wangwen896 SVN是Subversion的简称,是一个开放 ...
- css 3d 基础知识
css3d 总结 3d transform (3D变形)(rotate skew scale translate) 基础知识 perspective (视距,景深) perspective-origi ...
- MySQL 闪回工具之 binlog2sql
生产上误删数据.误改数据的现象也是时常发生的现象,作为 DBA 这时候就需要出来补锅了,最开始的做法是恢复备份,然后从中找到需要的数据再进行修复,但是这个时间太长了,对于大表少数数据的修复来讲,动作太 ...