js --代理模式

定义:

代理模式:为一个对象找一个替代对象,以便对原对象进行访问。在我的理解钟,代理就类似于第三方,比如,电视剧中的某大亨出现意外情况的时候,基本都会让律师全权代理,不会直接和大亨进行沟通,律师所做的事情就可以理解为代理模式。还有就是代购这个职业,比如我们因为各种原因不能出国去购买某种化妆品,这时候,代购的作用就显而易见了,她可以代替你出国去购买你所需要的东西,而你不需要出国。这也是符合代理模式的。

在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介作用。

使用代理的原因是我们不愿意或者不想对原对象直接进行操作。

先来一个简单的例子,代购买化妆品的例子

// 化妆品类
var cosmetic = function(name) {
    this.name = name;
}
cosmetic.prototype.getName = function() {
    return this.name;
}
// 定义不能出国的人
var people =  {
    buyCosmetic: function(name) {
        console.log('请帮我代购'+ name)
    }
}
// 定义代购对象
var purchasing = {
    buyCosmetic: function(cosmetic) {
        people.buyCosmetic(cosmetic.getName())
    }
}
purchasing.buyCosmetic(
new cosmetic('口红'))

ES6所提供Proxy构造函数能够让我们轻松的使用代理模式:

var proxy = new Proxy(target, handler);

Proxy构造函数传入两个参数,第一个参数target表示所要代理的对象,第二个参数handler也是一个对象用来设置对所代理的对象的行为。如果想知道Proxy的具体使用方法,可参考阮一峰的《 ECMAScript入门 - Proxy 》

 

虚拟代理:是把一些开销很大的对象,延迟到真正需要它的时候才去创建执行

我们在浏览一些购物商城的时候,会发现,当网络不太好的情况下,有些图片是加载不出来的,会有暂无图片的一张图片去代替它实际的图片,等网路图片加载完成之后,暂无图片就会被实际的图片代替。这就是使用的图片的懒加载。图片的懒加载也可是使用虚拟代理的模式来进行设计。

    // 图片懒加载
    var myImage = (function(){
        var imgNode = document.createElement('img')
        document.body.appendChild( imgNode)
        return {
            setSrc: function(src) {
                imgNode.src =src
            }
        }
    }
)();
var proxyImage = (function() {
    var img = new Image;
    img.onload = function() {
        myImage.setSrc(this.src)
    }
    return {
        setSrc: function(src) {
            console.log('src', src)
            myImage.setSrc('http://seopic.699pic.com/photo/40007/8839.jpg_wh1200.jpg');
            img.src = src;
        }
    }
})();
proxyImage.setSrc('http://seopic.699pic.com/photo/40006/7735.jpg_wh1200.jpg')

缓存代理::可以作为一些开销大的运算结果提供暂时的存储,下次运算时,如果传递进来堵塞参数跟之前一致,则可以直接返回前面存储的运算结果。

例如,前后端分离,向后端请求分页的数据的时候,每次页码改变时都需要重新请求后端数据,我们可以将页面和对应的结果进行缓存,当请求同一页的时候,就不再请求后端的接口而是从缓存中去取数据。

 

const getFib = (number) => {
  if (number <= 2) {
    return 1;
  } else {
    return getFib(number - 1) + getFib(number - 2);
  }
}

const getCacheProxy = (fn, cache = new Map()) => {
  return new Proxy(fn, {
    apply(target, context, args) {
      const argsString = args.join(' ');
      if (cache.has(argsString)) {
        // 如果有缓存,直接返回缓存数据        console.log(`输出${args}的缓存结果: ${cache.get(argsString)}`);
        
        return cache.get(argsString);
      }
      const result = fn(...args);
      cache.set(argsString, result);

      return result;
    }
  })
}
const getFibProxy = getCacheProxy(getFib);
getFibProxy(40); // 102334155getFibProxy(40); // 输出40的缓存结果: 102334155

使用场景:

 代理模式的类型较多,不同类型的代理模式有不同的优缺点,它们应用于不同的场合:

       (1) 当客户端对象需要访问远程主机中的对象时可以使用远程代理。

       (2) 当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理,例如一个对象需要很长时间才能完成加载时。

       (3) 当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理。通过使用缓冲代理,系统无须在客户端每一次访问时都重新执行操作,只需直接从临时缓冲区获取操作结果即可。

       (4) 当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限时可以使用保护代理。

       (5) 当需要为一个对象的访问(引用)提供一些额外的操作时可以使用智能引用代理。

优缺点:

优点:代理模式能够将代理对象与被调用的对象分离,降低了系统的耦合度。代理模式在客户端和目标对象之间起到一个中介作用,这样,可以起到保护目标对象的作用。代理对象也可以对目标对象调用之前进行其他的操作。

缺点:; 增加系统的复杂度

posted @ 2019-06-15 18:48  栀子花编织着留恋  阅读(2433)  评论(0编辑  收藏  举报