基本介绍
责任链模式 Chain of Responsibility Pattern 为请求创建一个接受者对象者链,将请求的发送者和接受者解耦。每个接受者都包含一个下一个接受者的引用,如果当前接受者不能处理的请求则会转发给下一个接受者。
UML
角色分析
Request 请求 包装多个请求的参数
Handler 责任链抽象类 组合了下一个责任链 包含一个handler 的抽象方法
ConcreteHandlerChain 责任链具体实现
Client 责任链调用者也需要将责任链串联起来
代码演示
典型的场景就是财务审核,0-2000部门经理审核,2000-5000CTO审核,5000以上Boss审核,这样的需求非常合适责任链模式设计
// Requst 请求 包装了所有在责任链中处理需要的参数
@Data
public class Request {
private final String name;
private final float money;
public Request(String name, float money) {
this.name = name;
this.money = money;
}
}
// 抽象责任链
public abstract class HandlerChain {
// 下一个责任链
protected HandlerChain nextChain;
public HandlerChain getNextChain() {
return nextChain;
}
public void setNextChain(HandlerChain nextChain) {
this.nextChain = nextChain;
}
// 抽象处理方法
public abstract void handler(Request request);
}
public class DeptManagerHandlerChain extends HandlerChain {
private final String name;
public DeptManagerHandlerChain( String name) {
this.name = name;
}
@Override
public void handler(Request request) {
// 处理0-2000
if (request.getMoney() > 0 && request.getMoney() <= 2000.0) {
System.out.println(name + "处理了" + request.getName() + "的" + request.getMoney() + "元的请求!");
}else{
getNextChain().handler(request);
}
}
}
public class CTOHandlerChain extends HandlerChain {
private final String name;
public CTOHandlerChain(String name) {
this.name = name;
}
@Override
public void handler(Request request) {
if (request.getMoney() > 2000 && request.getMoney() <= 5000.0) {
System.out.println(name + "处理了" + request.getName() + "的" + request.getMoney() + "元的请求!");
} else {
nextChain.handler(request);
}
}
}
public class BossHandlerChain extends HandlerChain {
private final String name;
public BossHandlerChain(String name) {
this.name = name;
}
@Override
public void handler(Request request) {
if (request.getMoney() > 5000) {
System.out.println(name + "处理了" + request.getName() + "的" + request.getMoney() + "元的请求!");
} else {
nextChain.handler(request);
}
}
}
// 调用测试
public class HandlerChainTest {
public static void main(String[] args) {
Request request = new Request("小王", 22220);
DeptManagerHandlerChain deptManagerHandlerChain = new DeptManagerHandlerChain("王部门经理");
CTOHandlerChain ctoHandlerChain = new CTOHandlerChain("张CTO");
BossHandlerChain bossHandlerChain = new BossHandlerChain("赵Boss");
// 设置部门经理下一个CTO
deptManagerHandlerChain.setNextChain(ctoHandlerChain);
// CTO --> BOSS
ctoHandlerChain.setNextChain(bossHandlerChain);
// BOSS--> 部门经理 形成闭环
bossHandlerChain.setNextChain(deptManagerHandlerChain);
deptManagerHandlerChain.handler(request);
}
}
使用细节
- 请求和处理请求分开,实现解耦,提高系统灵活性
- 简化使用,调用者无需知道责任链的内部结构
- 缺点在于如果责任链特别长会增加性能损耗,可以在责任链中控制最大节点数,一般在Handler中设置最大节点数,在setNext方法之前判断是否已经超过阈值,超过则不允许创建,避免过长链损耗系统性能
- 最佳使用场景 请假 审批等流程请求 拦截器等