代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。
保护代理
对象的访问控制逻辑不应该在该对象内部,该对象应该是对外界完全开放的,但是如果需要对该对象进行访问限制,借助的就是保护代理。保护代理来控制外界对被保护对象的操作。
虚拟代理
一些开销很大的操作,经过虚拟代理,延迟到真正需要时才被创建。这些操作就和无关的逻辑,如判断何时进行对象创建解耦了。
在js中,保护代理不易被实现,因为无法判断谁访问了哪个对象。
代理的意义,单一职责原则。该设计模式使用的场景相当的多。
在react中,使用高阶组件可以来拆分组件逻辑:
function ppHOC(WrappedComponent) {
return class PP extends React.Component {
render() {
return <WrappedComponent {...this.props}/>
}
}
}
// 当然也可以写成Function的形式
function hoc(WComponent){
return function(props){
return <WComponent {...props} />
}
}
虽然但是,高阶组件这个不一定叫代理模式。
注意保持代理和本体接口的一致性,
- 无成本请求代理和更换代理或者不用代理。
- 无成本从请求本体切换为请求代理。
合并同类的频繁请求
上面代码相当于是节流的变形应用var syncFile=function(id){
console.log('同步')
}
var proxySyncFile=(function(){
var cache=[]
var timer
return function(id){
cache.push(id)
if(timer) return
timer=setTimeout(()=>{
syncFile(cache.join(','))
clearTimeout(timer)
timer=null
cache.length=0
},2000)
}
})()
function throttle(fn,gap){
var timer=null
return function(...args){
if(timer) return
timer=setTimeout(()=>{
fn(...args)
timer=null
},gap)
}
}
缓存代理
也可以对异步ajax请求进行缓存,避免对请求过的再次缓存var proxyMult=(function(){
var cache={}
return function(){
var args=Array.prototype.join.call(arguments,',')
if(args in cache){
return cache[args]
}
return cache[args]=mult.apply(this,arguments)
}
})()
// 类似于求菲波那切数列,缓存已经求过的值,算法降低复杂度
检查知衣项目发现并没有对翻页做缓存。var createProxyFactory=function(fn){
var cache={}
return function(...args){
var key=args.join(',')
if(args.join(',') in cache){
return cache[key]
}
return cache[key]=fn.apply(this,args)
}
}
小结
在js中,最常用的是虚拟代理和缓存代理,
但是在写业务代码时,不需要预先使用代理模式,真正发现有需求时再编写代理。