设计模式-如何理解职责链模式?后端
定义: 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止
也就是说,请求之后,从第一个对象开始,链中收到请求的对象要么亲自处理它,要么转发给链中的下一个候选者。提交请求的对象并不明确知道哪个对象将会处理它——也就是该请求有一个隐式的接受者(implicit receiver)。根据运行时刻,任一候选者均可以响应相应的请求,候选者的数目是任意的,你能够在运行时刻决定哪些候选者参与到链中设计模式
还不明白?ok, 来个生活小实例, 早高峰挤公交车,每每挤上去却看不到售票员,咱们经常经过他人之手将票钱传递给售票员,这种关系就能看作为职责链,咱们的票钱经过多人之手最终递交到售票员手中app
代码场景:
假设咱们正在开发一个电商网站,某一个商品正在进行预约活动,活动规则以下函数
500 元定金会收到200 优惠劵
200 元定金会收到100 优惠劵
没有预约的用户只能普通购买
假设咱们后端会返回以下字段性能
orderType [1,2,3] 分别为500,200,普通购买学习
常规实现:网站
const order = function(orderType){ if(orderType===1){ // 假设咱们有其它需求 if(....){ ..... } return console.log(500元定金用户) } if(orderType===2){ // 假设咱们有其它需求 if(....){ ..... } return console.log(200元定金用户) } if(orderType===3){ // 假设咱们有其它需求 if(....){ ..... } return console.log(用户普通购买) } } order(1) // 500元定金用户
虽然咱们获得了意料中的运行结果,但这并非一段优秀的代码,order函数会随着业务的变动常常修改this
下面咱们用职责链模式进行改写prototype
const Chain = function(fn){ this.fn = fn; this.successor = null; } Chain.prototype.setNextSuccessor = function(successor){ 指定在链中的下一个节点 return this.successor = successor; } Chain.prototype.passRequest = function(){ //传递请求给某一下节点 var ret = this.fn.apply(this,arguments); if(ret === false){ // 若是ret 为false 表明链条还得继续往下走 return this.successor && this.successor.passRequest.apply(this.successor,arguments) } } // 包装成职责链的节点 var chainOrder500 = new Chain(order500); var chainOrder200 = new Chain(order200); // 而后再指定节点在链中的顺序 chainOrder500.setNextSuccessor(chainOrder200) // 最后把请求传递给第一个节点 chainOrder500.passRequest(1) // 500元定金用户
用AOP实现职责链又简单又巧妙,但这种函数叠加在一块儿的方式,同时也叠加了函数的做用域,若是链条太长也会对性能形成影响设计
Function.prototype.after(fn){ var _this = this; return function(){ var ret = _this.apply(this,arguments); if(ret === false){ return fn.apply(this.arguments); } return ret } } var order = order500.after(order200).after(orderNormal); order(2) // 200定金用户
职责链模式能够很好的帮助咱们管理代码,下降发起请求的对象跟接收请求对象的耦合,职责链中的节点顺序是可变化的,咱们能够在运行中决定链中包含哪些节点
JS每日一题能够当作是一个语音答题社区
天天利用碎片时间采用60秒内的语音形式来完成当天的考题
群主在第二天0点推送当天的参考答案