模式定义
使多个对象有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并演着这条链传递该请求,直到有一个对象处理它为止。
UML图
- Handler:定义职责接口,通常在内部定义处理请求的方法,可以在这里实现后继链。
- ConcreteHandler:实际的职责类,在这里个类里面,实现在它职责范围内的请求处理,如果不处理,就继续转发请求给后继者。
- Client:客户端,组装职责链,向链上的具体对象提交请求。
Handler抽象类代码
public abstract class Handler {
/**
* 内部持有后继的职责对象
*/
protected Handler successor;
/**
* 注入后继职责对象
* @param successor
*/
public void setSuccessor(Handler successor) {
this.successor = successor;
}
/**
* 抽象父类统一请求处理方法
* 可以在方法中传值 作为判断条件 也可以不传值利用其它外部条件
*/
public abstract void handlerRequest(int cost);
}
实现类代码
public class ConcreteHandler1 extends Handler {
@Override
public void handlerRequest(int cost) {
/*
根据某个条件判断是否是自己的处理职责范围
一般是传入的值 或者外部数据
*/
if (cost<1000){
//如果是自己的职责范围 就在内部处理
System.out.println(this.getClass().getSimpleName()+" handler event");
}else {
//如果不在自己的职责范围 就判断是否有后继者
if (this.successor!=null){
//存在后继者 讲请求传递
System.out.println(this.getClass().getSimpleName()+" post handler");
this.successor.handlerRequest(cost);
}
}
}
}
public class ConcreteHandler2 extends Handler {
@Override
public void handlerRequest(int cost) {
//简化流程 该对象一定能处理事件 不再下发
System.out.println(this.getClass().getSimpleName()+" handler event");
}
}
Client代码
public class Client {
public static void main(String[] args){
//客户端需要自己组装职责链
//构造职责对象
Handler handler1=new ConcreteHandler1();
Handler handler2=new ConcreteHandler2();
//组装链
handler1.setSuccessor(handler2);
//发起请求
handler1.handlerRequest(2000);
}
}
Android源码中的模式实现
ndroid中关于责任链模式比较明显的体现就是在事件分发过程中对事件的投递,其实严格来说,事件投递的模式并不是严格的责任链模式,但是其是责任链模式的一种变种体现。
适用性
在以下条件下使用职责链模式:
- 有多个对象可以处理同一个请求,那个对象处理该请求运行时刻自动确定。
- 你想在不明确指定接收者的情况下,想多个对象中的一个提交一个请求。
- 可处理一个请求的对象集合应被动态锁定。
优缺点
职责链模式有以下优点和缺点:
1)降低耦合度 该模式使得一个对象无需知道是其它哪一个对象处理其请求。对象仅需知道该请求会被“正确”地处理。接收者和发送者都没有对方的明确的消息,且链中的对象不许知道链的结构。
2)增强了给对象指派职责的灵活性 当在对象中分派职责时,职责链给你更多的灵活性。你可以通过在运行时刻对该职责链进行动态的增加或修改来增加或改变处理一个请求的那些职责。你可以将这种机制与静态的特例化处理对象的继承机制结合起来使用。
3)不保证被接受 既然一个请求没有明确的接收者,那么久不能保证它一定会被处理——该请求可能一直到链的末端都得不到处理。一个请求也可能因该链没有被正确配置而得不到处理。