1 职责链模式概述
职责链模式: 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为之。
好处
降低耦合度。
接受者和发送者都没有对方的明确信息。链中的对象只要保持一个指向后继者的引用,而不需要保持对链中所有接受者的引用,可以大大解耦。
同时,发送者只需要把请求传递给链即可,而不需要关心具体由链中哪个对象处理这个请求,这样可以不影响客户端而能够在链上增加任意的处理节点。
2 模式结构图
组成:
Handler类:抽象处理者,定义一个处理请求的接口。
ConcreteHandler类:具体处理类,处理它负责的请求。若无法处理,就将请求转发给它的后继者。
3 模式 的实现
Java代码如下:
1)Handler类:
public abstract class Handler {
protected Handler successor;
//设置下一个处理者
public void setSuccessor(Handler successor){
this.successor = successor;
}
//处理请求
public abstract void handleRequest(String request);
}
2)具体处理类ConcreteHandler:
public class ConcreteHandlerA extends Handler{
@Override
public void handleRequest(String request) {
if(request.equals("加载")){
System.out.println("ConcreteHandlerA处理加载请求,开始加载。。。");
} else if(successor != null){
System.out.println("ConcreteHandlerA无法处理,交由ConcreteHandlerB处理");
successor.handleRequest(request);
}else{
System.out.println("无法处理请求!");
}
}
}
public class ConcreteHandlerB extends Handler{
@Override
public void handleRequest(String request) {
if(request.equals("连接")){
System.out.println("ConcreteHandlerB处理连接请求,开始连接。。。");
} else if(successor != null){
System.out.println("ConcreteHandlerB无法处理,交由ConcreteHandlerC处理");
successor.handleRequest(request);
}else{
System.out.println("无法处理请求!");
}
}
}
public class ConcreteHandlerC extends Handler{
@Override
public void handleRequest(String request) {
if(request.equals("初始化")){
System.out.println("ConcreteHandlerC处理初始化请求,开始初始化。。。");
} else if(successor != null){
successor.handleRequest(request);
}else{
System.out.println("无法处理请求!");
}
}
}
3)测试:
public class Main {
public static void main(String[] args) {
Handler handler1 = new ConcreteHandlerA();
Handler handler2 = new ConcreteHandlerB();
Handler handler3 = new ConcreteHandlerC();
handler1.setSuccessor(handler2);
handler2.setSuccessor(handler3);
String request1 = "加载";
String request2 = "连接";
String request3 = "初始化";
String request4 = "运行";
handler1.handleRequest(request4);
}
}
输出:
ConcreteHandlerA无法处理,交由ConcreteHandlerB处理
ConcreteHandlerB无法处理,交由ConcreteHandlerC处理
ConcreteHandlerC处理初始化请求,开始初始化。。。
4 Tomcat中模式的实现
在Tomcat中的容器设置就是责任链模式,从Engine到Host再到Context,到Wrapper都是通过一个链来处理请求。
下图就是Tomcat中的责任链模式的类结构图:
由图可以看出:Container对应的就是抽象处理者handler的角色,
具体处理者由StandardEngine等子容器扮演。
与标准的责任链不同的是,这里引入了 Pipeline 和 Valve 接口。
实际上 Pipeline 和 Valve 是扩展了这个链的功能,使得在链往下传递过程中,能够接受外界的干预。Pipeline 就是连接每个子容器的管子,里面传递的 Request 和 Response 对象好比管子里流的水,而 Valve 就是这个管子上开的一个个小口子,让你有机会能够接触到里面的水,做一些额外的事情。
为了防止水被引出来而不能流到下一个容器中,每一段管子最后总有一个节点保证它一定能流到下一个子容器,所以每个容器都有一个 StandardXXXValve。只要涉及到这种有链式是处理流程这是一个非常值得借鉴的模式。
参考:
(1)《大话设计模式》
(2)《深入分析Java Web》