Fork me on GitHub

代理模式

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

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

先来一个带点趣味性的例子,小明要给女神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中被拒绝掉,这种代理方式叫保护代理

我知道是不会有人点的,但万一有人想不开呢?