代理模式是為一個(gè)對(duì)象提供一個(gè)代用品或占位符,以便控制對(duì)它的訪(fǎng)問(wèn)睛驳。
例子一 圖片預(yù)加載
var myImage = (function(){
var imgNode = document.createElement('img');
imgNode.className = '123';
document.body.appendChild(imgNode);
return {
setSrc : function(src){
imgNode.src = src;
}
}
})();
var proxyImage = (function(){
var img = document.createElement('img');
img.onload = function(){
console.log(this);//這里的this,指向的是上面創(chuàng)建的img撬讽,不是imgNode
myImage.setSrc(this.src);
}
return {
setSrc : function(src){
myImage.setSrc('http://o8kanx15h.bkt.clouddn.com/0.jpg');
img.src = src;
}
}
})();
proxyImage.setSrc('http://o8kanx15h.bkt.clouddn.com/octoliberty.png');
下面是不使用代理模式
var myImage = (function(){
var imgNode = document.createElement('img');
imgNode.className = '123';
document.body.appendChild(imgNode);
var img = new Image;
img.onload = function(){
imgNode.src = img.src;
}
return {
setSrc : function(src){
imgNode.src = 'http://o8kanx15h.bkt.clouddn.com/0.jpg';
img.src = src;
}
}
})();
myImage.setSrc('http://o8kanx15h.bkt.clouddn.com/octoliberty.png');
那么為什么要使用代理模式呢,這么小的功能貌似不用模式也能實(shí)現(xiàn)叠萍,原因有下面幾點(diǎn)
- 單一職責(zé)原則:就一個(gè)類(lèi)來(lái)說(shuō),應(yīng)該僅有一個(gè)引起它變化的原因渡讼。如果一個(gè)對(duì)象承擔(dān)了多項(xiàng)責(zé)任骂束,就意味著對(duì)象將變得巨大,引起它變化的原因可能會(huì)有多個(gè)成箫。如果一個(gè)對(duì)象承擔(dān)的職責(zé)過(guò)多展箱,等于把這些職責(zé)耦合到了一起,這種耦合會(huì)導(dǎo)致脆弱和低內(nèi)聚的設(shè)計(jì)蹬昌。
- 可能會(huì)違反開(kāi)放-封閉原則混驰。如果我們需要加載的圖片很小,或許以后網(wǎng)速快到不用預(yù)加載了皂贩,我們可能希望刪掉預(yù)加載的功能栖榨,這個(gè)時(shí)候,我們就不得不去更改myImage里面的代碼了明刷。
實(shí)際上婴栽,我們需要的只是給img節(jié)點(diǎn)設(shè)置src,預(yù)加載只是一個(gè)錦上添花的功能辈末。這里把預(yù)加載功能放到另一個(gè)對(duì)象里(代理)愚争。這個(gè)時(shí)候,代理負(fù)責(zé)預(yù)加載挤聘,預(yù)加載成功后轰枝,把請(qǐng)求重新交給本體myImage
例子二 計(jì)算乘積
var mult = function(){
console.log('開(kāi)始');
var a = 1;
for(var i = 0,l = arguments.length;i < l; i++){
a = a * arguments[i];
}
return a;
};
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);//開(kāi)始 24
proxyMult(1,2,3,4);//24