职责链模式闭包
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将对象连成一条链,并沿着这个链传递该请求,直到有一个对象处理它为止app
请求发送者只须要知道链中的第一个节点,从而弱化了发送者和一组接受者之间的强联系异步
职责链模式使得程序中多了一些节点对象,在某次请求传递过程当中,大部分节点并无实质性做用,只是让请求传递下去,从性能方面考虑,要避免过长的职责链带来的性能耗损函数
商城作活动,预付定金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)
//设置每一个节点的操做,即每种用户对应的操做,若是不能该节点不能操做则传递给下一个节点。 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函数,手动传递到下一个节点。this
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这句代码是为后面的函数准备的~prototype
若是某块功能中存在大量的if else能够考虑使用职责链模式code