JS设想形式——职责链形式

职责链形式

1. 职责链定义

使多个对象都有时机处置惩罚要求,从而防止要求的发送者和接受者之间的耦合关联,将对象连成一条链,并沿着这个链通报该要求,直到有一个对象处置惩罚它为止

2.职责链长处

要求发送者只须要晓得链中的第一个节点,从而弱化了发送者和一组接受者之间的强联络

3.职责链瑕玷

职责链形式使得顺序中多了一些节点对象,在某次要求通报历程当中,大部分节点并没有实质性作用,只是让要求通报下去,从机能方面斟酌,要防止太长的职责链带来的机能消耗

4.职责链运用场景

4.1 基本例子

商城做运动,预付定金500且购置的客户可返现100,预付定金200且购置的客户可返现50,一般购置则没有返现且库存不够买不到。

    //设置每一个节点的操纵,即每种用户对应的操纵,假如不能该节点不能操纵则通报给下一个节点。
var order500 = function (orderType, pay, stock) {
    if (orderType === 1 && pay === true) {
        console.log("100")
    } else {
        return 'nextSuccessor'
    }
}
var order200 = function (orderType, pay, stock) {
    if (orderType === 2 && pay === true) {
        console.log('50')
    } else {
        return 'nextSuccessor'
    }
}
var order = function (orderType, pay, stock) {
    if (stock > 0) {
        console.log('buy')
    } else {
        console.log('lack')
    }
}
//职责链,划定每一个节点的下一个节点,实行本节点的函数
function Chain(fn) {
    this.fn = fn
    this.nextSuccessor = null
}
Chain.prototype.setNextSuccessor = function (successor) {
    this.nextSuccessor = successor
}
Chain.prototype.passRequest = function () {
    var ret = this.fn.apply(this, arguments)
    if (ret === 'nextSuccessor') {
        return this.nextSuccessor && this.nextSuccessor.passRequest.apply(this.nextSuccessor, arguments)
    }
}
//把每一个节点都放到职责链中
var chainOrder500 = new Chain(order500)
var chainOrder200 = new Chain(order200)
var chainOrder = new Chain(order)
//设置职责链的下一个节点
chainOrder500.setNextSuccessor(chainOrder200)
chainOrder200.setNextSuccessor(chainOrder)
//设定从某个职责链节点最先实行
chainOrder500.passRequest(1, true, 1)

4.2 异步职责链

//设置每一个节点的操纵,即每种用户对应的操纵,假如不能该节点不能操纵则通报给下一个节点。
var order500 = function (orderType, pay, stock) {
    if (orderType === 1 && pay === true) {
        console.log("100")
    } else {
        return 'nextSuccessor'
    }
}
var order200 = function (orderType, pay, stock) {
    var self = this
    setTimeout(function () {
        self.next()
    }, 1000)
    // if (orderType === 2 && pay === true) {
    //     console.log('50')
    // } else {
    //     return 'nextSuccessor'
    // }
}
var order = function (orderType, pay, stock) {
    if (stock > 0) {
        console.log('buy')
    } else {
        console.log('lack')
    }
}
//职责链,划定每一个节点的下一个节点,实行本节点的函数
function Chain(fn) {
    this.fn = fn
    this.nextSuccessor = null
}
Chain.prototype.setNextSuccessor = function (successor) {
    this.nextSuccessor = successor
}
Chain.prototype.passRequest = function () {
    var ret = this.fn.apply(this, arguments)
    if (ret === 'nextSuccessor') {
        return this.nextSuccessor && this.nextSuccessor.passRequest.apply(this.nextSuccessor, arguments)
    }
}
Chain.prototype.next = function () {
    return (this.nextSuccessor) && this.nextSuccessor.passRequest.apply(this.nextSuccessor, arguments)
}
// 把每一个节点都放到职责链中
var chainOrder500 = new Chain(order500)
var chainOrder200 = new Chain(order200)
var chainOrder = new Chain(order)
//设置职责链的下一个节点
chainOrder500.setNextSuccessor(chainOrder200)
chainOrder200.setNextSuccessor(chainOrder)
// 设定从某个职责链节点最先实行
chainOrder500.passRequest(1, false, 1)

这里须要增添一个next函数,手动通报到下一个节点。

4.3 用AOP完成职责链

var order500 = function (orderType, pay, stock) {
    if (orderType === 1 && pay === true) {
        console.log("100")
    } else {
        return 'nextSuccessor'
    }
}
var order200 = function (orderType, pay, stock) {
    if (orderType === 2 && pay === true) {
        console.log('50')
    } else {
        return 'nextSuccessor'
    }
}
var order = function (orderType, pay, stock) {
    if (stock > 0) {
        console.log('buy')
    } else {
        console.log('lack')
    }
}

Function.prototype.after = function (fn) {
    var self = this
    return function () {
        var ret = self.apply(this, arguments)
        if (ret === 'nextSuccessor') {
            return fn && fn.apply(this, arguments)
        }
        return ret
    }
}
var func = order500.after(order200).after(order)
func(1, true, 3)

这里运用self变量存储上一个函数,func存储的是末了一个挪用after返回的函数。一旦挪用func函数,会先实行self保留的函数,会追根溯源一向到到最最先的self保留的函数order500。这里利用了闭包的特征保留了每一个self变量。全部函数的实行历程有点像倒序的递归。理解了历程也就会晓得return ret这句代码是为背面的函数预备的~

5. 发起

假如某块功用中存在大批的if else能够斟酌运用职责链形式

    原文作者:LJun
    原文地址: https://segmentfault.com/a/1190000016151870
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞