代理模式

2016-10-12 曹强 更多博文 » 博客 » GitHub »

javascript

原文链接 https://ronghuaxueleng.github.io/2016/10/12/JavaScript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E5%BC%80%E5%8F%91%E5%AE%9E%E8%B7%B5-7%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


代理模式是为一个对象提供一个代用品或占位符,以便控制对他的访问。代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个对象来控制这个对象的访问,客户实际上访问的是替身对象。替身对象对请求做出一些处理后再把请求转交给本体对象。

不使用代理:客户 → 本体
使用代理:客户 → 代理 → 本体

先来一个带点趣味性的例子,小明要给女神A送花,然后他不好意思,打算让B代送

var Flower = function(){};
var xiaoming = {
    sendFlower: function( traget ) {
      var flower = new Flower();
      target.receveFlower( flower );
    }
};

var A = {
    receiveFlower: function( flower ) {
      console.log('收到花' + flower);
  }
};

xiaoming.sendFlower(A);

//引入代理B
var B = {
    receiverFlower: function( flower ) {
      A.receiveFlower( flower );
  }
};

此时,我们就简单的完成了一个代理模式

接着,我们在原需求上做点改动,假设女神心情好的时候成功率会增大,小明跟女神不熟不知道她心情,而B跟女神比较熟可以去监听她心情的变化恰当时机送花,这样就不会造成不必要浪费了,于是代码如下:

//代理B
var B = {
    receiverFlower: function( flower ) {
      A.listenGoodMood(function() { //监听A的好心情
        A.receiveFlower( flower );
    });
  }
};

//女神A也要提供一个可被监听的方法(当然我们只是假设,毕竟女人我们是摸不透的)
var A = {
    receiveFlower: function( flower ) {
      console.log('收到花' + flower);
  },
  listenGoodMood: function( fn ) {
      setTimeout(function() { //假设A的心情十秒之后会变好
        fn();
    }, 10000);
  }
};

再假设买花是一个代价昂贵的操作(说不定会被别人误会什么的,而且花放太久也会谢),所以我们当需要的时候再去做这事才比较划算,就是在A心情好的时候再去new一个花出来。

//引入代理B
var B = {
    receiverFlower: function( flower ) {
      A.listenGoodMood(function() { //监听A的好心情
        var Flower = function(){};
      A.receiveFlower( flower );
    });
  }
};

此外,代理B可以帮助A做一些过滤请求,比如把一些年纪太大的,没有宝马的送花者都过滤掉,这种请求就可以直接在代理B中被拒绝掉,这种代理方式叫保护代理