一、代理模式
定义
使用者无权访问目标对象,需要通过代理,由代理进行授权、控制。
例子
比如我们可能无法直接获取到某张图片,想要获取他,我们或许只是通过代理获取。
class RealImg {
public fileName
constructor(fileName) {
this.fileName = fileName
}
display() {
console.log('display...' + this.fileName)
}
loadFromDisk() {
console.log('loading...' + this.fileName)
}
}
class ProxyImg {
private realImg
constructor(fileName) {
this.realImg = new RealImg(fileName);
}
display() {
this.realImg.display()
}
}
let proxyImg = new ProxyImg('1.png')
proxyImg.display()
常见场景
1.在本地开发过程中,为了解决跨域问题,所以通过代理服务器转发请求。
2.网页事件代理 将事件代理到dom元素,通过click触发,这正是运用啦代理模式
let div1 = document.getElementById('div1');
div1.addEventListener('click', function(e){
....
})
3.ES6中的Proxy
es6中的proxy可以对对象添加代理,目前vue3和mobx中都运用到了这个新的api
let star = {
name: '七崽',
age: '4个月',
hobby: '跑步',
}
let agent = new Proxy(star, {
get: function(target, key){
if(key === 'food'){
// 返回七崽爱吃的零食
return '苞米';
}
if(key === 'weight'){
// 返回对外公开的体重,七崽也是要面子的
return '100g';
}
return target[key];
},
set: function(target, key, val){
return val
}
})
对比
| 代理模式 | 适配器模式 |
|---|---|
| 提供一模一样的接口 | 提供一个不同的接口 |
| 代理模式 | 装饰器模式 |
|---|---|
| 显示原有功能,但是经过限制或者阉割之后的 | 扩展功能,原有的功能不变且直接可以使用 |
二、外观模式
定义
为子系统中的一组接口提供一个高层接口,使用者使用这个高层接口
例子
function HighInterface(event, value) {
switch(event) {
case 'apply': applyCard(value); break;
case 'getMoney': withdrawMoney(value); break;
}
}
function applyCard(value){
// 申请银行卡
}
function withdrawMoney(value){
// 取钱
}
常见场景
这个模式一般结合业务场景来使用
比如,如果你想去银行办理某些业务,你不是直接去对应的业务区自己办理业务。
而是通过柜员,告诉柜员你所需要办理的业务,由柜员给你办理。
这个过程当中,柜员就充当了高层接口的作用。
设计原则
不符合单一职责和开放封闭原则,因此谨慎使用,不可滥用
该模式有很强烈的业务结合性。