责任链模式介绍 简单说,责任链模式可以说是, 当问题不能解决的时候,将问题交给另一个对象去处理,就这样一直传递下去直至当前对象找不到下线了,处理结束.
意图: 避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
应用实例:
JS 中的事件冒泡。
JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,jsp servlet 的 Filter。
优点:
降低耦合度。它将请求的发送者和接收者解耦。
简化了对象。使得对象不需要知道链的结构。
增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
增加新的请求处理类很方便。
缺点:
不能保证请求一定被接收。
系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
可能不容易观察运行时的特征,有碍于除错。
使用场景:
有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
可动态指定一组对象处理请求。
示例程序
Trouble类 (数据结构)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package com.edu.tju.GOF.ChainOfResponsibility;public class Trouble { private int number; public Trouble (int number) { this .number = number; } public int getNumber () { return number; } public String toString () { return "[Trouble " + number + "]" ; } }
Support类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package com.edu.tju.GOF.ChainOfResponsibility;public abstract class Support { protected abstract boolean resolve (Trouble trouble) ; String name; Support next; public Support (String name) { this .name = name; } public String toString () { return "[" + name + "]" ; } public Support setAndReturnNext (Support next) { this .next = next; return next; } public final void support (Trouble trouble) { if (resolve(trouble)) { done(trouble); } else if (next != null ) { next.support(trouble); } else { fail(trouble); } } protected void fail (Trouble trouble) { System.out.println(trouble + "cannot be resolved." ); } protected void done (Trouble trouble) { System.out.println(trouble + " is resolved by " +this + "." ); } }
NoSupport类
1 2 3 4 5 6 7 8 9 10 11 12 13 package com.edu.tju.GOF.ChainOfResponsibility;public class NoSupport extends Support { public NoSupport (String name) { super (name); } protected boolean resolve (Trouble trouble) { return false ; } }
LimitSupport类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package com.edu.tju.GOF.ChainOfResponsibility;public class LimitSupport extends Support { private int limit; public LimitSupport (String name, int limit) { super (name); this .limit = limit; } protected boolean resolve (Trouble trouble) { return trouble.getNumber() <= limit ? true : false ; } }
SpecialSupport类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package com.edu.tju.GOF.ChainOfResponsibility;public class SpecialSupport extends Support { public int specialNumber; public SpecialSupport (String name, int specialNumber) { super (name); this .specialNumber = specialNumber; } protected boolean resolve (Trouble trouble) { return trouble.getNumber() == specialNumber ? true : false ; } }
OddSupport类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package com.edu.tju.GOF.ChainOfResponsibility;public class OddSupport extends Support { public OddSupport (String name) { super (name); } protected boolean resolve (Trouble trouble) { return (trouble.getNumber()%2 ) == 1 ? true : false ; } }
Main类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package com.edu.tju.GOF.ChainOfResponsibility;public class Main { public static void main (String[] args) { Support alice = new NoSupport("Alice" ); Support bob = new LimitSupport("Bob" , 100 ); Support charlie = new SpecialSupport("Charlie" , 429 ); Support diana = new LimitSupport("Diana" , 200 ); Support elmo = new OddSupport("Elmo" ); Support fred = new LimitSupport("Fred" , 300 ); alice.setAndReturnNext(bob).setAndReturnNext(charlie).setAndReturnNext(diana).setAndReturnNext(elmo) .setAndReturnNext(fred); for (int i = 0 ; i < 10 ; i += 1 ) { alice.support(new Trouble((int )(Math.random()*500 ))); } } }
角色 核心是Handle类,里面使用模板方法定义好了调用链的逻辑,然后通过递归调用下一个处理人。其它ConcreteHandler只负责定义各自的业务处理逻辑,然后等待被调用就行
Handle(处理者,抽象类)
ConcreteHandler(具体的处理者)
Client(请求者)
Chain of Responsibility模式的类图