代理模式是为一个对象提供一个替代品或者占位符,以便控制对他的访问。
当客户不方便直接访问或者不满足条件访问一个对象的时候,提供一个替身对象来控制对这个对象的访问。
客户 ——>本体
客户——>代理——>本体
保护代理
代理可以帮助本体过滤一些不满足条件的访问者,代理可以直接拒绝这些访问者,以便保护本体
代理模式的用途
图片预加载(虚拟代理)
let myImage = (function() {
let imgNode = document.createElement('img')
document.body.appendChild(imgNode)
return {
setSrc: function(src) {
imgNode.src = src
}
}
})()
let proxyImage = (function() {
let img = new Image
img.onload = function() {
myImage.setSrc(this.src)
}
return {
setSrc: function(src) {
myImage.setSrc('localimg')
img.src = src
}
}
})()
proxyImage.setSrc('inter img')
在引入代理之后,可以在图片加载完成之前设置预加载图片。myImage
负责给图片设置src
,proxyImage
负责预加载图片,这样保证了函数的单一职责。降低了函数耦合。如果以后有需求发生变化我们不需要直接改动myImage
中的代码,不需要改动myImage
的接口,只需要改变代理函数中的代码,没有违背开放——封闭原则。
虚拟代理合并HTTP请求
在web开发很多时候会和网络打交道,最大的开销也是网络请求。比如当我们点击按钮后要向后台提交文件,如果我们一直不停的点击就会造成频繁的网络请求带来巨大的开销。为了解决这个问题,我们引入一个代理函数来收集一段时间的请求,然后合并一起发送。
let send = (id) => {
conslog.log(id)
}
let proxy = (function() {
let cache = [] // 保存需要发送的文件
let timer
return function (id) {
cache.push(id)
if(timer) return
timer = setTimout(function() {
send(cache)
clearTimout(timer)
timer = null
cache = []
},2000)
}
})
使用缓存代理
let mult = function(...arg) {
let a = 1
for(let i = 1; i < arg.length; i++) {
a = a * arg[i]
}
return a
}
// 加入缓存代理函数
let proxyMult = (function() {
let cache = {}
return function() {
}
})