这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战
介绍
本期我们来聊聊代理模式,它主要为了解决在直接访问对象时带来的问题,有时候目的也不同有的是为了更方便的比如我们Windows系统里面的桌面快捷方式,有的是为了安全的比如防火墙代理。本身代理模式在程序中算是一种极为常见的模式。
举个栗子吧,粉丝追星的时候往往要求明星给自己签字,心情特别的激动,你也签我也签,如果粉丝特别多,那么这个明星一天什么事都不用干了光给粉丝签字就行了。结果,明星就想了个办法,我忙不过来就找个助理吧,如果我没时间了跟他说一声,粉丝的卡片就递不过来了,他就把粉丝给拦住了。这里那个助理就是来完成代理明星,收取卡片要求签字的业务,来解决明星的签字焦虑问题。
概念
代理模式是一种结构型模式。表现形式往往是一个类代表另一个类的功能,以便为其他对象提供一种代理以控制对这个对象的访问。
案例
接下来,就是要实现一下我们刚才栗子里的追星代理业务吧。
var fans = {
name:"粉丝",
sendCard:function(target){
console.log(this.name + ":请求签字")
target.receiveCard();
}
}
var star = {
name:"明星",
receiveCard:function(){
console.log(this.name + ":完成签字")
}
}
var agent = {
name:"代理",
receiveCard:function(){
if(window.confirm("是否有空签字?")){
console.log(this.name + ":递交给"+ star.name)
star.receiveCard();
}
else{
console.log(this.name + ":抱歉!"+ star.name +"没有时间~")
}
}
}
这里我们让fans发出签字的请求给目标,让目标接收请求,完成签字。这里用agent为star做了代理,保护了star免受打扰。
fans.sendCard(agent)
如果有空就签字:
没空就不签字了:
现在看出来这个代理的好处了,在这个业务中的作用就是过滤掉一些请求,保护star对象。
ES6中的代理
ES6 原生提供 Proxy 构造函数,可以生成 Proxy 实例,完成代理。
var jsmask = new Proxy({}, {
get: function(target, propKey) {
return "jsmask";
}
});
jsmask.name // jsmask
jsmask.name = 'superman' // superman
jsmask.name // jsmask
兼容性方面,pc端的IE系列又全军覆没了,移动端安卓低版本也是不太行。
本期目的是讲述代理模式的意图,至于proxy详细的使用可以看阮一峰的ES6入门教程。
结语
看了刚才的栗子,代理模式远远不止这些,比如可以做缓存代理,保护代理,写时复制代理等等,写法也有非常多,但形式都是加增加中间层,来解决直接访问对象时带来的问题。也不难发现它的好处就是,职责清晰还有较好的扩展性。当然缺点也很明显,就是因为出现了中间层,处理要做一些额外的工作,而且其处理速度肯定会比之前要慢。