职责链模式适合审批流是因为其支持动态增删节点、解耦逻辑、避免硬编码if-else导致的高维护成本;它通过统一接口、上下文透传、可配置跳过与会签增强,实现灵活可扩展的多级审批。

为什么职责链模式适合审批流而不是硬编码 if-else
因为审批规则常随业务动态变化:不同部门、金额区间、申请人职级对应不同审批人,且可能叠加“会签”“或签”“跳过条件”。硬编码 if-else 会导致每次加一条规则就要改主逻辑,测试成本高、易漏分支。职责链把每个审批节点封装成独立对象,新增节点只需注册进链,不侵入已有代码。
如何用 PHP 实现可配置的职责链结构
核心是抽象出统一接口,并让每个处理器决定是否处理、是否继续传递。关键点不是“必须传递”,而是“由当前节点判断是否终止”:
- 定义接口
ApproverInterface,含handle($request)方法,返回bool表示是否已处理完毕(true= 终止链,false= 继续下个节点) - 每个具体处理器(如
ManagerApprover、FinanceApprover)只关心自己职责范围:检查$request->amount或$request->department,满足则执行审批动作并返回true;否则返回false - 链式调用靠构造器注入下一个处理器:
new ManagerApprover($next = new FinanceApprover(null)),末端节点$next为null - 避免无限递归:在
handle()中先判空$this->next,再调用$this->next->handle($request)
怎么支持“会签”和“条件跳过”这类复杂场景
纯线性职责链无法直接表达并行或多条件分支,需在节点内部做增强,而非拉长链:
- 会签:不放在链中流转,而由某个节点(如
DirectorApprover)内部调用collectSignatures(['legal', 'hr', 'tech']),批量发起并等待结果,再统一返回true - 条件跳过:节点自身逻辑判断,例如
if ($request->isUrgent) { return $this->next->handle($request); }—— 这里不是“跳过自己”,而是“不处理、直接交棒”,符合职责链语义 - 金额分段:用策略组合,比如
AmountBasedApprover内部维护一个[$min => $approver1, $max => $approver2]映射,查到匹配项后调用对应处理器,不匹配则返回false继续链
实际部署时最容易被忽略的三个细节
职责链看着简单,但上线后常因这些点崩掉:
- 请求对象(
$request)必须是可变对象(如 DTO 类),不能传原始数组 —— 否则下游节点无法写回审批意见、时间戳等上下文信息 - 没有兜底处理器(fallback handler):当所有节点都返回
false,链走到末尾却没人处理,应强制抛出UnhandledRequestException,而不是静默失败 - 循环依赖风险:调试时用
debug_backtrace()打印当前链路径,防止 A→B→C→A 这类注册错误;建议在链初始化时加get_class($this)去重校验
链越长,单测越要覆盖“中间节点提前终止”和“全链无匹配”两种边界。别指望靠日志事后排查——审批流一旦漏审,业务损失已经发生。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











