责任链模式(Chain of responsibility pattern)可以为某个请求创建一个对象链,每个对象依序检查此请求并对其进行处理,或者将它传给链中的下一个对象。发送请求的客户不需要知道链上的细节,从而与具体处理者解耦。
意图
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链发送该请求,直到有一个对象处理它为止。
类图
Handler 定义处理请求的接口,并且实现后继链(successor)。原文图片丢失,据文字重绘。
classDiagram
class Handler {
<<abstract>>
#Handler successor
+handleRequest(Request)
}
class ConcreteHandler1 {
+handleRequest(Request)
}
class ConcreteHandler2 {
+handleRequest(Request)
}
class Request {
-RequestType type
-String name
+getType() RequestType
+getName() String
}
Handler <|-- ConcreteHandler1
Handler <|-- ConcreteHandler2
Handler --> Handler : successor
实现
先定义请求和请求类型:
public class Request {
private RequestType type;
private String name;
public Request(RequestType type, String name) {
this.type = type;
this.name = name;
}
public RequestType getType() {
return type;
}
public String getName() {
return name;
}
}
public enum RequestType {
type1, type2
}
Handler 定义处理请求的接口,并维护后继链:
public abstract class Handler {
protected Handler successor;
public Handler(Handler successor) {
this.successor = successor;
}
protected abstract void handleRequest(Request request);
}
两个具体处理者:能处理就处理,否则传给下家:
public class ConcreteHandler1 extends Handler {
public ConcreteHandler1(Handler successor) {
super(successor);
}
@Override
protected void handleRequest(Request request) {
if (request.getType() == RequestType.type1) {
System.out.println(request.getName() + " is handle by ConcreteHandler1");
return;
}
if (successor != null) {
successor.handleRequest(request);
}
}
}
public class ConcreteHandler2 extends Handler {
public ConcreteHandler2(Handler successor) {
super(successor);
}
@Override
protected void handleRequest(Request request) {
if (request.getType() == RequestType.type2) {
System.out.println(request.getName() + " is handle by ConcreteHandler2");
return;
}
if (successor != null) {
successor.handleRequest(request);
}
}
}
客户端组装链并发起请求:
public class Client {
public static void main(String[] args) {
Handler handler1 = new ConcreteHandler1(null);
Handler handler2 = new ConcreteHandler2(handler1);
Request request1 = new Request(RequestType.type1, "request1");
handler2.handleRequest(request1);
Request request2 = new Request(RequestType.type2, "request2");
handler2.handleRequest(request2);
}
}
输出:
request1 is handle by ConcreteHandler1
request2 is handle by ConcreteHandler2
JDK 中的应用
- java.util.logging.Logger#log()
- Apache Commons Chain
- javax.servlet.Filter#doFilter()
相关模式:与装饰器的对比
责任链与装饰器结构上很相似:两者都把对象串成一串,调用沿着链递归传递。区别在于意图——装饰器的每个节点都会执行并在转发前后附加行为,强调”给对象增加职责”;责任链的每个处理者可以自行决定处理请求还是传给下一个,强调”请求由谁处理”。
系列导航
- 上一篇:代理(Proxy)
- 下一篇:命令模式(Command)