代理模式
1. 介绍
- 使用者无权访问目标的对象
- 中间加代理,通过代理做授权和控制
2. UML 演示

3. 代码演示
class RealImg {
constructor(fileName) {
this.fileName = fileName
this.loadFromDisk()
}
display() {
console.log('display...' + this.fileName)
}
loadFromDisk() {
console.log('loading...' + this.fileName)
}
}
class ProxyImg {
constructor(fileName) {
this.realImg = new RealImg(fileName)
}
display() {
this.realImg.display()
}
}
let proxy = new ProxyImg('1.png')
proxy.display()
4. 场景
4.1 网页事件代理
<div id="div1">
<a href="#">a1<a/>
<a href="#">a2<a/>
<a href="#">a3<a/>
<a href="#">a4<a/>
<a href="#">a5<a/>
</div>
<script>
var div1 = document.getElementById('div1')
div1.addEventListener('click',function(e){
var target = e.target
if(target.nodeName === 'A'){
alert(alert.innerHTML)
}
})
</script>
4.2 jQuery $.proxy
$('div').click(function() {
var _this = this
setTimeout(function() {
$(_this).addClass('red')
}, 1000)
})
$('div').click(function() {
setTimeout(
$.proxy(function() {
$(this).addClass('red')
}, this),
1000
)
})
4.3 ES6 Proxy
let star = {
name: '朱攀',
age: 21,
phone: 'starPhone: 13007142502'
}
let agent = new Proxy(star, {
get: function(target, key) {
if (key === 'phone') {
return 'agentPhone: 11008888'
}
if (key === 'price') {
return '经纪人报价:' + 10000 + '元'
}
return target[key]
},
set: function(target, key, val) {
if (key === 'customPrice') {
if (val < 10000) {
throw new Error('价格太低')
} else {
target[key] = val
return true
}
}
}
})
console.log(agent.name)
console.log(agent.age)
console.log(agent.phone)
console.log(agent.price)
agent.customPrice = 10000
console.log('客户报价:', agent.customPrice + '元')
5. 设计原则
- 代理类和目标类分离,隔离开目标类和使用者
- 符合开放封闭原则
6. 模式对比
6.1 代理模式 vs 适配器模式
- 适配器模式:提供一个不同的接口
- 代理模式:提供一模一样的接口
6.2 代理模式 vs 适装饰器模式
- 装饰器模式:拓展功能,原有功能不变且可直接使用
- 代理模式:可使用原有功能,但是被限制