代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。

保护代理

对象的访问控制逻辑不应该在该对象内部,该对象应该是对外界完全开放的,但是如果需要对该对象进行访问限制,借助的就是保护代理。保护代理来控制外界对被保护对象的操作。

虚拟代理

一些开销很大的操作,经过虚拟代理,延迟到真正需要时才被创建。这些操作就和无关的逻辑,如判断何时进行对象创建解耦了。


在js中,保护代理不易被实现,因为无法判断谁访问了哪个对象。
代理的意义,单一职责原则。该设计模式使用的场景相当的多。
在react中,使用高阶组件可以来拆分组件逻辑:

  1. function ppHOC(WrappedComponent) {
  2. return class PP extends React.Component {
  3. render() {
  4. return <WrappedComponent {...this.props}/>
  5. }
  6. }
  7. }
  8. // 当然也可以写成Function的形式
  9. function hoc(WComponent){
  10. return function(props){
  11. return <WComponent {...props} />
  12. }
  13. }

虽然但是,高阶组件这个不一定叫代理模式。
注意保持代理和本体接口的一致性

  1. 无成本请求代理和更换代理或者不用代理。
  2. 无成本从请求本体切换为请求代理。

    合并同类的频繁请求

    1. var syncFile=function(id){
    2. console.log('同步')
    3. }
    4. var proxySyncFile=(function(){
    5. var cache=[]
    6. var timer
    7. return function(id){
    8. cache.push(id)
    9. if(timer) return
    10. timer=setTimeout(()=>{
    11. syncFile(cache.join(','))
    12. clearTimeout(timer)
    13. timer=null
    14. cache.length=0
    15. },2000)
    16. }
    17. })()
    上面代码相当于是节流的变形应用
    1. function throttle(fn,gap){
    2. var timer=null
    3. return function(...args){
    4. if(timer) return
    5. timer=setTimeout(()=>{
    6. fn(...args)
    7. timer=null
    8. },gap)
    9. }
    10. }

    缓存代理

    1. var proxyMult=(function(){
    2. var cache={}
    3. return function(){
    4. var args=Array.prototype.join.call(arguments,',')
    5. if(args in cache){
    6. return cache[args]
    7. }
    8. return cache[args]=mult.apply(this,arguments)
    9. }
    10. })()
    11. // 类似于求菲波那切数列,缓存已经求过的值,算法降低复杂度
    也可以对异步ajax请求进行缓存,避免对请求过的再次缓存
    检查知衣项目发现并没有对翻页做缓存。
    1. var createProxyFactory=function(fn){
    2. var cache={}
    3. return function(...args){
    4. var key=args.join(',')
    5. if(args.join(',') in cache){
    6. return cache[key]
    7. }
    8. return cache[key]=fn.apply(this,args)
    9. }
    10. }

    小结

    在js中,最常用的是虚拟代理和缓存代理,
    但是在写业务代码时,不需要预先使用代理模式,真正发现有需求时再编写代理。