职责链模式,使用AOP实现职责链编程

107 阅读2分钟

image.png 优点:每种场景都有各自的处理函数,而不受影响;链中的节点对象可以灵活地拆分、重组;还可以手动指定起始节点。

缺点:在请求传递的过程中,大部分的节点并没有起到实质性的作用,所以要避免过长的职责链带来的性能损耗。

同步职责链:

    //   orderType: 订单类型, 1: 500元定金用户;2: 200元定金用户;3: 普通购买用户
    // pay: 用户是否支付定金, 值为true或false,
    // stock:表示当前用于普通购买的手机库存数量,
    const order500 = function( orderType, pay, stock ) {
        if (orderType === 1 && pay === true) {
            console.log('500元定金预购,得到100优惠券')
        } else {
            return 'nextSuccessor'
        }
    }
    const order200 = function( orderType, pay, stock ) {
        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( '手机库存不足');
        }
    }

    const Chain = function(fn) {
        this.fn = fn
        this.successor = null
    }
    Chain.prototype.setNextSuccessor = function(successor) {
        return this.successor = successor
    }
    Chain.prototype.passRequest = function() {
        const res = this.fn.apply(this, arguments)
        if (res === 'nextSuccessor') {
            return this.successor && this.successor.passRequest.apply(this.successor, arguments)
        }
        return res
    }

    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 )
    chainOrder500.passRequest( 2, true, 500 )
    chainOrder500.passRequest( 3, true, 500 )
    chainOrder500.passRequest( 1, false, 0 )

异步职责链:


 const Chain = function(fn) {
        this.fn = fn
        this.successor = null
    }
    Chain.prototype.setNextSuccessor = function(successor) {
        return this.successor = successor
    }
    Chain.prototype.passRequest = function() {
        const res = this.fn.apply(this, arguments)
        if (res === 'nextSuccessor') {
            return this.successor && this.successor.passRequest.apply(this.successor, arguments)
        }
        return res
    }
    Chain.prototype.next = function() {
        this.successor && this.successor.passRequest.apply(this.successor, arguments)
    }

    const chainFirst = new Chain(function() {
        console.log('1')
        return 'nextSuccessor'
    })
    const chainSecond = new Chain(function() {
        console.log('2')
        setTimeout(() => {
            this.next()
        }, 2000);
    })
    const chainThird = new Chain(function(){
        console.log('3');
    })
    chainFirst.setNextSuccessor(chainSecond).setNextSuccessor(chainThird)
    chainFirst.passRequest()

使用AOP实现职责链编程


  Function.prototype.next = function(successor) {
        const self = this
        return function() {
            const res = self.apply(this, arguments)
            if(res === 'next') {
                return successor.apply(this, arguments)
            }
            return res
        }
    }

    const order500 = function( orderType, pay, stock ) {
        if (orderType === 1 && pay === true) {
            console.log('500元定金预购,得到100优惠券')
        } else {
            return 'next'
        }
    }
    const order200 = function( orderType, pay, stock ) {
        if (orderType === 2 && pay === true) {
            console.log('200元定金预购,得到50优惠券')
        } else {
            return 'next'
        }
    }
    const orderNormal = function( orderType, pay, stock ) {
        if ( stock > 0 ){
            console.log( '普通购买,无优惠');
        }else{
            console.log( '手机库存不足');
        }
    }
    const orderChain = order500.next(order200).next(orderNormal)
    orderChain(1, true, 500)
    orderChain(2, true, 500)
    orderChain(1, false, 500)
    orderChain(1, false, 0)