定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合,将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
使用场景
- 多个对象可以处理同一个请求,但是具体哪个对象处理则在运行时动态决定。
- 在请求处理者不明确的情况下向多个对象中的一个提交请求。
- 需要动态指定一组对象处理请求。
优点
- 可以对请求者和处理者关系解耦,提高代码灵活性。
缺点
- 对处理链中请求的遍历,如果处理者太多那么遍历必定会影响性能,特别是在递归调用中。
关键类
- 处理请求的抽象类和具体类
- 请求的抽象类和具体类。
在Android 源码的应用
- 事件分发机制
- 有序广播机制
生活实例
最近农村在测量土地,测量后重新登记,但是村里的王二麻子家测量的土地和登记的土地不一致,那么这个时候怎么办呢?村民嘛肯定是先向村长汇报,然后村长向乡长汇报,乡长向县长汇报。每一个领导的处理权限都不一样,级别越高,权利越大。这个地球人都知道,哈哈。当然村民也可以直接找乡长,或者县长,不过正常流程还是先找村长,因为县衙的大门不一定能进去。这个就是生活中的责任链的场景。现在我们涉及代码来实现。
处理的顶层抽象类:
public abstract class Officer{
public Officer lastOfficer;
//权限等级
public abstract int landNum();
//对请求的统一处理
public void requestHandle(Request request){
if (landNum() >= request.landNum()){
handle(request);
}else {
if (lastOfficer!=null){
lastOfficer.requestHandle(request);
}
}
}
//每一个请求的具体处理方法
public abstract void handle(Request request);
}
-
lstOfficer
字段代表上一级官员的引用,因为在责任链中处理的时候村长处理不了,那么需要通过这个引用去调用乡长去处理。 -
landNum()
用来设置自己的权限到底多大。 -
requestHandler(Request request)
这个方法是所有处理实现类共有的处理逻辑,当自己处理不了的时候就调用上一级官员处理。因为是共有的逻辑,所以封装在了顶层抽象类,简化代码。 -
handle(Request request)
每个处理实现类用来对请求进行具体个性化的处理。
处理的顶层请求类
public abstract class Request {
//需要处理的请求等级
public abstract int landNum();
//请求之后的结果通知
public abstract void noticeResult(String result);
}
-
landNum()
在此案例中是王二麻子少登记的土地亩数,与官员权利处理等级一致。 -
noticeResult(String result)
当请求被处理后通知王二麻子,可有可无。
处理请求的具体实现类
public class villageOfficer extends Officer{
public villageOfficer(){
this.lastOfficer = new TownshipOfficer(); //指定下一个汇报对象是乡长
}
@Override
public int landNum() { //可以处理一亩地
return 1;
}
@Override
public void handle(Request request) {
request.noticeResult("村长处理了");
}
}
- 这个是村长,可以处理王二麻子一亩地的请求,不用向上汇报。
- 在它的构造方法中直接指定了它的向上汇报对象是镇长,当然也可以在请求的时候在灵活的指定。
public class TownshipOfficer extends Officer {
public TownshipOfficer() {
this.lastOfficer = new CountryOfficer(this);
}
@Override
public int landNum() { //可以处理3亩地
return 3;
}
@Override
public void handle(Request request) {
request.noticeResult("乡长处理了");
}
}
- 这个是乡长的实现类,在这里乡长可以处理王二麻子3亩土地的请求。
- 当然也直接在构造方法中指定了汇报对象是县长,也可以灵活指定。
public class CountryOfficer extends Officer{
public CountryOfficer(TownshipOfficer townshipOfficer) {
}
@Override
public int landNum() { //可以处理10亩地
return 10;
}
@Override
public void handle(Request request) {
request.noticeResult("县长解决了");
}
}
- 这个是县长的实现类,可以处理十亩地的请求。
请求的实现类
public class WangVillage extends Request{
@Override
public int landNum() {
return 1;
}
@Override
public void noticeResult(String result) {
System.out.print(result);
}
}
- 王二麻子少登记一亩地。
请求开始
WangVillage wangVillage = new WangVillage(); //创建请求
villageOfficer villageOfficer = new villageOfficer(); //创建村长
villageOfficer.requestHandle(wangVillage); //向村长提交请求
- 王二麻子写好了申请书,去了村长家递交了,等待消息,当然在这里你也可以直接向乡长县长提交。
总结
设计套路源于生活,套路的定义往往高度抽象,因为为了具有一般性,刚开始看开篇的定义可能一头雾水,看完王二麻子的故事,在回去看看开篇部分,可能会若有所悟。