前言:
Android 的设计模式系列文章,欢迎star,持续更新。。。
定义:
责任链就是从一个起点发起请求,然后沿着任务链依次传递给每一个节点上的对象,直到有一个节点处理这个请求为止。
应用场景:
- 多个对象可以处理统一请求,但具体谁处理在运行时动态决定。
- 在请求的处理者不明确的情况下,向多个对象的一个提交请求。
- 需要动态指定一组对象处理请求。
简单版 UML :
- client:用户发起的一个请求
- handler:抽象处理者角色,声明一个处理请求的方法,并保持对下一个处理节点Handler对象的引用。
- CH1,CH2(具体处理者):实现抽象处理类,对请求进行处理,如果不处理则转发给下一个处理者.
简单版代码示例: 用快递作为例子应该是最形象的了吧,每个快递员只负责送自己负责的区域,当有一个快递过来,如果不是自己市的那就给其他市的快递员去派送,直到有人送,或者最终没人能送为止。
/**
* 整个广东的快递员抽象类
*/
public abstract class GuangDongPostman {
public GuangDongPostman nextPostman;//下一个快递员
//根据快递单上的地址决定是给哪个市的快递员派送
public abstract void onPost(String address);
}
/**
* 深圳市的快递员
*/
public class SZPostman extends GuangDongPostman {
@Override
public void onPost(String address) {
if ("shenzhen".equals(address)) {
System.out.println("是我深圳市的,我去派送");
return;
} else {
if (nextPostman!=null)
nextPostman.onPost(address);
else
System.out.println("没有快递员能派送这个快递");
}
}
}
/**
* 珠海市的快递员
*/
public class ZHPostman extends GuangDongPostman {
@Override
public void onPost(String address) {
if ("zhuhai".equals(address)) {
System.out.println("是我珠海市的,我去派送");
return;
} else {
if (nextPostman != null)
nextPostman.onPost(address);
else
System.out.println("没有快递员能派送这个快递");
}
}
}
/**
* 广州市的快递员
*/
public class GZPostman extends GuangDongPostman {
@Override
public void onPost(String address) {
if ("guangzhou".equals(address)) {
System.out.println("是我广州市的,我去派送");
return;
} else {
if (nextPostman != null)
nextPostman.onPost(address);
else
System.out.println("没有快递员能派送这个快递");
}
}
}
public class ClienTest {
public static void main(String[] args) {
GuangDongPostman szPostman = new SZPostman();
GuangDongPostman zhPostman = new ZHPostman();
GuangDongPostman gzPostman = new GZPostman();
//假设快递是从广州最新开始派送的,最后一个是珠海(广州-深圳-珠海)
gzPostman.nextPostman = szPostman;
szPostman.nextPostman = zhPostman;
//责任链开始处理
System.out.println("快递单上地址写着深圳市");
gzPostman.onPost("shenzhen");
System.out.println("快递单上地址写着珠海市");
gzPostman.onPost("zhuhai");
System.out.println("快递单上地址写着广州市");
gzPostman.onPost("guangzhou");
System.out.println("快递单上地址写着广西省柳州市的");
gzPostman.onPost("liuzhou");
}
}
最终结果:
复杂版UML:
现实中最适合责任链的应该就是部门领导之间的上报请求了。比如员工要申请一笔资金,会先向组长申请,额度如果在组长的范围内,组长就批了,组长权限不够就向主管申请,主管如果也额度不够就向经理申请。这就形成了个责任链。
组长,主管,经理。每个人都是责任链上的一个节点。一个请求被层层转达,知道被处理或没有一个人能处理。普通员工,就是那个申请的发起者并不需要知道到底最后是谁审批的,他只要拿到钱就行了。
代码实现:
1:抽象领导类
/**
* 领导的抽象类
*/
public abstract class Leader {
public Leader nextLeader; //下一个领导
public void handleRequest(int money) {
//在可申请范围之内
if (money <= getLimit()) {
handle(money);
} else {
//递交下一级处理
if (nextLeader != null) {
nextLeader.handleRequest(money);
} else {
System.out.println(money + "元,没有人能处理你的申请");
}
}
}
//每个领导能处理的最大值
public abstract int getLimit();
//直接处理请求
public abstract void handle(int money);
}
2:具体领导类
/**
* 组长
*/
public class GroupLeader extends Leader {
//组长能处理的金额最多1000元
private static final int BALANCE = 1000;
@Override
public int getLimit() {
return BALANCE;
}
@Override
public void handle(int money) {
System.out.println("你申请的:" + money + "元 由组长审批就行");
}
}
/**
* 主管
*/
public class DirectorGroup extends Leader {
//主管能处理的金额最多5000元
private static final int BALANCE = 5000;
@Override
public int getLimit() {
return BALANCE;
}
@Override
public void handle(int money) {
System.out.println("你申请的:" + money + "元 由主管审批就行");
}
}
/**
* 经理
*/
public class ManagerGroup extends Leader {
//经理能处理的金额最多10000元
private static final int BALANCE = 10000;
@Override
public int getLimit() {
return BALANCE;
}
@Override
public void handle(int money) {
System.out.println("你申请的:" + money + "元 由经理审批就行");
}
}
3:员工申请入口
public class ClienTest {
public static void main(String[] args) {
Leader groupLeader = new GroupLeader();
Leader director = new DirectorGroup();
Leader manager = new ManagerGroup();
groupLeader.nextLeader = director;
director.nextLeader = manager;
groupLeader.handleRequest(500);
groupLeader.handleRequest(3000);
groupLeader.handleRequest(8000);
groupLeader.handleRequest(20000);
}
}
4:最终结果
优缺点总结:
- 降低耦合度,便于拓展,提高代码灵活性。
- 责任链对象互相链接,头部发起请求。
- 如果责任链太长,或者每条链判断处理的时间太长会影响性能。特别是递归循环的时候
- 请求不一定能得到处理,可能会没有对象处理。