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);  //输出:普通购买,无优惠卷

上一篇下一篇

猜你喜欢

热点阅读