美文网首页
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