JavaScript职责链模式
2021-01-02 本文已影响0人
晓蟲QwQ
定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连城一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
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('手机库存不足');
}
};
//定义构造链节点构造函数
var Chain = function( fn ){
this.fn = fn;
this.successor = null;
};
//指定在链中的下一个节点
Chain.prototype.setNextSuccessor = function(successor){
return this.successor = successor;
};
//传递请求给某个节点
Chain.prototype.passRequset = 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.passRequset( 1, true, 500); //输出:500元定金预购,得到100优惠卷
chainOrder500.passRequset( 2, true, 500); //输出:200元定金预购,得到50优惠卷
chainOrder500.passRequset( 3, true, 500); //输出:普通购买,无优惠卷
chainOrder500.passRequset( 1, false, 0); //输出:手机库存不足
异步的职责链
//添加next方法,用于异步返回时使用
Chain.prototype.next = function(){
return this.successor && this.successsor.passRequset.apply( this.successor, arguments );
};
//使用例子
var fn1 = new Chain(function(){
console.log(1);
return 'nextSuccessor';
});
var fn2 = new Chain(function(){
console.log(2);
var self = this;
setTimeout(function(){
self.next();
},1000);
});
var fn3 = new Chain(function(){
console.log(3);
});
//使用例子
fn1.setNextSuccessor( fn2 ).setNextSuccessor( fn3 );
fn1.passRequset();
使用AOP实现职责链
优点:实现简单。
缺点:叠加作用域,链条太长时对性能影响较大。
Function.prototype.after = function( fn ){
var self = this;
return function(){
var ret =self.apply( this, arguments );
if( ret === 'nextSuccessor' ){
return fn.apply( this, arguments );
}
return ret;
}
};
var order = order500.after( order200 ).after( orderNormal );
order( 1, true, 500); //输出:500元定金预购,得到100优惠卷
order( 2, true, 500); //输出:200元定金预购,得到50优惠卷
order( 1, false, 500); //输出:普通购买,无优惠卷