js 责任链设计模式
2020-04-04 本文已影响0人
b59a2ae26f20
在业务逻辑中,有时会遇到解决一个问题需要多个步骤的操作,下一个步骤的执行需要上一个步骤的结果,当多个步骤前后都有依赖时,再坚持通过很多if eles解决问题的话,代码就容易变得不可维护,这种情况下,责任链模式的运用就十分关键。
举个简单的例子,在一促销活动中,有提前预定的活动,500元预定返现100,200元预定返现50,没有预定原价购买。交了定金的不会担心库存没有,没交定金的,库存没了就买不了了。下面通过责任链模式展现一下业务的处理过程。
const order500 = function (orderType, pay, stock) {
if(orderType === 5 && pay === true) {
console.log('500元定金预购,得到100优惠卷')
}else{
return 'nextSuccessor'
}
}
const order200 = function (orderType, pay, stock) {
debugger
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('库存不足')
}
}
以上是每种业务对应的函数,每个函数完全独立,没有任何依赖关系,只是如果不满足当前函数处理条件的话,返回‘nextSuccessor’,用该告诉调用者可以进行下一逻辑的处理。
但是现在还缺少一个串联者,用来把这些函数链接起来的角色,下面的类可以用来构造联条的每个环节
function Chain(fn) {
this.fn = fn
this.successor = null
}
Chain.prototype.setNextSuccessor = function (successor) {
return this.successor = successor
}
Chain.prototype.passRequest = function () {
let res = this.fn.apply(this, arguments)
if(res === 'nextSuccessor') {
return this.successor && this.successor.passRequest.apply(this.successor, arguments)
}
}
此时就可以构造联条了
const chainOrder500 = new Chain(order500);
const chainOrder200 = new Chain(order200);
const chainOrderNormal = new Chain(orderNormal)
链条好了,但是还要连起来
chainOrder500.setNextSuccessor(chainOrder200)
chainOrder200.setNextSuccessor(chainOrderNormal)
最后是对责任链的触发
chainOrder500.passRequest(2, true, 2) // 预约单类型,是否付款,库存