责任链模式,顾名思义,多个对象可以处理同一个请求,但是用哪个对象处理请求,是动态的,对象成链式结构,将请求一级一级向下传,处理则截断,否则继续向下传递,这就是责任链模式。
android里的屏幕触摸事件就是用的这种模式,父布局先收到触摸事件,如果父布局选择处理,子view则收不到触摸事件,反之父布局将事件传给子布局,后面有时间我会写一篇关于android触摸事件传递的源码讲解,在这之前先了解一下责任链模式。
一、定义
1、多个对象有机会处理同一个请求,从而避免了请求的发送者和各个接收者之间的耦合关系。将这些接收者对象连成一条链,直到有从头到尾一次调用处理请求。
UML图:
Handler:抽象处理者,声明一个处理请求的方法,并在其中保存一个下一节点的处理者的对象引用
ConcreteHandler1/2:具体处理者,对请求进行处理,如果不能处理则将请求发送给下一个节点的处理者处理
二、使用场景
多个对象有机会处理同一个请求,但是用哪个对象处理请求,是动态的
三、示例
先写一个抽象类作为父类:
public abstract class EventHandler {
public EventHandler eventHandler;//下一个节点
public abstract void doSomething(String name);//待处理的请求
}
然后创建三个可以处理同一个请求的对象:
public class MyHandler1 extends EventHandler {
@Override
public void doSomething(String name) {
if ("MyHandler1".equals(name)) {
Log.e("tag", "MyHandler1 处理了事件");
} else {
if (eventHandler != null)
eventHandler.doSomething(name);
}
}
}
public class MyHandler2 extends EventHandler {
@Override
public void doSomething(String name) {
if ("MyHandler2".equals(name)) {
Log.e("tag", "MyHandler2 处理了事件");
} else {
if (eventHandler != null)
eventHandler.doSomething(name);
}
}
}
public class MyHandler3 extends EventHandler {
@Override
public void doSomething(String name) {
if ("MyHandler3".equals(name)) {
Log.e("tag", "MyHandler3 处理了事件");
} else {
if (eventHandler != null)
eventHandler.doSomething(name);
}
}
}
好了,不用解释什么,代码几乎都是一样的,使用起来很简单:
客户类:
MyHandler1 handler1 = new MyHandler1();
MyHandler2 handler2 = new MyHandler2();
MyHandler3 handler3 = new MyHandler3();
//设置MyHandler1的下一个节点
handler1.eventHandler = handler2;
//设置MyHandler2的下一个节点
handler2.eventHandler = handler3;
handler1.doSomething("MyHandler2");
传入MyHandler2,这个事件将会被MyHandler2处理,并且截断不再传给MyHandler3
四、责任链模式进阶
上面我们说的是一个简化版的通用模式代码,因为对于请求者来说,其形式是固定的,就是一个字符串,我们判断接收者是否能处理请求的时候,只是判断字符串是否匹配,然而在大多数情况下,这样显然是不满足需求的,所以我们也需要对请求者进行封装,把请求者也作为一个独立的对象:
五,进阶示例
首先我们来看抽象处理者AbsteactHandler
public abstract class AbstractHandler {
protected AbstractHandler next;
public final void handleRequest(AbstractRequest request) {
if (getHandleLevel() == request.getRequestLevel()) {
handle(request);
} else {
if (next != null) {
next.handleRequest(request);
} else {
System.out.print("所有处理者皆不能处理请求");
}
}
}
/**
* 获取处理者对象的级别
*
* @return 级别
*/
public abstract int getHandleLevel();
/**
* 每个处理者对象的处理方式
*
* @param request 请求者对象
*/
public abstract void handle(AbstractRequest request);
}
这种情况下我们的责任转发逻辑由抽象处理者控制,而对于抽象请求者,其内部也声明了请求级别的方法,什么级别的处理者处理什么级别的请求
public abstract class AbstractRequest {
/**
* 处理对象
*/
private Object obj;
public AbstractRequest(Object obj) {
this.obj = obj;
}
public Object getObj() {
return obj;
}
/**
* 获取请求级别
*
* @return 级别
*/
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
public int getHandleLevel() {
return 1;
}
@Override
public void handle(AbstractRequest request) {
System.out.print(getClass().getSimpleName() + "处理了请求:" + obj);
}
}
public class Handler2 extends AbstractHandler {
@Override
public int getHandleLevel() {
return 2;
}
@Override
public void handle(AbstractRequest request) {
System.out.print(getClass().getSimpleName() + "处理了请求:" + obj));
}
}
public class Handler3 extends AbstractHandler {
@Override
public int getHandleLevel() {
return 3;
}
@Override
public void handle(AbstractRequest request) {
System.out.print(getClass().getSimpleName() + "处理了请求:" + obj));
}
}
下面是客户类,大家可以自行尝试:
public static void main(String[] args) {
//构造三个处理者
AbstractHandler handler1 = new Handler1();
AbstractHandler handler2 = new Handler2();
AbstractHandler handler3 = new Handler3();
handler1.next = handler2;
handler2.next = 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);
}