欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > asp.net >内容正文

asp.net

js设计模式之职责链模式

发布时间:2024/1/1 asp.net 41 豆豆
生活随笔 收集整理的这篇文章主要介绍了 js设计模式之职责链模式 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

一. 初始职责链模式

        定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者的关系,将这个对象连成一条链,并沿着一条链传递该请求,直到一个对象处理它为止。

可能有点晦涩难懂,我们来看一个例子,比如说你妈让你出去打酱油,此时我的请求就是买一瓶酱油回来,你会出门先去离你家最近的超市买酱油,如果没有,你会去下一个超市,知道有一个超市买到了酱油,也就结束了这条链的传递,超市就相当于处理请求的一条对象链,这就是职责链模式,我们想办法用代码实现它。

二. 代码实现

需求:我们来实现生活中的一个例子,商品的优惠活动,有三种情况,第一种是500元订金100元优惠券,第二种是200元订金50元优惠券,第三种是无优惠。

        此时我们首先想到的做法肯定使用条件分支来判断属于哪一种优惠,虽然可以达到目的,但是代码的可维护性太低,我们可以使用职责链模式来实现。

1. 灵活可拆分的职责链节点

        分析:首先我们将每一次优惠作为单独封装,判断请求是否满足此次优惠条件,如果不满足,则向下传递,直到满足优惠条件为止。

let order500 = function( orderType, pay, stock ) {if( orderType == 1 && pay == true) {console.log(" 500元订金,得到100元优惠券");}else{return 'nextSuccessor';}}let order200 = function( orderType, pay, stock ){if( orderType == 2 && pay == true ) {console.log(" 200元订金,得到50元优惠券");}else{return 'nextSuccessor';}}let orderNormal = function( orderType, pay, stock ) {if(stock > 0) {console.log("普通购买,无优惠券");}else{console.log("手机库存不足");}}// 包装节点let Chain = function( fn ){this.fn = fn;this.successor = null;}Chain.prototype.setNextSuccessor = function( successor ) {return this.successor = successor;}Chain.prototype.passRequest = function() {let ret = this.fn.apply(this, arguments);if( ret === "nextSuccessor") {return this.successor && this.successor.passRequest.apply(this.successor, arguments);}return ret;}// 创建职责链节点let chainOrder500 = new Chain( order500 );let chainOrder200 = new Chain( order200 );let chainOrderNormal = new Chain( orderNormal );chainOrder500.setNextSuccessor( chainOrder200 ).setNextSuccessor(chainOrderNormal);chainOrder500.passRequest(1, true, 500);chainOrder500.passRequest(2, true, 500);

2. 异步的职责链

        分析:有时我们的请求可能不是那么顺畅,比如获取请求时,请求数据拿回来可能有延迟,我们根据拿到的数据来判断是否进行再次的请求,因此我们需要设置主动向下一节点传递请求,通过异步实现。

// 包装节点let Chain = function( fn ){this.fn = fn;this.successor = null;}Chain.prototype.setNextSuccessor = function( successor ) {return this.successor = successor;}Chain.prototype.passRequest = function() {let ret = this.fn.apply(this, arguments);if( ret === "nextSuccessor") {return this.successor && this.successor.passRequest.apply(this.successor, arguments);}return ret;}Chain.prototype.next = function() {return this.successor && this.successor.passRequest.apply( this.successor, arguments);}// 创建职责链节点let fn1 = new Chain(()=>{console.log(1);return 'nextSuccessor';})let fn2 = new Chain(function(){console.log(2);let self = this;setTimeout(()=>{self.next();}, 2000);})let fn3 = new Chain(()=>{console.log(3);})fn1.setNextSuccessor( fn2 ).setNextSuccessor( fn3 );fn1.passRequest();

3. 用 AOP 实现职责链

分析:用 AOP 来实现虽然简单巧妙,但是将函数叠在一起,也叠加了函数的作用域,如果两天太长会对性能有较大影响。

Function.prototype.after = function( fn ) {let self = this;return function() {let ret = self.apply(this, arguments);if(ret === 'nextSuccessor') {fn.apply( this, arguments );}return ret;}}let order = order500.after( order200 ).after( orderNormal );order(3, true, 500);

三. 总结

        优点:1.  解耦了请求的发送者和 N 个接收者之间的 复杂关系

                   2. 每个对象可有灵活拆分,控制请求的入口和长度

        缺点: 1. 可能某次传递中大部分节点都只是作为传递,并没有多大的用处,造成性能损耗

无论是作用域链,原型链,还是冒泡事件中都合适的应用了职责链模式。职责链模式还可以和组合模式结合在一起,用来连接部件和父部件,或者提高组合对象的效率。

总结

以上是生活随笔为你收集整理的js设计模式之职责链模式的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。