代理模式的定义:当一个请求想要访问一个原始对象A的时候,实际访问的是A的代理对象B,由对象B对请求做出一些处理之后,在把请求转交给原始对象A。
案例一( 一般代理模式 )
场景:某一天小明数学考试考了50分,这时候如果老师直接把试卷给到父亲的手里,那小明怕是免不了一顿毒打;那如果老师把试卷给了小明,小明再回家给到父亲,那小明是不是可以在给父亲之前改一下自己的分数呢?
在这个过程中:
- 老师把试卷给父亲:原始请求
- 小明:代理对象
- 父亲:原始对象
试卷经过小明这个代理对象的处理之后交给父亲,小明的分数就可以变成100?,下面模拟一下这个过程
var teacher = {
sendGrade: function( target ) {
let grade = 50;
console.log( '老师给小明的分数是' + grade + '分' );
target.receiveGrade( grade );
}
}
var xiaoMing = {
receiveGrade: function( grade ) {
grade = grade + 50;
father.receiveGrade( grade );
}
}
var father = {
receiveGrade: function( grade ) {
console.log( '父亲看到儿子的分数是' + grade + '分' );
}
}
teacher.sendGrade( xiaoMing );
// 老师给小明的分数是50分
// 父亲看到儿子的分数是100分
案例二( 缓存代理模式 )
场景:我们用相加求和来模拟一个请求商城商品的过程。假设我们的商城有三类商品:分别是家具类、食品类、电子类,那么我们第一次请求的时候请求了电子类商品的数据,那么是不是可以把数据缓存到本地,下次在请求的时候是不是可以不用去请求接口了,而是直接在本地来取出第一次请求的数据来使用呢?如果我们的用户量是100万,那可能每五分钟就减少了服务端100万次的访问压力( 这里不考虑数据变化的因素 )
假设:
- 1 + 1 = 2 ------ 2 代表家具类商品;1 + 1 代表请求体
- 2 + 2 = 4 ------ 4 代表食品类商品;2 + 2 代表请求体
- 3 + 3 = 6 ------ 6 代表电子类商品;3 + 3 代表请求体
下面来实现一下这个过程:
// 用相加代表请求过程
var plus = function() {
let sum = 0;
for ( let i = 0; i < arguments.length; i++ ) {
sum = sum + arguments[i];
}
console.log( 'plus执行了' );
return sum;
}
var proxyPlus = (function(){
let cache = {}; // 缓存请求的数据
return function() {
let args = Array.prototype.join.call( arguments, ',' );
if ( args in cache ) {
return cache[ args ];
}
let data = plus.apply( this, arguments );
cache[ args ] = data;
return cache[ args ];
}
})();
proxyPlus( 1, 1 ); // plus执行了
proxyPlus( 1, 1 );
虽然我们执行了两次同样的请求,但是我们会发现 ‘plus执行了’ 只打印了一次,因为我们的缓存代理会首先查看cache里面有没有本次请求的数据,发现有就直接返回回来了,没有的话再去请求
总结:代理模式的思想就是这样,在请求到达真正的目标对象之前设置一层代理,代理层可以先处理一下,再转交给请求的目标对象