一、定义
使多个对象都有机会处理请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
二、使用场景
多个对象都可以处理同一请求,但具体由哪一个对象处理则在运行时动态决定。
三、UML类图
Handler:抽象处理者,声明一个处理请求的方法,并保持一个下一节点的处理者对象的引用。
ConcreteHandler:具体处理者,对请求进行处理,如果不能处理则将该请求转发给下一节点的处理者对象。
上面是一个简化版的通用模式,因为对于请求来说,其形式是固定的,就是一个字符串,而判断一个节点上的处理者对象是否能够处理该请求的标志,则是该字符串是否与之匹配。然而在大多数情况下责任链中的请求和对应的处理规则是不尽相同的,在这种情况下可以将请求进行封装,同时对请求的处理规则也进行封装作为一个独立的对象。
四、实现
方式一:
//抽象处理者
public abstract class Handler {
protected Handler successor; //下一节点处理者
public abstract void handleRequest(String condition); //字符串条件
}
//具体处理者1
public class ConcreteHandler1 extends Handler {
public void handleRequest(String condition) {
if(condition.equals("ConcreteHandler1")) {
System.out.println("ConcreteHandler1 handled");
return;
} else {
successor.handleRequest(condition);
}
}
}
//具体处理者2
public class ConcreteHandler2 extends Handler {
public void handleRequest(String condition) {
if(condition.equals("ConcreteHandler2")) {
System.out.println("ConcreteHandler2 handled");
return;
} else {
successor.handleRequest(condition);
}
}
}
//客户端
public class Client {
public static void main(String[] args) {
ConcreteHandler1 handler1 = new ConcreteHandler1();
ConcreteHandler2 handler2 = new ConcreteHandler2();
handler1.successor = handler2;
handler2.successor = handler1;
handler1.handleRequest("ConcreteHandler2");
}
}
方式二:
//抽象处理者
public abstract class AbstractHandler {
protected AbstractHandler nextHandler;
public final void handleRequest(AbstractRequest request) { //对象条件
if(getHandleLevel() == request.getRequestLevel()) {
handle(request);
} else {
if(nextHandler != null) {
nextHandler.handleRequest(request);
} else {
System.out.println("All of handler can not handle the request");
}
}
}
protected abstract int getHandleLevel();
protected abstract void handle(AbstractRequest request);
}
//抽象请求
public abstract class AbstractRequest {
private Object obj;
public AbstractRequest(Object obj) {
this.obj = obj;
}
public Object getContent() {
return obj;
}
public abstract int getRequestLevel();
}
//具体请求1
public class Request1 extends AbstractRequest {
public Request1(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 1;
}
}
//具体请求2
public class Request2 extends AbstractRequest {
public Request2(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 2;
}
}
//具体请求3
public class Request3 extends AbstractRequest {
public Request3(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 3;
}
}
//具体处理者1
public class Handler1 extends AbstractHandler {
@Override
protected int getHandleLevel() {
return 1;
}
@Override
protected void handle(AbstractRequest request) {
System.out.println("Handler1 handle request: " + request.getRequestLevel());
}
}
//具体处理者2
public class Handler2 extends AbstractHandler {
@Override
protected int getHandleLevel() {
return 2;
}
@Override
protected void handle(AbstractRequest request) {
System.out.println("Handler2 handle request: " + request.getRequestLevel());
}
}
//具体处理者3
public class Handler3 extends AbstractHandler {
@Override
protected int getHandleLevel() {
return 3;
}
@Override
protected void handle(AbstractRequest request) {
System.out.println("Handler3 handle request: " + request.getRequestLevel());
}
}
//客户端
public class Client {
public static void main(String[] args) {
AbstractHandler handler1 = new Handler1();
AbstractHandler handler2 = new Handler2();
AbstractHandler handler3 = new Handler3();
handler1.nextHandler = handler2;
handler2.nextHandler = handler3;
AbstractRequest request1 = new Request1("Request1");
AbstractRequest request2 = new Request2("Request2");
AbstractRequest request3 = new Request3("Request3");
//总是从链式的首端发起请求
handler1.handleRequest(request1);
handler1.handleRequest(request2);
handler1.handleRequest(request3);
}
}
五、应用
例子: Android View事件分发机制
View事件是从父容器到子元素分发,如果子元素是ViewGroup并且有子元素,则继续传递事件,直到事件被消耗分发才结束。
六、总结
责任链模式可以对请求和处理者关系解耦,提高代码的灵活性。但是对链中请求处理者的遍历,如果处理者太多那么遍历必定会影响性能,特别是在一些递归调用中,要慎重。