代理模式的关键是:当客户不方便直接访问一个对象或不满足需求的时候,提供一个替身对象来控制这个对象的访问,客户实际上访问的是替身对象。替身对象对请求做出一系列的处理之后,再把请求交给本体对象。
代理模式的例子下面的代码我们通过举例子的方式来进行具体的阐述:
我们就以Tony追求Kristen来举一个例子:具体是这样的Tony在某天某地遇到了她心中的百分百女神Kristen,两天之后,Tony决定送给Kristen一束花,刚好Tony打听到了Kristen和他有一个共同的好友kelly。于是Tony决定委托kelly来代替自己完成送花的举动。现在我们看一下代码,假设Tony没有使用代理模式,而是直接将花送给了Kristen。代码如下:
let Flower = function(){};
let Tony = {
sendFlower: function (target){
let flower = new Flower();
target.receiveFlower(flower);
}
};
let Kristen={
receiverFlower : function (flower){
console.log('收到花:' + flower);
}
};
Tony.sendFlower (Kristen);
接下来让我们来引入代理kelly,即Tony通过Kelly将花送给了Kristen,那我们现在的操作应该是:
let Flower = function(){};
//客户
let Tony = {
sendFlower: function (target){
let flower = new Flower();
target.receiveFlower(flower);
}
};
//代理
let kelly = {
receiverFlower : function (flower){
A.receiverFlower(flower);
}
};
//主体
let Kristen = {
receiverFlower : function (flower){
console.log('收到花:' + flower);
}
};
Tony.sendFlower (kelly);
我们发现执行的两段代码的执行结果是一样的,至此我们就完成了一个最简单的代理模式的编写,如果代理模式的作用仅仅是这样的,我们完全没有必要引入代理。那么我们引入代理模式,是为了解决什么样的问题呢?我们向下继续走一步,如果代理可以为我们过滤掉某一些条件,那么处理起来是不是就简单多了。比如说,因为kelly和Kristen是很好的朋友,那么kelly就可以检测到什么时候Kristen的心情比较好,当Kristen的心情好的时候,Kristen答应Tony的追求的概率就会大大的增加了,当Kristen心情不好的时候,Tony追去成功的概率就会无限的趋近于0。那么我们现在就可以通过kelly来监听一下Kristen的心情,并在Kristen心情好的时候,选择将花送出去。
let Flower = function(){}
let Tony = {
sendFlower: function(){
let flower = new flower(target);
target.receiverFlower (flower);
}
};
let kelly = {
receiverFlower : function(){
Kristen.listenGoodMood (function(){ //监听Kristen的好心情
Kristen.receiverFlower(flower);
});
}
};
let Kristen = {
receiverFlower : function (flower){
console.log('收到花:' + flower);
},
listenGodMood: function(){
setTimeout(function(){
fn();
},1000);
}
};
Tony.sendFlower (kelly);
这就是引入代理的意义之一,那就是有一些操作,不是不是主体来做,也不是客体来做,而是将这部分的逻辑统一抽出,交给代理来做。这样的话,也有一定的好处,可以减少冗余的代码。
let Tony= {
sendFlower: function (target) {
let flower = new Flower();
taget.goodMood(function () {
target.receiveFlower(flower)
})
}
};
let Ben= {
sendFlower: function (target) {
let flower = new Flower();
taget.goodMood(function () {
target.receiveFlower(flower)
})
}
};
let Adolph = {
sendFlower: function (target) {
let flower = new Flower();
taget.goodMood(function () {
target.receiveFlower(flower)
})
}
};
//这样写代码就会比较重复了,所以我们用个代理这样写
let Tony = {
sendFlower: function (target) {
target.receiveFlower(flower)
}
};
let Ben= {
sendFlower: function (target) {
target.receiveFlower(flower)
}
};
let Adolph = {
sendFlower: function (target) {
target.receiveFlower(flower)
}
};
let kelly= {
receiveFlower: function(flower) {
// 代理接收到花感知到了女神心情好,开始送花
Kristen.goodMood(function () {
let flower = new Flower();
Kristen.receiveFlower(flower);
})
}
};
Tony.sendFlower(kelly);
Ben.sendFlower(kelly);
Adolph.sendFlower(kelly);
在这个程度上面精简了代码,使代码变的简单了。
保护代理
上面是保护代理呢,我们可以看出Kelly可以帮助Kristen过滤到一些不合规定的请求,比如说,Kristen要求他的男朋友必须是年龄较小的,年龄不能超过25岁,这样的请求可以直接在代理里面被拒绝。这种代理被拒绝掉,这样的代理作为保护代理。
let Flower = function() {};
let Tony = {
sendFlower: function (target, condition) {
target.receiveFlower(condition)
}
};
let Ben = {
sendFlower: function (target, condition) {
target.receiveFlower(condition)
}
};
let kelly= {
receiveFlower: function(condition) {
// 代理接收到花感知到了女神心情好,开始送花
if ( condition.age > 25) {
Kristen.reject();
return;
}
Kristen.goodMood(function () {
let flower = new Flower();
Kristen.receiveFlower(flower);
})
}
};
let Kristen= {
receiveFlower: function (flower) {
console.log('收到花了' + flower)
},
reject: function () {
console.log('不接受大叔')
},
goodMood: function (fn) {
setTimeout(function() {
fn() // 假如女神5秒后心情好
}, 5000)
}
}
Tony.sendFlower(daiLi, {age: 23});
Ben.sendFlower(daiLi, {age: 32});
看到这里我们知道了,保护代理其实就是做了一个访问对象的筛选,我们这个时候或许还有一个疑问,我们可以把删选条件写道女神自己的对象里面把,如下:
let Kristen= {
receiveFlower: function (flower, condition) {
if (condition.age > 25) {
console.log('我接受大叔')
} else {
console.log('收到花了' + flower)
}
},
goodMood: function (fn) {
setTimeout(function() {
fn() // 假如女神5秒后心情好
}, 5000)
}
}
// 把条件写在这里看似是没问题的
//但是如果有多个女神都不喜欢大叔怎么
//三个女神还是会重复同样的代码,跟上面情况是一样的
let Flower = function() {};
let Tony= {
sendFlower: function (target, love,condition) {
target.receiveFlower(love, condition)
}
};
let ben = {
sendFlower: function (target, condition) {
target.receiveFlower(condition)
}
};
let kelly= {
receiveFlower: function(love, condition) { // 代理接收到花感知到了女神心情好,开始送花
if ( condition.age > 25) {
love.reject();
return;
}
love.goodMood(function () {
let flower = new Flower();
love.receiveFlower(flower);
})
}
};
let Kristen2= {
receiveFlower: function (flower) {
console.log('收到花了' + flower)
},
reject: function () {
console.log('不接受大叔')
},
goodMood: function (fn) {
setTimeout(function() {
fn() // 假如女神5秒后心情好
}, 5000)
}
}
let Kristen3= {
receiveFlower: function (flower) {
console.log('收到花了' + flower)
},
reject: function () {
console.log('不接受大叔')
},
goodMood: function (fn) {
setTimeout(function() {
fn() // 假如女神5秒后心情好
}, 5000)
}
}
Tony.sendFlower(daiLi, Kristen1, {age: 21});
Ben.sendFlower(daiLi, Kristen2, {age: 30});
我们可以看到了,这样写的话,我们的代码一下子就增加了很多,很多代码重复的写,这样的代码并不是我们想要的样子。
网友评论