设计模式之责任链模式 (Chain of Responsibility Pattern)
责任链模式是一种解耦请求发送者与处理者的设计模式,让多个对象都有机会处理请求。其核心思想是将处理者连成链,每个处理者自行决定是否处理或传递给下一节点,使请求在链上自动流转。典型应用包括审批流程、中间件处理等场景。该模式优势在于动态调整处理顺序、符合开闭原则,但会牺牲处理确定性并增加调试难度。实现时通过抽象处理者基类定义模板方法,客户端只需将请求发送给链头,无需关心具体处理逻辑。本质是将处理决策权从
📋 Research Summary
责任链模式是解耦请求发送者和接收者的经典方案。在 Web 框架中间件(Express、Django Middleware)、审批流程、异常处理机制中广泛应用。它让多个对象都有机会处理请求,避免请求发送者与具体处理者的紧耦合。
🌱 逻辑原点
如果报销审批需要根据金额大小依次经过主管、经理、总监、CEO,但金额标准经常变化,你是让申请人自己决定找谁,还是让申请自动流转到合适的人?
请求发送与处理决策的矛盾:发送者不知道谁来处理,处理者需要根据内容动态决定。

🧠 苏格拉底式对话
1️⃣ 现状:最原始的解法是什么?
发送者直接决定由谁处理:
def submit_request(request):
if request.amount < 1000:
supervisor.handle(request)
elif request.amount < 5000:
manager.handle(request)
elif request.amount < 10000:
director.handle(request)
else:
ceo.handle(request)
优点:直接,流程一目了然。
问题:发送者需要知道所有处理者的存在和判断逻辑。
2️⃣ 瓶颈:规模扩大 100 倍时会在哪里崩溃?
当审批层级有 10 层,且判断逻辑复杂(不仅看金额,还要看类型、部门、紧急程度)时:
- 判断逻辑重复:100 个发送点都重复写着相同的判断逻辑
- 修改困难:审批规则改变,所有发送点都要修改
- 违反开闭原则:新增审批层级,所有发送代码都要改
- 无法动态调整:无法在运行时改变审批顺序或插入新层级
核心矛盾:谁来处理的决策逻辑,不应该由发送者承担。
3️⃣ 突破:必须引入什么新维度?
将处理者连成链,让请求自己流转。
不是"发送者决定找谁",而是"发送者只发给链头,每个处理者决定是自己处理还是传给下一个"。处理者之间形成链条,请求在链上自动流转直到被处理:
请求 --> 主管(金额太大,传给下一个)--> 经理(可以处理,处理完成)
这就是责任链的本质:将处理决策从发送者转移到处理者,形成请求的自流转机制。
📊 视觉骨架
关键洞察:责任链让请求发送者完全不知道谁会处理请求。每个处理者只知道"自己能处理就处理,不能就传给下一个"。链条可以在运行时动态组装。
⚖️ 权衡模型
公式:
Chain of Responsibility = 解决了请求发送与处理的解耦 + 牺牲了处理确定性 + 增加了调试难度
代价分析:
- ✅ 解决: 发送者与处理者解耦、动态调整处理顺序、符合开闭原则(新增处理者不影响现有代码)、职责分离清晰
- ❌ 牺牲: 处理确定性(不知道谁会处理)、可能到达链尾都未被处理、性能(请求可能经过多个处理者)
- ⚠️ 增加: 调试难度(需要在链中跟踪请求)、循环引用风险
使用建议:当多个对象可以处理同一请求,但具体由谁处理在运行时才确定时使用。典型场景:审批流程、中间件过滤器链、事件冒泡、异常处理链。
🔁 记忆锚点
class Handler(ABC):
"""
责任链的本质:请求在链上自流转
"""
def __init__(self):
self._next = None
def set_next(self, handler: "Handler") -> "Handler":
self._next = handler
return handler # 支持链式设置
def handle(self, request) -> Optional[str]:
"""模板方法:能处理就处理,不能就传给下一个"""
if self.can_handle(request):
return self.process(request)
elif self._next:
return self._next.handle(request)
return None # 链尾都未处理
@abstractmethod
def can_handle(self, request) -> bool:
pass
@abstractmethod
def process(self, request) -> str:
pass
# 组装链条
chain = SupervisorHandler()
chain.set_next(ManagerHandler()).set_next(DirectorHandler())
# 客户端:只需要发给链头
result = chain.handle(request) # 不知道谁会处理,也不关心
一句话本质: 责任链模式 = 将处理决策从发送者转移到处理者,形成请求的自流转。
更多推荐



所有评论(0)