前言:
责任链模式是一个行为模式。责任链就是从一个起点发起请求,然后沿着任务链依次传递给每一个节点上的对象,直到有一个节点处理这个请求为止。听着是不是跟Android的事件分发机制很像。
定义:
使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递改请求,直到有对象处理它为止
使用场景:
- 多个对象可以处理统一请求,但具体谁处理在运行时动态决定。
- 在请求的处理者不明确的情况下,向多个对象的一个提交请求。
- 需要动态指定一组对象处理请求
UML 简单版:
- Handler:抽象处理者角色,声明一个处理请求的方法,并保持对下一个处理节点Handler对象的引用。
- ConcreteHandler: 具体的处理者,对请求进行处理,如果不处理就讲请求转发给下一个节点上的处理对象。
抽象处理者:
public abstract class Handler {
protected Handler successor;
public abstract void handleRequest(String condition);
}
实际处理者:
public class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(String condition) {
if ("ConcreteHandler1".equals(condition)){
System.out.println("ConcreteHandler1 handled");
return;
}else {
successor.handleRequest(condition);
}
}
}
public class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(String condition) {
if ("ConcreteHandler2".equals(condition)) {
System.out.println("ConcreteHandler2 handled");
return;
} else {
successor.handleRequest(condition);
}
}
}
客户端调用:
public class Client {
public static void main(String[] args) {
ConcreteHandler1 concreteHandler1 = new ConcreteHandler1();
ConcreteHandler2 concreteHandler2 = new ConcreteHandler2();
concreteHandler1.successor = concreteHandler2;
concreteHandler2.successor = concreteHandler1;
concreteHandler1.handleRequest("ConcreteHandler2");
}
}
输出:
UML复杂图:
抽象处理者:
public abstract class AbstractHandler {
protected AbstractHandler nextHandler;
public final void handleRequest(AbstractRequest request){
if (request.getRequestLevel()==getHandleLevel()){
handle(request);
}else {
if (nextHandler!=null){
nextHandler.handleRequest(request);
}else {
System.out.println("没有对象能处理这个请求");
}
}
}
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();
}
实现请求:
public class Request1 extends AbstractRequest {
public Request1(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 1;
}
}
public class Request2 extends AbstractRequest {
public Request2(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 2;
}
}
public class Request3 extends AbstractRequest {
public Request3(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 3;
}
}
处理实现:
public class Handler1 extends AbstractHandler {
@Override
protected int getHandleLevel() {
return 1;
}
@Override
protected void handle(AbstractRequest request) {
System.out.println("Handler1处理了请求:"+request.getRequestLevel());
}
}
public class Handler2 extends AbstractHandler {
@Override
protected int getHandleLevel() {
return 2;
}
@Override
protected void handle(AbstractRequest request) {
System.out.println("Handler2处理了请求:"+request.getRequestLevel());
}
}
public class Handler3 extends AbstractHandler {
@Override
protected int getHandleLevel() {
return 3;
}
@Override
protected void handle(AbstractRequest request) {
System.out.println("Handler3处理了请求:"+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("A");
AbstractRequest request2 = new Request2("B");
AbstractRequest request3 = new Request3("C");
handler1.handleRequest(request1);
handler1.handleRequest(request2);
handler1.handleRequest(request3);
}
}
输出:
纯的与不纯的责任链模式:
一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一是承担责任,而是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又 把责任向下传的情况。
在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。
纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。有些人认为不纯的责任链根本不是责任链模式,这也许是有道理的。但是在实际的系统里,纯的责任链很难找到。如果坚持责任链不纯便不是责任链模式,那么责任链模式便不会有太大意义了。
优点:
- 降低耦合度,便于拓展,提高代码灵活性。
- 责任链对象互相链接,只用想头部发起请求。
缺点:
- 如果责任链太长,或者每条链判断处理的时间太长会影响性能。特别是递归循环的时候。
- 请求不一定能得到处理,可能会没有对象处理。