:::info 责任链模式是一个相对比较简单的模式,它的名字已经非常好的暗示了其工作原理。每个处理器互相首尾连接在一起成为一条链,然后任务顺着这条链往下传,直到被某个处理器处理掉。 :::
定义
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
使用场景
一个请求需要被多个对象中的某一个处理,但是到底是哪个对象必须在运行时根据条件决定。
UML
角色结构
- Handler:所有处理器类的接口
ConcreteHandler :具体的处理器类,其实现Handler接口,有多少个处理器,就定义多少个这样的类
优点
是命令发出者与执行者解耦。
-
缺点
不能保证请求一定被接收。
- 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
- 可能不容易观察运行时的特征,有碍于除错。
业务场景
二狗提出买一台Mac笔记本电脑。这花钱的事需要领导审批,而每个领导权限不一样,能够审批的最大金额有限制。二狗首先肯定是向自己的小组leader提出,但是由于金额太大,超出了他的审批权限。于是小组领导就去找自己的领导,部门经理,但是部门经理也权限不够,最后到了CFO那里…
王二狗遇到的情况就非常适合使用责任链模式。二狗这个预算申请的请求,事先不知道会由哪层领导处理,而各层领导的审批职责就好像铁链一样连接在一起,一个预算请求沿着这条链一直往上传… 让我们用代码来实现上面的场景吧。
代码示例
BudgetHandler 一个所有处理器都要实现的接口
public interface BudgetHandler {
/**
* 设置下一个处理器
*/
void setNextHandler(BudgetHandler nextHandler);
/**
* 负责处理请求
*/
boolean handle(int amount);
}
GroupLeader 小组领导类
public class GroupLeader implements BudgetHandler {
private BudgetHandler nextHandler;
@Override
public void setNextHandler(BudgetHandler nextHandler) {
this.nextHandler = nextHandler;
}
/**
* 小组领导最多可以批1000块以下的预算,再多了就批不了了。
*/
@Override
public boolean handle(int amount) {
Objects.requireNonNull(nextHandler);
if(amount<1000){
System.out.println("小钱,批了!");
return true;
}
System.out.println(String.format("%d超出GroupLeader权限,请更高级管理层批复",amount));
return nextHandler.handle(amount);
}
}
Manager 部门经理类
public class Manager implements BudgetHandler {
private BudgetHandler nextHandler;
@Override
public void setNextHandler(BudgetHandler nextHandler) {
this.nextHandler = nextHandler;
}
/**
* 经理最多可以批5000块以下的预算
*/
@Override
public boolean handle(int amount) {
Objects.requireNonNull(nextHandler);
if (amount < 5000) {
System.out.println("小于2000块,我这个经理可以决定:同意!");
return true;
}
System.out.println(String.format("%d超出Manager权限,请更高级管理层批复", amount));
return nextHandler.handle(amount);
}
}
CFO 首席财务执行官
public class CFO implements BudgetHandler {
private BudgetHandler nextHandler;
@Override
public void setNextHandler(BudgetHandler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public boolean handle(int amount) {
if (amount < 50000) {
System.out.println("CFO同意,希望你再接再厉,为公司做出更大的贡献。");
return true;
}
if (nextHandler != null) {
return nextHandler.handle(amount);
}
//已经没有更高级的管理层来处理了
System.out.println(String.format("%d太多了,回去好好看看能不能缩减一下", amount));
return false;
}
}
Client
每个处理器都建好了,那么怎么才能让他们连成链呢?
这里可以让客户端来组织,也可以初始化的时候每一级处理器都指定自己的下一级。
public class Client {
public static void main(String[] args) {
GroupLeader leader = new GroupLeader();
Manager manager = new Manager();
CFO cfo = new CFO();
leader.setNextHandler(manager);
manager.setNextHandler(cfo);
System.out.println(String.format("领导您好:由于开发需求,需要购买一台Mac笔记本电脑,预算为%d 望领导批准", 95000));
if (leader.handle(25000)) {
System.out.println("谢谢领导");
} else {
System.out.println("巧妇难为无米之炊,只能划船了...");
}
}
}
输出
领导您好:由于开发需求,需要购买一台Mac笔记本电脑,预算为95000 望领导批准
25000超出GroupLeader权限,请更高级管理层批复
25000超出Manager权限,请更高级管理层批复
CFO同意,希望你再接再厉,为公司做出更大的贡献。
谢谢领导