职责链模式

1.职责链模式的定义是:使多个对象都有机会处理请求,从⽽避免请求的发送者和接收者之间的耦合关系,

将这些对象连成⼀条链,并沿着这条链传递该请求,直到有⼀个对象处理它为⽌。 职责链模式的名字⾮
常形象,⼀系列可能会处理请求的对象被连接成⼀条链,请求在这些对 象之间依次传递,直到遇到⼀个
可以处理它的对象,我们把这些对象称为链中的节点
 
假设我们负责⼀个售卖⼿机的电商⽹站,经过分别交纳 500 元定⾦和 200 元定⾦的两轮预定后(订单已
在此时⽣成),现在已经到了正式购买的阶段。 公司针对⽀付过定⾦的⽤户有⼀定的优惠政策。在正式
购买后,已经⽀付过 500 元定⾦的⽤ 户会收到 100 元的商城优惠券,200 元定⾦的⽤户可以收到 50 元
的优惠券,⽽之前没有⽀付定⾦的⽤户只能进⼊普通购买模式,也就是没有优惠券,且在库存有限的情
况下不⼀定保证能买到。
 
var order = function( orderType, pay, stock ){
if ( orderType === 1 ){ // 500 元定⾦购买模式
if ( pay === true ){ // 已⽀付定⾦
console.log( '500 元定⾦预购, 得到 100 优惠券' );
} else{ // 未⽀付定⾦,降级到普通购买模式
if ( stock > 0 ){ // ⽤于普通购买的⼿机还有库存
console.log( '普通购买, ⽆优惠券' );
}else{
console.log( '⼿机库存不⾜' );
}
}
} else if ( orderType === 2 ){
if ( pay === true ){ // 200 元定⾦购买模式
console.log( '200 元定⾦预购, 得到 50 优惠券' );
}else{
if ( stock > 0 ){
console.log( '普通购买, ⽆优惠券' );
}else{
console.log( '⼿机库存不⾜' );
}
}
} else if (orderType === 3) {
if ( stock > 0 ){
console.log( '普通购买, ⽆优惠券' );
} else{
console.log( '⼿机库存不⾜' );
}
}
};
order( 1 , true, 500); // 输出: 500 元定⾦预购, 得到 100 优惠券
 
现在我们采⽤职责链模式重构这段代码,先把 500 元订单、200 元订单以及普通购买分成 3 个函数。
接下来把 orderType、pay、stock 这 3 个字段当作参数传递给 500 元订单函数,如果该函数不符合处
理条件,则把这个请求传递给后⾯的 200 元订单函数,如果 200 元订单函数依然不能处理该请求,则
继续传递请求给普通购买函数。
 
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( '⼿机库存不⾜' );
}
};
// Chain.prototype.setNextSuccessor 指定在链中的下⼀个节点
// Chain.prototype.passRequest 传递请求给某个节点
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( orderNormal );
chainOrder500.setNextSuccessor( chainOrder200 );
chainOrder200.setNextSuccessor( chainOrderNormal);
chainOrder500.passRequest( 1, true, 500 ); // 输出:500 元定⾦预购,得到 100 优惠
chainOrder500.passRequest( 2, true, 500 ); // 输出:200 元定⾦预购,得到 50 优惠券开课吧web全栈架构师
chainOrder500.passRequest( 3, true, 500 ); // 输出:普通购买,⽆优惠券
chainOrder500.passRequest( 1, false, 0 ); // 输出:⼿机库存不⾜
通过改进,我们可以⾃由灵活地增加
加、移除和修改链中的节点顺序,假如某天⽹站运营⼈员 ⼜想出了⽀
持 300 元定⾦购买,那我们就在该链中增加⼀个节点即可
var order300 = function(){
// 具体实现略
};
chainOrder300= new Chain( order300 );
chainOrder500.setNextSuccessor( chainOrder300);
chainOrder300.setNextSuccessor( chainOrder200);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2020-09-14 14:19  又回到了起点  阅读(127)  评论(0编辑  收藏  举报