🔗责任链模式?代码界的“踢皮球”高手!一文搞懂!
一、生活中的责任链,代码里的优雅之道

✨宝子们,你们有没有遇到过申请请假要层层审批的情况?组长→经理→CEO,每个人根据权限处理请求。这种 “踢皮球” 的智慧,在代码世界里就是大名鼎鼎的责任链模式!它能让请求像接力赛一样传递,直到找到合适的处理者。
二、责任链模式 360° 解析
2.1 模式定义与原理
责任链模式,简单来说,就是将请求的发送者和接收者解耦,让多个对象都有机会处理请求。它通过将这些对象连成一条链,请求在链上传递,直到有对象处理它为止。 🌐
比如在医院看病,病人挂号后,先分诊到科室,医生检查后可能安排进一步检查,最后根据结果开药。每个环节都是一个处理者,决定是否继续传递请求。
从原理上讲,责任链模式像一个接力赛,每个选手(处理者)决定是否接过接力棒(处理请求),如果不处理就传递给下一个选手。这就形成了一个动态的处理链路,非常灵活。
2.2 核心角色
在责任链模式中,有三个关键角色:抽象处理者、具体处理者和客户端。
| 角色 | 作用 | 案例中的体现 |
|---|---|---|
| 抽象处理者 | 定义处理接口和下一个节点 | 请假审批抽象类 |
| 具体处理者 | 实现处理逻辑,决定是否传递 | 组长、经理、CEO |
| 客户端 | 组装责任链,发起请求 | 员工提交请假申请 |
抽象处理者就像是一个模板,定义了处理请求的基本方法和下一个处理者的引用。具体处理者则是实现了这些方法,根据自己的逻辑决定是否处理请求。客户端则是负责创建责任链,并发送请求。
三、Java 实战:请假审批流程
3.1 代码实现
接下来,我们用 Java 代码实现一个简单的请假审批流程。
首先,定义一个请假请求类LeaveRequest,用于封装请假的相关信息:
public class LeaveRequest {
private String empName; // 员工姓名
private int leaveDays; // 请假天数
private String reason; // 请假原因
public LeaveRequest(String empName, int leaveDays, String reason) {
this.empName = empName;
this.leaveDays = leaveDays;
this.reason = reason;
}
public String getEmpName() {
return empName;
}
public int getLeaveDays() {
return leaveDays;
}
public String getReason() {
return reason;
}
}
然后,定义抽象处理者类AbstractApprover,它定义了处理请求的基本方法和下一个处理者的引用:
public abstract class AbstractApprover {
protected AbstractApprover nextApprover; // 下一个审批人
public void setNextApprover(AbstractApprover nextApprover) {
this.nextApprover = nextApprover;
}
// 处理请假请求的抽象方法
public abstract void processRequest(LeaveRequest request);
}
接着,定义具体处理者类,分别是组长TeamLeader、经理Manager和 CEOCEOApprover,它们继承自AbstractApprover,并实现具体的处理逻辑:
// 组长审批
public class TeamLeader extends AbstractApprover {
@Override
public void processRequest(LeaveRequest request) {
if (request.getLeaveDays() <= 1) {
System.out.println("组长 " + request.getEmpName() + " 请假 " + request.getLeaveDays() + " 天,原因:" + request.getReason() + ",审批通过");
} else {
if (nextApprover != null) {
System.out.println("组长 " + request.getEmpName() + " 请假天数超过权限,转交给经理审批");
nextApprover.processRequest(request);
} else {
System.out.println("审批流程结束,无人处理该请假请求");
}
}
}
}
// 经理审批
public class Manager extends AbstractApprover {
@Override
public void processRequest(LeaveRequest request) {
if (request.getLeaveDays() <= 3) {
System.out.println("经理 " + request.getEmpName() + " 请假 " + request.getLeaveDays() + " 天,原因:" + request.getReason() + ",审批通过");
} else {
if (nextApprover != null) {
System.out.println("经理 " + request.getEmpName() + " 请假天数超过权限,转交给CEO审批");
nextApprover.processRequest(request);
} else {
System.out.println("审批流程结束,无人处理该请假请求");
}
}
}
}
// CEO审批
public class CEOApprover extends AbstractApprover {
@Override
public void processRequest(LeaveRequest request) {
if (request.getLeaveDays() > 3) {
System.out.println("CEO " + request.getEmpName() + " 请假 " + request.getLeaveDays() + " 天,原因:" + request.getReason() + ",审批通过");
} else {
if (nextApprover != null) {
nextApprover.processRequest(request);
} else {
System.out.println("审批流程结束,无人处理该请假请求");
}
}
}
}
最后,在客户端代码中组装责任链并发起请求:
public class Client {
public static void main(String[] args) {
// 创建具体处理者实例
AbstractApprover teamLeader = new TeamLeader();
AbstractApprover manager = new Manager();
AbstractApprover ceo = new CEOApprover();
// 组装责任链
teamLeader.setNextApprover(manager);
manager.setNextApprover(ceo);
// 创建请假请求
LeaveRequest request1 = new LeaveRequest("张三", 1, "身体不适");
LeaveRequest request2 = new LeaveRequest("李四", 2, "参加婚礼");
LeaveRequest request3 = new LeaveRequest("王五", 5, "出国旅游");
// 发起请假请求
teamLeader.processRequest(request1);
teamLeader.processRequest(request2);
teamLeader.processRequest(request3);
}
}
3.2 执行结果
运行上述代码,输出结果如下:
组长 张三 请假 1 天,原因:身体不适,审批通过
组长 李四 请假天数超过权限,转交给经理审批
经理 李四 请假 2 天,原因:参加婚礼,审批通过
组长 王五 请假天数超过权限,转交给经理审批
经理 王五 请假天数超过权限,转交给CEO审批
CEO 王五 请假 5 天,原因:出国旅游,审批通过
从结果可以看出,不同天数的请假请求在责任链上被不同的处理者处理,完美体现了责任链模式的魅力。 🌟
四、应用场景大揭秘
责任链模式在实际开发中应用广泛,以下是一些常见的场景:
4.1 审批流程
请假、报销、合同审批等流程都可以用责任链模式实现。不同级别的审批人根据权限处理请求,形成一条审批链。例如,在报销流程中,普通员工提交报销申请,先由部门经理审批,金额较大时再由财务总监审批,最后由总经理审批。
4.2 日志处理
按日志级别输出日志,如 DEBUG→INFO→ERROR。可以将不同级别的日志处理器组成责任链,根据日志级别决定由哪个处理器处理。比如,DEBUG 级别的日志先由 DEBUG 处理器处理,若不需要处理则传递给 INFO 处理器,以此类推。
4.3 拦截器 / 过滤器
在 Spring Security 中,权限校验通过多个过滤器组成的责任链实现。每个过滤器负责特定的校验逻辑,如身份验证、权限检查等。请求在过滤器链中传递,直到通过所有校验或被拦截。
4.4 游戏事件处理
在游戏中,攻击、防御、治疗等事件可以通过责任链模式处理。例如,玩家发起攻击,先由防御系统处理,若未被防御则由治疗系统处理,形成链式反应。
五、优缺点大 PK
责任链模式就像一把双刃剑,既有它的闪光点,也有一些小瑕疵。
5.1 优点
解耦:请求发送者和接收者彻底分离,发送者不用关心谁来处理请求,接收者也不用知道是谁发的请求。就像我们在网上购物,下单后,订单的处理(库存检查、支付处理等)和我们没有直接关联,各个处理环节之间也相互独立 。
灵活:责任链的结构超级灵活,可以根据需要动态调整。比如请假审批流程,公司可以根据业务变化随时调整审批人或审批顺序,而不会影响其他部分的代码 。
扩展性:新增处理者就像搭积木一样简单,符合开闭原则。例如在日志处理系统中,要新增一个日志级别处理器,只需要创建新的处理器类并加入责任链即可,原有代码完全不用动 。
5.2 缺点
性能:如果责任链很长,请求处理的时间可能会变长,影响系统性能。想象一下,一个请求要经过 100 个处理者,那得多耗时呀 。
调试:当请求出现问题时,很难定位是哪个处理者出了问题,因为要遍历整条链。就像一串糖葫芦,中间某个山楂坏了,很难一下子找到是哪一个 。
六、避坑指南
在使用责任链模式时,也有一些需要注意的地方,宝子们可要牢记哦!
6.1 合理控制链长
责任链不宜过长,一般建议不超过 5 个节点。太长的链会导致性能下降,请求处理时间变长,就像排队太长会让人失去耐心一样 。
6.2 明确终止条件
一定要设置好终止条件,防止请求在链中无限递归,陷入死循环。比如在请假审批中,CEO 审批后就应该结束流程,不能再传递下去 。
6.3 日志记录
记录请求在责任链中的流转路径,方便调试和排查问题。就像我们记录快递的物流信息一样,知道请求到了哪个处理者手中 。
6.4 线程安全
在多线程环境下,要注意线程安全问题。可以使用锁机制来控制对责任链的访问,确保请求处理的正确性 。
七、总结
责任链模式是处理流程化业务的神器,适用于有明确层级关系的审批场景、需要动态扩展处理逻辑以及希望解耦请求与处理者的情况 。
宝子们,你们在项目中用过责任链模式吗?评论区聊聊你的 “链式操作” 经验吧!👇💡
最后,给大家对比一下责任链模式和状态模式,帮助大家更好地区分它们:责任链关注请求传递,状态模式关注对象状态变化。例如:请假审批(责任链)与订单状态流转(状态模式)。
3610

被折叠的 条评论
为什么被折叠?



