美文网首页
11.设计模式(职责链模式)

11.设计模式(职责链模式)

作者: 悠哈121 | 来源:发表于2020-11-19 14:16 被阅读0次

    1.职责链模式是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象形成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止
    举例说明:中学时代期末考试,如果你平时不太老实,考试将会被安排在第一个位置,遇到不会打的题目,就把题目编号写在小纸条上往后传递,坐在后面的同学如果不会,也会继续往后传
    职责链模式的优点:请求发送者只需要知道链中的第一个节点,从而弱化了发送者和一组接收者的强联系

    代码实现(假设我们有一个售卖手机的电商网站,经过分别交纳500和200元定金的两轮预定后,订单在此时生效,到正式购买阶段。在正式购买后,已经支付过500的用户会收到100元的券,支付过200的获得50券,而之前没有支付过的用户只能进入普通购买模式,且在库存有限的情况下)
    //1.orderType:订单类型(定金或者普通用户)code为1是500定金用户,code为2是200定金用户,为3是普通用户
    //2.pay:表示用户是否已经支付定金,用户可能下了500的订单,但是没有支付定金
    //3.stock:手机库存
    function order(orderType,pay,stock){
      switch(orderType){
        case 1:
          if(pay){
            console.log("500,返100")
          }else{
              if(stock > 0){
                console.log("普通用户,可以购买")
                return;
              }else{
                console.log("手机库存不足")
              }
          }
          break;
        case 2:
          if(pay){
            console.log("200,返50")
          }else{
              if(stock > 0){
                console.log("普通用户,可以购买")
              }else{
                console.log("手机库存不足")
              }
          }
          break;
        case 3:
          if(orderType === 3){
            if(stock > 0){
              console.log("普通用户,可以购买")
            }else{
              console.log("手机库存不足")
            }
          }
      }
    }
    order(1,true,20)//虽然我们得到了意料中运行结果,但这段代码巨大难以阅读
    代码实现2使用职责链重构代码 将500、200以及普通用户分为三个函数
    function order500(orderType,pay,stock){
      if ( orderType === 1 && pay === true ){ 
        console.log( '500 ,返100券' ); 
      }else{ 
        order200( orderType, pay, stock ); // 将请求传递给 200 元订单
      }
    }
    function order200( orderType, pay, stock ){
      if ( orderType === 2 && pay === true ){ 
        console.log( '200 ,返50券' ); 
      }else{ 
        orderNomarl( orderType, pay, stock ); // 将请求传递给 200 元订单
      }
    }
    function orderNomarl(orderType, pay, stock ){
      if(stock > 0){
        console.log("普通用户,可以购买")
      }else{
        console.log("手机库存不足")
      }
    }
    order500(1,false,200) //普通用户,可以购买
    //我们已经把大函数拆分成了互不影响的3个小函数,但请求在链条中的传递顺序很僵硬,传递请求别耦合在了业务函数中
    var order500 = function( orderType, pay, stock ){ 
     if ( orderType === 1 && pay === true ){ 
     console.log( '500 元定金预购, 得到 100 优惠券' ); 
     }else{ 
     order200( orderType, pay, stock ); 
     // order200 和 order500 耦合在一起 如果有天我们要增加300或者去掉200的订单则需要改动这些业务函数内部
     } 
    };
    代码实现3.灵活可拆分的职责链节点,我们约定摸个节点不能处理请求的时候返回一个特殊的字符串“nextSuccessor”,表示该请求需要继续往后传递
    function order500(orderType,pay,stock){
      if ( orderType === 1 && pay === true ){ 
        console.log( '500 ,返100券' ); 
      }else{ 
        return 'nextSuccessor';
      }
    }
    function order200( orderType, pay, stock ){
      if ( orderType === 2 && pay === true ){ 
        console.log( '200 ,返50券' ); 
      }else{ 
        return 'nextSuccessor';
      }
    }
    function orderNomarl(orderType, pay, stock ){
      if(stock > 0){
        console.log("普通用户,可以购买")
      }else{
        console.log("手机库存不足")
      }
    }
    //接下来需要把函数包装进职责链节点,我们定义一个构造函数Chain,在new Chain的时候传递的参数即为需要被包装的函数,同时它还拥有一个实例属性this.successor,百表示在链中的下一节点
    var Chain = function( fn ){ 
      this.fn = fn; 
      this.successor = null; 
     }; 
     Chain.prototype.setNextSuccessor = function( successor ){ 
      return this.successor = successor; 
     };
     Chain.prototype.passRequest = function(){
       var ret = this.fn.apply(this,arguments) 
       if(ret === 'nextSuccessor'){
         return this.successor && this.successor.passRequest.apply(this.successor,arguments)
       }
       return ret;
     }
    //将三个订单函数分别包装成职责链节点
    var chainOrder500 = new Chain( order500 ); 
    var chainOrder200 = new Chain( order200 ); 
    var chainOrderNormal = new Chain( orderNomarl );
    //然后指定节点子职责链中的顺序
    chainOrder500.setNextSuccessor(chainOrder200);
    chainOrder200.setNextSuccessor(chainOrderNormal);
    //最后把请求传给一个节点
    chainOrder500.passRequest(2,false,500)
    

    总结:无论是在作用域链、原型链、还是DOM节点中的事件冒泡,我们都能从中找到职责链模式的影子。

    相关文章

      网友评论

          本文标题:11.设计模式(职责链模式)

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