在软件开发中,经常会遇到需要按照顺序处理请求的情况,例如日志处理、权限控制、审批流程等。如果使用硬编码的 if-else 结构,代码将变得复杂且难以扩展。

责任链模式(Chain of Responsibility Pattern) 提供了一种将请求的处理者组织成链式结构的方法,使请求可以沿着责任链传递,直到被某个处理者处理,从而提高代码的灵活性和可扩展性。本文将详细介绍责任链模式的概念、应用场景,并通过 Python 代码示例展示其实现方式


一、责任链模式的概念

责任链模式(Chain of Responsibility Pattern) 是一种行为型设计模式(Behavioral Pattern),其核心思想是:

将多个处理者(Handler)连接成链条,请求在链条中传递,直到某个处理者处理请求或链条结束。

UML 结构

    Client(客户端)
        │
    Handler(抽象处理者)
        │
    ┌───┴──────────┐
ConcreteHandlerA  ConcreteHandlerB(具体处理者)
        │
      (next) →  下一个处理者

组成部分

  1. Handler(抽象处理者):定义 handle_request() 方法,声明处理请求的逻辑,并包含指向下一个处理者的引用。
  2. ConcreteHandler(具体处理者):实现 Handler,决定是否处理请求,或者将请求传递给下一个处理者
  3. Client(客户端):创建责任链并发送请求,客户端无需关心具体的处理者,只需传递请求即可。

二、责任链模式的应用场景

责任链模式适用于以下场景:

日志处理,不同级别的日志(DEBUG、INFO、ERROR)需要不同的处理方式。

权限管理,不同角色(普通用户、管理员、超级管理员)对请求的权限不同。

审批流程,如请假审批,经理、主管、总经理按照层级审批。

请求拦截器,如 Web 服务器中的中间件(权限校验、日志记录、限流等)。


三、责任链模式的 Python 实现

示例:审批流程(请假审批)

假设公司有一个请假审批流程,规则如下:

  • 普通员工(Supervisor) 可审批1天以内的假期。
  • 部门经理(Manager) 可审批3天以内的假期。
  • 总经理(Director) 可审批5天以内的假期,超过5天则拒绝。

我们使用责任链模式来构建审批流程,使请求能够沿着审批链传递。


代码实现

from abc import ABC, abstractmethod

# 1. 抽象处理者(Handler)
class Approver(ABC):
    """审批者基类"""
    def __init__(self, next_approver=None):
        self.next_approver = next_approver  # 下一个处理者

    @abstractmethod
    def handle_request(self, days):
        pass

# 2. 具体处理者(ConcreteHandler)
class Supervisor(Approver):
    """主管审批 1 天以内的假期"""
    def handle_request(self, days):
        if days <= 1:
            print(f"✅ 主管批准了 {days} 天的假期")
        elif self.next_approver:
            print("➡️ 主管无法审批,转交给经理...")
            self.next_approver.handle_request(days)

class Manager(Approver):
    """经理审批 3 天以内的假期"""
    def handle_request(self, days):
        if days <= 3:
            print(f"✅ 经理批准了 {days} 天的假期")
        elif self.next_approver:
            print("➡️ 经理无法审批,转交给总经理...")
            self.next_approver.handle_request(days)

class Director(Approver):
    """总经理审批 5 天以内的假期,超过 5 天拒绝"""
    def handle_request(self, days):
        if days <= 5:
            print(f"✅ 总经理批准了 {days} 天的假期")
        else:
            print(f"❌ 申请 {days} 天的假期被拒绝!")

# 3. 客户端代码(Client)
if __name__ == "__main__":
    # 构建审批链
    director = Director()  # 最高级别
    manager = Manager(director)  # 经理的上级是总经理
    supervisor = Supervisor(manager)  # 主管的上级是经理

    # 提交不同天数的请假申请
    print("\n--- 员工申请 1 天假期 ---")
    supervisor.handle_request(1)

    print("\n--- 员工申请 3 天假期 ---")
    supervisor.handle_request(3)

    print("\n--- 员工申请 5 天假期 ---")
    supervisor.handle_request(5)

    print("\n--- 员工申请 7 天假期 ---")
    supervisor.handle_request(7)

四、输出结果

--- 员工申请 1 天假期 ---
✅ 主管批准了 1 天的假期

--- 员工申请 3 天假期 ---
➡️ 主管无法审批,转交给经理...
✅ 经理批准了 3 天的假期

--- 员工申请 5 天假期 ---
➡️ 主管无法审批,转交给经理...
➡️ 经理无法审批,转交给总经理...
✅ 总经理批准了 5 天的假期

--- 员工申请 7 天假期 ---
➡️ 主管无法审批,转交给经理...
➡️ 经理无法审批,转交给总经理...
❌ 申请 7 天的假期被拒绝!

审批流程清晰,每个处理者只关注自己的职责,并将无法处理的请求传递给下一级处理者

可以动态调整审批链,如果增加 HR 角色 作为初级审批者,只需修改链条,而无需修改 handle_request() 逻辑。


五、责任链模式的优缺点

✅ 优点

解耦请求发送者和处理者,请求者无需关心具体的处理逻辑。

提高系统灵活性,可以随时调整审批链的顺序和数量。

符合开闭原则(OCP),可以新增处理者,而无需修改已有代码。

❌ 缺点

可能导致请求未被处理,如果没有合适的处理者,可能会导致请求被丢弃。

可能影响性能,如果责任链太长,可能会影响系统响应速度。


六、责任链模式 vs 其他模式

设计模式主要作用
责任链模式(Chain of Responsibility)按顺序处理请求,多个处理者可处理同一请求
策略模式(Strategy)选择最合适的策略来处理请求
观察者模式(Observer)多个观察者监听同一事件,并做出不同反应

如果请求需要按顺序传递,使用 责任链模式

如果请求可以有不同的处理策略,使用 策略模式


七、总结

责任链模式(Chain of Responsibility Pattern) 是一种行为型设计模式,它允许多个处理者按顺序处理请求,并提供动态扩展的能力,适用于审批流程、权限管理、日志处理等场景

希望本文能帮助你理解责任链模式,并在实际开发中应用它!🚀


📌 有什么问题和经验想分享?欢迎在评论区交流、点赞、收藏、关注! 🎯

更多推荐