美文网首页
JavaScript 代理模式

JavaScript 代理模式

作者: kim_jin | 来源:发表于2018-12-03 15:55 被阅读0次

    代理模式的关键是:当客户不方便直接访问一个对象或不满足需求的时候,提供一个替身对象来控制这个对象的访问,客户实际上访问的是替身对象。替身对象对请求做出一系列的处理之后,再把请求交给本体对象。

    代理模式的例子

    下面的代码我们通过举例子的方式来进行具体的阐述:
    我们就以Tony追求Kristen来举一个例子:具体是这样的Tony在某天某地遇到了她心中的百分百女神Kristen,两天之后,Tony决定送给Kristen一束花,刚好Tony打听到了Kristen和他有一个共同的好友kelly。于是Tony决定委托kelly来代替自己完成送花的举动。现在我们看一下代码,假设Tony没有使用代理模式,而是直接将花送给了Kristen。代码如下:

    let Flower = function(){};
    let Tony = {
      sendFlower: function (target){
        let flower = new Flower();
        target.receiveFlower(flower);
      }
    };
    let Kristen={
      receiverFlower : function (flower){
        console.log('收到花:' + flower);
      }
    };
    
    Tony.sendFlower (Kristen);
    

    接下来让我们来引入代理kelly,即Tony通过Kelly将花送给了Kristen,那我们现在的操作应该是:

    let Flower = function(){};
    //客户
    let Tony = {
      sendFlower: function (target){
        let flower = new Flower();
        target.receiveFlower(flower);
      }
    };
    //代理
    let kelly = {
      receiverFlower : function (flower){
         A.receiverFlower(flower);
      }
    };
    //主体
    let Kristen = {
      receiverFlower : function (flower){
        console.log('收到花:' + flower);
      }
    };
    
    Tony.sendFlower (kelly);
    

    我们发现执行的两段代码的执行结果是一样的,至此我们就完成了一个最简单的代理模式的编写,如果代理模式的作用仅仅是这样的,我们完全没有必要引入代理。那么我们引入代理模式,是为了解决什么样的问题呢?我们向下继续走一步,如果代理可以为我们过滤掉某一些条件,那么处理起来是不是就简单多了。比如说,因为kelly和Kristen是很好的朋友,那么kelly就可以检测到什么时候Kristen的心情比较好,当Kristen的心情好的时候,Kristen答应Tony的追求的概率就会大大的增加了,当Kristen心情不好的时候,Tony追去成功的概率就会无限的趋近于0。那么我们现在就可以通过kelly来监听一下Kristen的心情,并在Kristen心情好的时候,选择将花送出去。

    let Flower = function(){}
    let Tony = {
      sendFlower: function(){
        let flower = new flower(target);
        target.receiverFlower (flower);
      }
    };
    let kelly = {
      receiverFlower : function(){
        Kristen.listenGoodMood (function(){ //监听Kristen的好心情
          Kristen.receiverFlower(flower);
        });
      }
    };
    let Kristen = {
      receiverFlower : function (flower){
        console.log('收到花:' + flower);
      },
      listenGodMood: function(){
        setTimeout(function(){
          fn();
        },1000);
      }
    };
    Tony.sendFlower (kelly);
    

    这就是引入代理的意义之一,那就是有一些操作,不是不是主体来做,也不是客体来做,而是将这部分的逻辑统一抽出,交给代理来做。这样的话,也有一定的好处,可以减少冗余的代码。

    let Tony= {
      sendFlower: function (target) {
       let flower = new Flower();
        taget.goodMood(function () {
      target.receiveFlower(flower)
    })
    }
    };
    let Ben= {
      sendFlower: function (target) {
       let flower = new Flower();
        taget.goodMood(function () {
      target.receiveFlower(flower)
    })
    }
    };
    let Adolph = {
      sendFlower: function (target) {
       let flower = new Flower();
        taget.goodMood(function () {
      target.receiveFlower(flower)
    })
    }
    };
    
    //这样写代码就会比较重复了,所以我们用个代理这样写
    let Tony = {
      sendFlower: function (target) {
        target.receiveFlower(flower)
    }
    };
    let Ben= {
      sendFlower: function (target) {
        target.receiveFlower(flower)
    }
    };
    let Adolph = {
      sendFlower: function (target) {
        target.receiveFlower(flower)
    }
    };
    
    let kelly= {
      receiveFlower: function(flower) { 
    // 代理接收到花感知到了女神心情好,开始送花
        Kristen.goodMood(function () {
    let flower = new Flower();
          Kristen.receiveFlower(flower);
      })
      }
    };
    Tony.sendFlower(kelly);
    Ben.sendFlower(kelly);
    Adolph.sendFlower(kelly);
    

    在这个程度上面精简了代码,使代码变的简单了。

    保护代理

    上面是保护代理呢,我们可以看出Kelly可以帮助Kristen过滤到一些不合规定的请求,比如说,Kristen要求他的男朋友必须是年龄较小的,年龄不能超过25岁,这样的请求可以直接在代理里面被拒绝。这种代理被拒绝掉,这样的代理作为保护代理。

    let Flower = function() {};
    let Tony = {
      sendFlower: function (target, condition) {
        target.receiveFlower(condition)
    }
    };
    let Ben = {
      sendFlower: function (target, condition) {
        target.receiveFlower(condition)
    }
    };
    let kelly= {
      receiveFlower: function(condition) { 
    // 代理接收到花感知到了女神心情好,开始送花
    if ( condition.age > 25) {
      Kristen.reject();
      return;
    }
        Kristen.goodMood(function () {
        let flower = new Flower();
          Kristen.receiveFlower(flower);
      })
      }
    };
    let Kristen= {
      receiveFlower: function (flower) {
      console.log('收到花了' + flower)
    },
    reject: function () {
    console.log('不接受大叔')
    },
    goodMood: function (fn) {
      setTimeout(function() {
      fn() // 假如女神5秒后心情好
    }, 5000)
    }
    } 
    Tony.sendFlower(daiLi, {age: 23});
    Ben.sendFlower(daiLi, {age: 32});
    

    看到这里我们知道了,保护代理其实就是做了一个访问对象的筛选,我们这个时候或许还有一个疑问,我们可以把删选条件写道女神自己的对象里面把,如下:

    let Kristen= {
      receiveFlower: function (flower, condition) {
       
    if (condition.age > 25)  {
      console.log('我接受大叔')
    } else {
       console.log('收到花了' + flower)
    }
    },
    goodMood: function (fn) {
      setTimeout(function() {
      fn() // 假如女神5秒后心情好
    }, 5000)
    }
    } 
    
    // 把条件写在这里看似是没问题的
    //但是如果有多个女神都不喜欢大叔怎么
    //三个女神还是会重复同样的代码,跟上面情况是一样的
    let Flower = function() {};
    let Tony= {
      sendFlower: function (target, love,condition) {
        target.receiveFlower(love, condition)
    }
    };
    let ben = {
      sendFlower: function (target, condition) {
        target.receiveFlower(condition)
    }
    };
    let kelly= {
      receiveFlower: function(love, condition) { // 代理接收到花感知到了女神心情好,开始送花
    if ( condition.age > 25) {
      love.reject();
      return;
    }
        love.goodMood(function () {
        let flower = new Flower();
          love.receiveFlower(flower);
      })
      }
    };
    
    let Kristen2= {
      receiveFlower: function (flower) {
      console.log('收到花了' + flower)
    },
    reject: function () {
    console.log('不接受大叔')
    },
    goodMood: function (fn) {
      setTimeout(function() {
      fn() // 假如女神5秒后心情好
    }, 5000)
    }
    } 
    
    let Kristen3= {
      receiveFlower: function (flower) {
      console.log('收到花了' + flower)
    },
    reject: function () {
    console.log('不接受大叔')
    },
    goodMood: function (fn) {
      setTimeout(function() {
      fn() // 假如女神5秒后心情好
    }, 5000)
    }
    } 
    
    Tony.sendFlower(daiLi, Kristen1, {age: 21});
    Ben.sendFlower(daiLi, Kristen2, {age: 30});
    

    我们可以看到了,这样写的话,我们的代码一下子就增加了很多,很多代码重复的写,这样的代码并不是我们想要的样子。

    相关文章

      网友评论

          本文标题:JavaScript 代理模式

          本文链接:https://www.haomeiwen.com/subject/ndntxqtx.html