责任链模式使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
从第一个对象开始,链中收到请求的对象要么亲自处理它,要么转发给链中的下一个候选者,提交请求的对象并不明确的知道哪一个对象将会处理它,我们说这个请求有一个隐式接收者。
责任链模式适用于有多个对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定,或者你希望在不明确接收者的情况下,向多个对象中的一个提交一个请求。例如,设定帮助系统,可能某些组件并没有设定帮助,而系统会去调用这些组件的父组件的帮助,若父组件也没有设定帮助,则依次向上请求帮助。
public class Handler {
private Handler successor = null;
private boolean isHelp = false;
public Handler(Handler successor, boolean isHelp) {
this.successor = successor;
this.isHelp = isHelp;
}
public void handleRequest() {
if (successor != null) {
successor.handleRequest();
}
}
public boolean hasHelp() {
return isHelp;
}
}
public class ConcreteHandler1 extends Handler{
public ConcreteHandler1(Handler successor, boolean isHelp) {
super(successor, isHelp);
}
public void handleRequest() {
if (hasHelp()) {
System.out.println("Many help!");
} else {
super.handleRequest();
}
}
}
public class ConcreteHandler2 extends Handler{
public ConcreteHandler2(Handler successor, boolean isHelp) {
super(successor, isHelp);
}
public void handleRequest() {
if (hasHelp()) {
System.out.println("Little help!");
} else {
super.handleRequest();
}
}
}
public class Client {
@Test
public void test() {
ConcreteHandler1 h1 = new ConcreteHandler1(null, true);
ConcreteHandler1 h2 = new ConcreteHandler1(h1, true);
h2.handleRequest();
ConcreteHandler2 h3 = new ConcreteHandler2(null, true);
ConcreteHandler2 h4 = new ConcreteHandler2(h3, true);
h4.handleRequest();
ConcreteHandler1 h5 = new ConcreteHandler1(null, true);
ConcreteHandler2 h6 = new ConcreteHandler2(h5, false);
h6.handleRequest();
ConcreteHandler1 h7 = new ConcreteHandler1(null, false);
ConcreteHandler2 h8 = new ConcreteHandler2(h7, true);
h8.handleRequest();
}
}
这里的Handler提供了所有Handler的基类,并且其中包含着默认的处理request的方法——handleRequest,它可以调用父组件的handleRequest方法。每个子类继承父类时,需要覆盖父类的handleRequest来自定义自己的帮助(如果不覆盖则会自动使用父类的handleRequest方法)。这样整个系统中并没有设定某个特定的类来处理请求,处理请求的类只是在系统运行时被动态的配置。当然,也可以把Handler的参数设定为enum类型(而不是boolean类型指定的两种类型),这样可以动态设定不同的enum类型对应的Handler类型,这些类型的解析可以通过xml之类的配置来实现,这样整个系统就会有非常强大的动态性。