一、定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有对象处理它为止。
二、适用场景
- 多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
- 在请求处理着不明确的情况下向多个对象中的一个提交一个请求。
- 需要动态指定一组对象处理请求。
责任链模式在View事件分发中、OkHttp中都有见到。应用面还是很多的。
三、实现
以一个员工报销的场景来说,每一级的领导能报销的项目额度是有最大限制的。
1. UML
2. 抽象领导(处理者)
封装了转发消耗的判断逻辑,剩下判断限制和具体处理交给具体的处理者去实现。
public abstract class Leader {
protected Leader nextHandler;
// 统一实现的转发消耗逻辑
public final void handleRequest(int money) {
if (money <= limit()) {
// 消耗
handle(money);
} else {
// 上层领导不空就转交
if (nextHandler != null) {
nextHandler.handleRequest(money);
}
}
}
// 具体的领导实现具体的额度限制
public abstract int limit();
// 具体领导实现具体报销方式
public abstract void handle(int money);
}
3. 具体领导
需要实现自己的额度限制方法和具体处理的方法。
public class Director extends Leader {
@Override
public int limit() {
return 1000;
}
@Override
public void handle(int money) {
System.out.println("director handle " + money);
}
}
public class Manager extends Leader {
@Override
public int limit() {
return 10000;
}
@Override
public void handle(int money) {
System.out.println("manager handle " + money);
}
}
public class Boss extends Leader {
@Override
public int limit() {
return Integer.MAX_VALUE;
}
@Override
public void handle(int money) {
System.out.println("boss handle " + money);
}
}
4. 使用
自己构造责任链,之后调用Director的处理方法。
public class Test {
public static void main(String[] args) {
Director director = new Director();
Manager manager = new Manager();
Boss boss = new Boss();
// 连接责任链
director.nextHandler = manager;
manager.nextHandler = boss;
// 调用最低级领导的方法
director.handleRequest(2222);
}
}
可以看到,Test访问了Director一个处理者,完全不需要知道其他处理者的存在,这就达到了请求和处理的解耦。
四、小结
优点:
请求者和处理者关系解耦,提高代码的灵活性。
缺点:
如果处理者过多,遍历会影响性能,特别如果有递归调用时需要慎重。
网友评论