设计模式-代理模式
举个例子,如果想请明星来办一场商业演出,你是无法直接联系到本人的,只能联系他的经纪人(明星本人的时间比较宝贵),经纪人会把商业演出的细节和报酬都谈好之后,再把合同交给明星签,经纪人就是代理。在程序中,代理可以看做是一个对象,这个对象是一个占位符
虚拟代理
在Web开发中,也许最大的开销就是网络请求。假设我们在做一个文件同步的功能,当我们选中一个 checkbox 的时候,它对应的文件就会被同步到另外一台备用服务器上面,如图所示
一般的做法是先获取到所有的checkbox,然后给他们绑定点击事件,并且在点击的同时往另一台服务器同步文件,这种做法有什么问题?如果用户在2s内选中了4个文件,需要向服务器发送4次HTTP请求,如此频繁的网络请求将会带来相当大的开销。
解决方案是,我们可以通过一个代理函数proxySynchronousFile来收集一段时间之内的请求,最后一次性发送给服务器
<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
var synchronousFile = function(id) {
console.log('开始同步文件,id 为: ' + id);
};
var proxySynchronousFile = (function() {
var cache = [], // 保存一段时间内需要同步的 ID
timer; // 定时器
return function(id) {
cache.push(id);
if (timer) { // 保证不会覆盖已经启动的定时器
return;
}
timer = setTimeout(function() {
synchronousFile(cache.join(',')); // 2 秒后向本体发送需要同步的 ID 集合
clearTimeout(timer);
timer = null;
cache.length = 0;
}, 2000);
}
})();
var checkbox = document.getElementsByTagName('input');
for (var i = 0, c; c = checkbox[i++];) {
c.onclick = function() {
if (this.checked === true) {
proxySynchronousFile(this.id);
}
}
};
缓存代理
缓存代理可以为一些开销大的运算结果提供暂时的存储,在下次运算时,如果传递进来的参
数跟之前一致,则可以直接返回前面存储的运算结果
下面用计算乘积的例子演示如何使用缓存代理,实际开发中应该是开销较大的运算,这里仅作演示
// 计算乘积
var mult = function() {
console.log('开始计算乘积');
var a = 1;
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, ','); // '1,2,3,4'
if (args in cache) {
return cache[args];
}
// {'1,2,3,4': 24}
return cache[args] = fn.apply(this, arguments);
}
};
var proxyMult = createProxyFactory(mult);
console.log(proxyMult(1, 2, 3, 4));
console.log(proxyMult(1, 2, 3, 4));
代理模式的变体种类非常多,比较常用的是虚拟代理和缓存代理,其他还有防火墙代理、远程代理、保护代理、智能引用代理和写时复制代理
胖胖熊笔记,笔记已迁移