设计模式实战:责任链模式(Chain of Responsibility)

在很多业务系统中,你会遇到这样的场景:

  • 请求需要经过多个处理步骤
  • 每个步骤可能处理,也可能放行
  • 处理流程可以动态调整

例如:

  • 审批流程(组长 → 经理 → 总监)
  • Web 中间件(鉴权 → 日志 → 限流)
  • 风控系统(规则1 → 规则2 → 规则3)

如果你这样写:

python 复制代码
def handle(request):
    if not check_auth(request):
        return "无权限"

    if not check_rate_limit(request):
        return "限流"

    if not check_risk(request):
        return "风控拦截"

    return "通过"

问题:

  • 所有逻辑耦合在一起
  • 顺序写死
  • 难扩展、难复用

这正是 责任链模式(Chain of Responsibility) 要解决的问题。


一、责任链模式解决什么问题?

一句话:

将请求沿着处理链传递,直到有对象处理它为止。

关键词:

  • 链式处理
  • 请求传递
  • 解耦处理者
  • 动态组合

二、核心结构

责任链模式包含:

1️⃣ Handler(处理者)

定义处理接口,并持有"下一个处理者"。

2️⃣ ConcreteHandler(具体处理者)

实现具体处理逻辑。

结构:

复制代码
Request → Handler1 → Handler2 → Handler3 → ...

每个节点可以:

  • 处理请求
  • 或传递给下一个

三、一个典型场景:审批流程

审批规则:

  • 小于 1000 → 组长审批
  • 小于 5000 → 经理审批
  • 其他 → 总监审批

四、Python 实现责任链模式

1️⃣ 定义处理器基类

python 复制代码
class Handler:

    def __init__(self):
        self.next_handler = None

    def set_next(self, handler):
        self.next_handler = handler
        return handler  # 支持链式调用

    def handle(self, request):
        if self.next_handler:
            return self.next_handler.handle(request)
        return None

2️⃣ 具体处理器

python 复制代码
class TeamLeader(Handler):

    def handle(self, amount):
        if amount < 1000:
            return f"组长审批通过: {amount}"
        return super().handle(amount)
python 复制代码
class Manager(Handler):

    def handle(self, amount):
        if amount < 5000:
            return f"经理审批通过: {amount}"
        return super().handle(amount)
python 复制代码
class Director(Handler):

    def handle(self, amount):
        return f"总监审批通过: {amount}"

3️⃣ 构建责任链

python 复制代码
leader = TeamLeader()
manager = Manager()
director = Director()

leader.set_next(manager).set_next(director)

4️⃣ 使用方式

python 复制代码
print(leader.handle(500))
print(leader.handle(3000))
print(leader.handle(10000))

输出:

复制代码
组长审批通过: 500
经理审批通过: 3000
总监审批通过: 10000

五、责任链模式的核心价值

责任链模式本质是:

把"处理流程"拆成一节一节的链。

它解决的是:

  • 流程耦合
  • 顺序固定
  • 难扩展

改造后:

  • 每个节点独立
  • 可以自由组合
  • 可以动态调整顺序

六、责任链的两种常见模式

1️⃣ 处理即终止(短路)

一旦某个节点处理,就停止:

python 复制代码
if can_handle:
    return result

2️⃣ 全链路处理(不中断)

每个节点都执行:

python 复制代码
def handle(self, request):
    do_something()
    if self.next_handler:
        self.next_handler.handle(request)

类似:

  • 中间件
  • Filter
  • AOP

七、更贴近实际的例子:中间件

python 复制代码
class Middleware:

    def __init__(self):
        self.next = None

    def set_next(self, next):
        self.next = next
        return next

    def process(self, request):
        if self.next:
            return self.next.process(request)

鉴权:

python 复制代码
class AuthMiddleware(Middleware):

    def process(self, request):
        print("鉴权")
        return super().process(request)

日志:

python 复制代码
class LogMiddleware(Middleware):

    def process(self, request):
        print("记录日志")
        return super().process(request)

使用:

python 复制代码
auth = AuthMiddleware()
log = LogMiddleware()

auth.set_next(log)

auth.process("request")

八、责任链 vs if/else

对比点 if/else 责任链
扩展性
顺序 写死 可调整
复用

一句话:

if/else 是"写死流程",责任链是"拼装流程"。


九、责任链 vs 观察者模式

很多人会混淆。

对比点 责任链 观察者
调用方式 顺序传递 广播通知
关系 一条链 一对多

一句话:

责任链是"一个接一个",

观察者是"同时通知"。


十、真实项目中的应用

非常常见:

1️⃣ Web 框架中间件

Django / Flask:

  • 请求 → 中间件 → 视图

2️⃣ 审批流系统

  • 请假审批
  • 报销审批

3️⃣ 风控系统

  • 多规则判断
  • 动态组合规则

4️⃣ 网关过滤器

  • 鉴权
  • 限流
  • 日志

十一、优缺点

✅ 优点

  • 解耦处理逻辑
  • 支持动态扩展
  • 提高复用性
  • 符合开闭原则

❌ 缺点

  • 请求可能无人处理
  • 调试链路较复杂
  • 链过长影响性能

十二、什么时候使用责任链模式?

适合:

  • 多个处理节点
  • 顺序处理请求
  • 处理逻辑可扩展

不适合:

  • 简单逻辑
  • 固定流程

十三、一句话总结

责任链模式的本质是:
把一个复杂流程拆成一条可组合的处理链。

换句话说:

不要写一大坨逻辑,把它拆成一节一节串起来。


相关推荐
2301_803875612 小时前
如何通过phpMyAdmin给WordPress所有用户发送全站通知_系统表插入
jvm·数据库·python
学弟2 小时前
【内涵】深度学习中的三种变量及pytorch中对应的三种tensor
人工智能·pytorch·python
2301_777599372 小时前
mysql如何进行数据库容量规划_评估磁盘空间增长趋势
jvm·数据库·python
aq55356002 小时前
PHP vs Python:30秒看懂核心区别
开发语言·python·php
m0_377618233 小时前
Redis怎样应对大规模集群的重启风暴_分批次重启节点并等待集群状态恢复绿灯后再继续操作
jvm·数据库·python
心态与习惯3 小时前
Julia 初探,及与 C++,Java,Python 的比较
java·c++·python·julia·比较
ZC跨境爬虫4 小时前
3D 地球卫星轨道可视化平台开发 Day8(分步渲染200颗卫星+ 前端分页控制)
前端·python·3d·重构·html
zopple4 小时前
ThinkPHP5.x与3.x核心差异解析
java·python·php
2401_835956814 小时前
Golang怎么写基准测试benchmark_Golang基准测试教程【完整】
jvm·数据库·python