Javascript-设计模式_职责链模式
定义
职责链模式(Chain of responsibility)是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止
核心思想
请求者不必知道是谁哪个节点对象处理的请求。如果当前不符合终止条件,那么把请求转发给下一个节点处理
职责链模式是一种对象行为型模式
场景
1000+万人口的新一线城市 ,以早高峰公交为例,早上早高峰的时候通常都是公交车前门拥堵,以至于没办法刷卡乘车;但是后门相对来说会空一些,这时只能选择后门上车,但是后门上车就刷不了卡,逃单?不存在的,这可不是作为讲文明、有素质的新一代青年应该做的,于是,只能往前面传递公交卡,请求前面的乘客帮忙传递至刷卡器处刷卡,但是在后门,刷卡器是在前门,这传递的过程中会通过请求多位乘客帮忙传递公交卡,这个传递的过程就是一种职责链模式,每一位传递的乘客就是职责链中的节点对象
特性
而当需求具有“传递”的性质时(代码中其中一种体现就是:多个 if、else if、else if、else 嵌套),就可以考虑将每个分支拆分成一个节点对象,拼接成为责任链
适用性
-
如果你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求的话,可以使用职责链模式
职责链模式实现了请求者和接收者之间的解耦,请求者不需要知道究竟是哪一个接收者对象来处理了请求
-
如果想要动态指定处理一个请求的对象集合,可以使用职责链模式,职责链模式能动态的构建职责链
也就是动态的来决定到底哪些职责对象来参与到处理请求中来,相当于是动态指定了处理一个请求的职责对象集合
式例
const Circle = function() { this.radius = 0 this.drawByRadius = function(radius) { if(radius < 5) { this.drawVerySmalCircle() }else if(radius < 10) { this.drawSmalCircle() }else if(radius < 15) { this.drawMediumCircle() }else if(radius < 20) { this.drawBigCircle() }else{ this.drawVeryBigCircle() } } this.drawVerySmalCircle = function() { console.log('画一个超小的圆( 5以下 )') } this.drawSmalCircle = function() { console.log('画一个小圆( 5-10 )') } this.drawMediumCircle = function() { console.log('画一个中圆 ( 10-15 )') } this.drawBigCircle = function() { console.log('画一个大圆 ( 15-20 )') } this.drawVeryBigCircle = function() { console.log('画一个超大的圆 ( 20以上 )') } } const circle = new Circle(); circle.drawByRadius(30) // 画一个超大的圆 ( 20以上 )
const drawSmalCircle = function(min, max) { this.max = max this.min = min this.nextCircle this.setNextDraw = function(circle) { this.nextCircle = circle } this.draw = function(radius) { console.log('执行:drawSmalCircle') if(this.min < radius && radius < this.max) { console.log('画一个小圆( 10以下 )') } if(this.nextCircle) { this.nextCircle.draw(radius) } } } const drawMediumCircle = function(min, max) { this.max = max this.min = min this.nextCircle this.setNextDraw = function(circle) { this.nextCircle = circle } this.draw = function(radius) { console.log('执行:drawMediumCircle') if(this.min < radius && radius < this.max) { console.log('画一个中圆 ( 10-20 )') } if(this.nextCircle) { this.nextCircle.draw(radius) } } } const drawBigCircle = function(min, max) { this.max = max this.min = min this.nextCircle this.setNextDraw = function(circle) { this.nextCircle = circle } this.draw = function(radius) { console.log('执行:drawBigCircle') if(this.min < radius && radius < this.max) { console.log('画一个大圆 ( 20以上 )') } if(this.nextCircle) { this.nextCircle.draw(radius) } } } function initChain() { const smalCircle = new drawSmalCircle(0, 10) const mediumCircle = new drawMediumCircle(10, 20) const bigCircle = new drawBigCircle(20, 100) smalCircle.setNextDraw(mediumCircle) mediumCircle.setNextDraw(bigCircle) return smalCircle } const circle = initChain() circle.draw(30) // 执行:drawSmalCircle // 执行:drawMediumCircle // 执行:drawBigCircle // 画一个大圆 ( 20以上 ) circle.draw(15) // 执行:drawSmalCircle // 执行:drawMediumCircle // 画一个中圆 ( 10-20 ) // 执行:drawBigCircle circle.draw(5) // 执行:drawSmalCircle // 画一个小圆( 10以下 ) // 执行:drawMediumCircle // 执行:drawBigCircle
优缺点
优点
-
降低耦合度,在职责链模式里面,请求者并不知道接收者是谁,也不知道具体如何处理,请求者只是负责向职责链发出请求就可以了。接收者和请求者都没有对象的明确的信息,且链中的对象不需要知道链的结构。 结果是,职责链可简化接收者对象的相互连接。它们仅需保持一个指向其后续者的引用,而不需要保持它所有的候选接收者的引用
-
增强了给对象指派职责的灵活性, 当在接收者中分派职责时,职责链给你更多的灵活性。你可以通过在运行时刻对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责
缺点
-
不保证被接受,既然一个请求没有明确的接收者,那么就不能保证它一定会被处理--该请求可能一直到链的末端都得不到处理,一个请求也可能因该链没有正确配置而得不到处理
-
带来多余消耗,当责任链过长,很多节点只有传递的作用,而不是真正地处理逻辑
-
建链不当,会造成循环调用,导致系统陷入死循环