设计模式学习之四—职责链模式

职责链者模式应用场景

该模式在业务中比较常见,常见场景是:检测用户是否满足A条件,不满足就检测是否满足B,再不满足就检测是否满足C,直到找到一个他满足的一个条件,但是从A-C是有优先级的,按照优先级一次降级检测。

职责链者模式应用案例

现在我们来模拟一个场景使用该模式:
用户来买手机,目前有三个优惠政策,分为优惠500,优惠200,无优惠,售罄。当然,优先级也是按照优惠大小来划分。当用户来买时,我们就要检测他满足哪种优惠。
随手来码代码的话:我们会用if判断来检测他满足哪种优惠,但是if层级太多的话,会显得代码非常乱,于是就用到职责连模式。
我们来看代码,首先列出三种优惠条件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var order500 = function( orderType, pay, stock ){
if ( orderType === 1 && pay === true ){
console.log( '500 元定金预购,得到 100 优惠券' );
}else{
return 'nextSuccessor'; // 我不知道下一个节点是谁,反正把请求往后面传递
}
};
var order200 = function( orderType, pay, stock ){
if ( orderType === 2 && pay === true ){
console.log( '200 元定金预购,得到 50 优惠券' );
}else{
return 'nextSuccessor'; // 我不知道下一个节点是谁,反正把请求往后面传递
}
};
var orderNormal = function( orderType, pay, stock ){
if ( stock > 0 ){
console.log( '普通购买,无优惠券' );
}else{
console.log( '手机库存不足' );
}
};

以上代码,把每个优惠政策分别声明,如果满足该优惠条件,则执行优惠,否则就传给下一节点,但是我们需要把这些节点关联起来才行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//  声明一个链
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;
};

然后实例化各个节点,让他们串联起来:

1
2
3
4
5
6
7
8
//  实例化各个节点
var chainOrder500 = new Chain( order500 );
var chainOrder200 = new Chain( order200 );
var chainOrderNormal = new Chain( orderNormal );

// 通过 setNextSuccessor方法跟下一个节点关联起来
chainOrder500.setNextSuccessor( chainOrder200 );
chainOrder200.setNextSuccessor( chainOrderNormal );

检验一下成果:

1
2
3
4
chainOrder500.passRequest( 1, true, 500 ); // 输出:500 元定金预购,得到 100 优惠券
chainOrder500.passRequest( 2, true, 500 ); // 输出:200 元定金预购,得到 50 优惠券
chainOrder500.passRequest( 3, true, 500 ); // 输出:普通购买,无优惠券
chainOrder500.passRequest( 1, false, 0 ); // 输出:手机库存不足

(完)