设计模式之职责链模式

前言

职责链模式在咱们的开发中很是常见,然而在不知道的同窗那里,可能你以前都是经过if/else的方式来实现的相似逻辑。职责链主要就是指,在执行一个具体的事情时,不肯定使用哪一种逻辑时,进行链式的判断,直到找到符合条件的函数或者对象,而后处理。分析,发现其实咱们不少的代码的背后逻辑就是职责链模式。javascript

图解

image.png

现实中的职责链

现实中的例子很是多,好比,咱们在挤公交时,若是人特别多,咱们以前是将硬币经过人传递的方式,依次向前传递,直到前面的人是司机或者售票员,这就是一个很是明显的职责链的例子。java

代码重构

原先的代码主要是经过if,else进行不断的判断,执行不一样的逻辑。设计模式

案例说明

image.png

重构前

const order = (orderType,pay,stock){
	if(orderType === 1){
  	if(pay === true){
    	console.log('500元定金,返回100优惠券')
    } else {
    	if(stock > 0 ){
      	consle.log('普通购买,无优惠券')
      } else {
      	console.log('库存不足')
      }
    }
  }
  else if(orderType === 2){
    if(pay === true){
    	console.log('200元定金,返回50优惠券')
    } else {
    	if(stock > 0 ){
      	consle.log('普通购买,无优惠券')
      } else {
      	console.log('库存不足')
      }
    }           
   }else{
   	if(stock > 0 ){
      	consle.log('普通购买,无优惠券')
      } else {
      	console.log('库存不足')
      }
   }
}
复制代码

重构后

咱们按照职责链的设计思想,一步到位,分别包含如下的思路:app

  • 将不一样的购买模式封装为函数
  • 实现链式函数,能够不断追加函数,能够在不符合时,实现递交
const order500 = function(orderType,pay,stock){
	if(orderType === 1 && pay === true){
    	console.log('500元定金,返回100优惠券')
    } else {
    	return 'nextSuccessor';
    }
}
const order200 = function(orderType,pay,stock){
	if(orderType === 2 && pay === true){
    
    console.log('200元定金,返回50优惠券')
    } else {
    	return 'nextSuccessor';
    }
}


const orderNormal = function(orderType,pay,stock){
	if(stock > 0 ){
      	console.log('普通购买,无优惠券')
      } else {
      	console.log('库存不足')
      }
}

const Chain = function(fn){
	this.fn = fn;
    this.successor = null;
}
Chain.prototype.setNextSuccessor = function(successor){
	return this.successor = successor;
}
Chain.prototype.passRequest = function(){
 let ret = this.fn.apply(this, arguments);
 if(ret === 'nextSuccessor'){
 	return this.successor && this.successor.passRequest.apply(this.successor, arguments);
 }
 return ret;
}

let chainOrder500 = new Chain(order500);
let chainOrder200 = new Chain(order200);
let chainOrderNormal = new Chain(orderNormal);
chainOrder500.setNextSuccessor(chainOrder200);
chainOrder200.setNextSuccessor(chainOrderNormal);

chainOrder500.passRequest(1,false,0);
chainOrder500.passRequest(1,true,10);
chainOrder500.passRequest(2,true,11);
chainOrder500.passRequest(2,false,1);
复制代码

codepen地址:codepen.io/robinson90/…函数

番外篇:职责驱动设计以及状态模式的实践

文章连接:mp.weixin.qq.com/s/qQEEnf79F…学习

需求

image.png

解决方案

引入职责驱动概念,从知识的能力的角度,去判断哪一个对象具备操做的能力。ui

但这样的坏处是当加入新的状态时,全部实现接口的状态类都须要变动,不符合设计模式的开闭原则。this

状态图:spa

image.png

image.png

另外一种"职责链"

这种不在典型的职责链设计中,是我我的在开发过程当中,本身认为的也符合形式上的链式判断,但最终只肯定执行一个最终函数,而不是实现链式递交的。prototype

固然了,也可能这彻底不属于任何一种设计模式,不过我以为设计模式的本质仍是为了解决固定场景的固定思惟模式,至于叫什么名字应该不是重点。

具体代码以下:

let Chain = function(){
  let dutyArr = []
	this.addDuty = function(duty){
    dutyArr.push(duty)
  }
  this.opt = function(params){
		for(let index in dutyArr){
    	if(dutyArr[index].judge(params)){
      	return dutyArr[index].opt && dutyArr[index].opt(params);
      }
    } 
    return false
  }
}

let ageChainDemo = new Chain();
ageChainDemo.addDuty({
	judge:function(params){
    let {age} = params;
    return age > 18;
},
  opt:function(params){
    let {age} = params;
    return '你已是成年人了'
  }
})

ageChainDemo.addDuty({
	judge:function(params){
    let {age} = params;
    return age > 0 && age < 18;
},
  opt:function(params){
    let {age} = params;
    return '你仍是未成年'
  }
})
let result = ageChainDemo.opt({age:20});
console.log(result);
let result2 =ageChainDemo.opt({age:10});
console.log(result2);
复制代码

codepen地址:codepen.io/robinson90/…

与策略模式的区别

乍一看,写法上,职责链与策略模式没什么,都是分别维护不一样的函数逻辑,其区别主要是使用条件的判断。

策略模式能够准确的决定使用哪一种策略,并且能够肯定使用这种策略就能返回结果;而职责链模式,则是将使用条件进行抽象,内置到函数中,经过不断的函数内部判断,若是不符合,须要继续判断传递,直到执行到符合条件的函数并执行。

由此,咱们能够这样断定,若是咱们对条件属于模糊的,更适合使用职责链。这样要好于写if/else内写复杂的布尔运算,或者使用某个计算变量的结果值,或者使用其余函数的返回结果。

更多

原文连接:www.yuque.com/robinson/de…

更多设计模式的学习与了解,能够移步到个人设计模式专辑:www.yuque.com/robinson/de…

相关文章
相关标签/搜索