# 设计模式——代理模式
提到代理,我们可能想到的是代理人。在生活中代理人最多的可能就是明星了,每个明星都有自己的代理人,我们找明星合作通常都是先接触代理人,然后才接触明星。也就是说这个代理人是在我们和明星之间进行了一次拦截,筛选出符合见明星的人。其实代理模式在开发中也是这样,只不过这里代理的是对象,而不是明星,通过为对象提供一个代理,用来控制对这个对象的访问。
# 代理模式定义:
为对象提供一个代理,用来控制对这个对象的访问。
下面以具体代码举例:比如公司的个人信息的访问:
let person = {
id = '1',
name = '刘亦菲',
age:30
}
console.log(person.name)
上面定义了一个包含个人信息的对象person,如果没有进行代理,那么可以直接通过person.xx进行访问。但是,事实上我们不希望个人信息被查看,只有本人能够进行查看和修改。那么这时候我们可以对对象的访问添加代理。 具体代码如下:
let info = (function(){
let person = {
id:1,
name:'刘亦菲',
age:24,
job:'teacher'
}
return function({id}){
//代理对象
let handle = {
get:function(target,key){
if(key === 'age'){
if(id === 1){
return Reflect.get(target,key)
}else{
throw new Error('您没有权限查看该信息')
}
}
},
set:function(target,key,value){
if(id === 1){
return Reflect.set(target,key,value)
}else{
throw new Error('您没有权限修改个人信息')
}
}
}
return new Proxy(person,handle)
}
})()
let star = info({id:1})
console.log(star.age)
star.age = 30;
console.log(star.age)
通过使用new Proxy(target,handle)
来进行代理。其中target
为被代理对象,handle
为代理对象或者说拦截对象。在handle
中我们通过定义get
和set
函数来进行拦截,只有id
为1
的人才能查看自己的个人信息。这就是代理模式。
# 代理模式的应用场景:
上面的例子只是简单的代理对象的访问,其实代理更多的时候是用于控制开销很大的对象的访问。比如,一个创建实例开销很大的访问,它会把创建实例放到方法被调用的时候(也就是真正需要被用到的时候),因为如果整个程序运行期间都没有用到这个对象,那么就不需要创建它,这样可以大大节省资源。比如图片的延迟加载,我们并不需要一开始就加载所有的图片,而是使用一张loading图片来代替它们,只有在真正需要展示这张图片的时候,再替代掉src即可。
# 代理模式的总结:
归功接底代理模式就是控制对对象的访问,无论是拦截访问,还是延迟访问都是对对象访问的控制罢了。如果你要访问一个对象,但是你不想马上访问,或者不想直接访问那么这都是代理模式。