代理模式
2018-09-26 本文已影响0人
月离丶
为一个对象提供一个代用品或者占位符,以方便控制对它的访问。
客户->代理->本体
让我们举个例子,在淘宝、京东等电商还没发达起来的时候,我们要往手机里充话费的时候,会找家专门充话费的营业点,付钱让他们帮忙充值。营业点就是代理。
代理类型:
- 虚拟代理:会将一些开销比较大的对象或者行为延迟到真正需要它的时候再执行。比如说 ,当我们要上传文件的时候,我们将文件一个个上传,会给网络带来很大的开销,但是如果我们将一定时间内上传的文件缓存起来,一次性上传,就可以节省很大的性能,将一定时间内上传的文件缓存起来的对象就是虚拟代理
- 保护代理:代理会替本体过滤掉一些请求,比如,明星的经纪人会替明星推掉一些上不得台面或者没有价值的通告。
单一职责原则 最小知识原则 封闭开放原则
代理和本体的接口要保持一致性,比如小明让B替他向女神A送玫瑰花,代理B和女神A都有一个收玫瑰花的接口。
代理接收请求的过程对用户来说是透明的,女神A不需要知道B是怎么接收小明的这个请求,是因为小明请他吃了顿饭还是喝了杯下午茶什么的。这样的话,在任何使用本体的地方都可以替换成代理,B可以替小明送玫瑰花,还可以替小刚、小松送玫瑰花。
注意:若代理对象和本体对象都是一个函数,那么就认为它们具有相同的接口。
代理使用的场景:
- 缓存运算:比如加减乘除,计算图形面积甚至一些开销比较大的运算,代理可以将计算结果缓存起来,只要下次请求是同样的参数,就直接将缓存结果返回
- 合并HTTP请求:如上面的例子,将一段时间内的文件上传缓存起来一次性向服务器发送请求
- 缓存HTTP请求:比如请求的是同一个活动id的活动详情,可以直接通过代理返回,不需要向服务器再次发送请求
- 图片懒加载:在要加载的图片还未加载成功时,可以通过代理先放置一张占位符图片,等图片加载成功后,替换掉占位符图片
例子:缓存计算结果
//缓存代理 ,存储方法的返回结果
var createProxyFactory:any = function(fn:any) {
var cache:any = {}
return function () {
var args:string = Array.prototype.join.call(arguments,',')
if(args in cache) {
return cache[args]
}
return cache[args] =fn.apply(this, arguments);
}
}
var mult = function () {
var a = 0
for(var i = 0,l = arguments.length;i<l;i++){
a = a + arguments[i]
}
return a
}
var proxyMult = createProxyFactory(mult)
proxyMult(1,2,3,5)
proxyMult(1,2,3,5)
例子:图片懒加载
//本体
var myImage = (function() {
var imgNode = document.createElement('img')
document.body.appendChild(imgNode)
return function (src:string) {
imgNode.src = src
}
}
)()
//代理:负责实际图片加载成功前,加载占位图片
var proxyImage = (function () {
var image = new Image()
image.onload = function () {
myImage(image.src)
}
return function (src:string) {
myImage('loading.png')
image.src = src
}
})()