Python设计模式:责任链模式

发布于:2025-04-03 ⋅ 阅读:(20) ⋅ 点赞:(0)

1. 什么是责任链模式?

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许将请求的发送者和接收者解耦。通过将多个处理对象连接成一条链,责任链模式可以让请求沿着这条链传递,直到有一个对象处理它为止。这种模式的核心思想是将请求的处理逻辑分散到多个处理者中,每个处理者负责处理特定类型的请求。

1.1 模式内容

责任链模式的主要组成部分包括:

处理者接口(Handler)

处理者接口定义了处理请求的基本方法,并包含一个指向下一个处理者的引用。这个接口通常包括一个方法,用于处理请求和设置下一个处理者。

class Handler:
    """处理者接口"""
    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

具体处理者(Concrete Handler)

具体处理者实现了处理者接口,负责处理特定类型的请求,并决定是否将请求传递给下一个处理者。每个具体处理者可以有自己的处理逻辑。

class ConcreteHandlerA(Handler):
    """具体处理者 A"""
    def handle(self, request):
        if request == "A":
            return f"Handler A handled request: {request}"
        else:
            return super().handle(request)


class ConcreteHandlerB(Handler):
    """具体处理者 B"""
    def handle(self, request):
        if request == "B":
            return f"Handler B handled request: {request}"
        else:
            return super().handle(request)


class ConcreteHandlerC(Handler):
    """具体处理者 C"""
    def handle(self, request):
        if request == "C":
            return f"Handler C handled request: {request}"
        else:
            return super().handle(request)

客户端(Client)

客户端负责创建具体处理者并设置责任链的顺序,发送请求。客户端不需要知道哪个处理者会处理请求,从而实现了请求的发送者和接收者之间的解耦。

# 客户端代码
handler_a = ConcreteHandlerA()
handler_b = ConcreteHandlerB()
handler_c = ConcreteHandlerC()

# 设置责任链
handler_a.set_next(handler_b).set_next(handler_c)

# 发送请求
print(handler_a.handle("A"))  # 输出: Handler A handled request: A
print(handler_a.handle("B"))  # 输出: Handler B handled request: B
print(handler_a.handle("C"))  # 输出: Handler C handled request: C
print(handler_a.handle("D"))  # 输出: None

1.2 含义

责任链模式的含义在于通过将请求的处理者组织成一个链条,使得请求可以在多个处理者之间传递。这样,客户端不需要直接与具体的处理者交互,而是通过责任链来处理请求。这种解耦的方式使得系统更加灵活,便于扩展和维护。

1.3 用途

责任链模式的用途广泛,适用于以下场景:

  • 多个处理者:当有多个对象可以处理请求,但不确定哪个对象会处理请求时,责任链模式可以提供灵活的处理机制。
  • 请求解耦:当希望将请求的发送者和接收者解耦时,责任链模式可以有效地实现这一目标。
  • 动态处理:当需要动态地改变处理请求的对象时,责任链模式允许在运行时修改链的结构。
  • 简化代码:通过将请求处理逻辑分散到多个处理者中,责任链模式可以减少条件语句的使用,使代码更加简洁和可读。

2. 示例 1:日志处理系统中的责任链模式

在一个日志处理系统中,可能需要根据日志的级别(如 DEBUG、INFO、WARNING、ERROR)将日志消息发送到不同的处理者。使用责任链模式,可以灵活地处理不同级别的日志请求,并将请求的发送者和接收者解耦。

class LogHandler:
    """日志处理者接口"""

    def __init__(self):
        self.next_handler = None  # 初始化 next_handler 属性

    def set_next(self, handler):
        self.next_handler = handler
        return handler

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


class DebugLogHandler(LogHandler):
    """处理 DEBUG 级别的日志"""

    def handle(self, level, message):
        if level == "DEBUG":
            return f"DEBUG: {message}"
        else:
            return super().handle(level, message)


class InfoLogHandler(LogHandler):
    """处理 INFO 级别的日志"""

    def handle(self, level, message):
        if level == "INFO":
            return f"INFO: {message}"
        else:
            return super().handle(level, message)


class WarningLogHandler(LogHandler):
    """处理 WARNING 级别的日志"""

    def handle(self, level, message):
        if level == "WARNING":
            return f"WARNING: {message}"
        else:
            return super().handle(level, message)


class ErrorLogHandler(LogHandler):
    """处理 ERROR 级别的日志"""

    def handle(self, level, message):
        if level == "ERROR":
            return f"ERROR: {message}"
        else:
            return super().handle(level, message)


# 客户端代码
debug_handler = DebugLogHandler()
info_handler = InfoLogHandler()
warning_handler = WarningLogHandler()
error_handler = ErrorLogHandler()

# 设置责任链
debug_handler.set_next(info_handler).set_next(warning_handler).set_next(error_handler)

# 发送日志请求
print(debug_handler.handle("DEBUG", "This is a debug message."))  # 输出: DEBUG: This is a debug message.
print(debug_handler.handle("INFO", "This is an info message."))  # 输出: INFO: This is an info message.
print(debug_handler.handle("WARNING", "This is a warning message."))  # 输出: WARNING: This is a warning message.
print(debug_handler.handle("ERROR", "This is an error message."))  # 输出: ERROR: This is an error message.
print(debug_handler.handle("TRACE", "This is a trace message."))  # 输出: None
  1. 处理者接口(LogHandler)

    • LogHandler 类定义了处理请求的基本结构,包括设置下一个处理者的方法和处理请求的方法。通过这种方式,所有具体处理者都可以继承这个接口,确保它们具有一致的行为。
  2. 具体处理者(Concrete Handlers)

    • DebugLogHandlerInfoLogHandlerWarningLogHandlerErrorLogHandler 类分别处理不同级别的日志请求。每个处理者都实现了自己的 handle 方法,检查请求的级别并决定是否处理该请求。如果当前处理者无法处理请求,它会调用 super().handle(level, message) 将请求传递给下一个处理者。
  3. 客户端代码

    • 客户端创建了多个具体处理者,并通过 set_next 方法将它们连接成一条责任链。客户端只需将请求发送到链的起始点(debug_handler),责任链会自动找到合适的处理者进行处理。
  4. 输出结果

    • 通过发送不同级别的日志请求,系统能够根据请求的级别返回相应的处理结果。对于未处理的请求(如 “TRACE”),系统返回 None,表明没有处理者能够处理该请求。

3. 示例 2:审批流程中的责任链模式

在一个审批流程系统中,可能需要根据请求的类型和金额将请求发送到不同的审批者。使用责任链模式,可以灵活地处理不同类型的审批请求,并将请求的发送者和接收者解耦。

class Approver:
    """审批者接口"""

    def __init__(self):
        self.next_approver = None  # 初始化下一个审批者

    def set_next(self, approver):
        self.next_approver = approver
        return approver

    def approve(self, request):
        if self.next_approver:
            return self.next_approver.approve(request)
        return None


class Manager(Approver):
    """经理审批者"""

    def approve(self, request):
        if request.amount <= 1000:
            return f"Manager approved request: {request.description} for amount: {request.amount}"
        else:
            return super().approve(request)


class Director(Approver):
    """董事审批者"""

    def approve(self, request):
        if request.amount <= 5000:
            return f"Director approved request: {request.description} for amount: {request.amount}"
        else:
            return super().approve(request)


class VicePresident(Approver):
    """副总裁审批者"""

    def approve(self, request):
        if request.amount <= 10000:
            return f"Vice President approved request: {request.description} for amount: {request.amount}"
        else:
            return super().approve(request)


class President(Approver):
    """总裁审批者"""

    def approve(self, request):
        return f"President approved request: {request.description} for amount: {request.amount}"


class Request:
    """审批请求类"""

    def __init__(self, description, amount):
        self.description = description  # 请求描述
        self.amount = amount              # 请求金额


# 客户端代码
manager = Manager()
director = Director()
vp = VicePresident()
president = President()

# 设置责任链
manager.set_next(director).set_next(vp).set_next(president)

# 创建请求
request1 = Request("Purchase office supplies", 500)        # 经理可以处理
request2 = Request("Team building event", 3000)            # 董事可以处理
request3 = Request("New software license", 8000)           # 副总裁可以处理
request4 = Request("Company expansion", 15000)             # 总裁处理

# 发送请求
print(manager.approve(request1))  # 输出: Manager approved request: Purchase office supplies for amount: 500
print(manager.approve(request2))  # 输出: Director approved request: Team building event for amount: 3000
print(manager.approve(request3))  # 输出: Vice President approved request: New software license for amount: 8000
print(manager.approve(request4))  # 输出: President approved request: Company expansion for amount: 15000
  1. 处理者接口(Approver)
    • Approver 类定义了处理请求的基本结构,包括设置下一个审批者的方法和处理请求的方法。通过这种方式,所有具体审批者都可以继承这个接口,确保它们具有一致的行为。
  2. 具体处理者(Concrete Approvers)
    • ManagerDirectorVicePresidentPresident 类分别处理不同金额的请求。每个处理者都实现了自己的 approve 方法,检查请求的金额并决定是否处理该请求。如果当前处理者无法处理请求,它会调用 super().approve(request) 将请求传递给下一个处理者。
  3. 请求类(Request)
    • Request 类用于表示审批请求,包含请求的描述和金额。
  4. 客户端代码
    • 客户端创建了多个具体审批者,并通过 set_next 方法将它们连接成一条责任链。客户端只需将请求发送到链的起始点(manager),责任链会自动找到合适的处理者进行处理。
  5. 输出结果
    • 通过发送不同金额的请求,系统能够根据请求的金额返回相应的处理结果。每个处理者根据自己的处理逻辑决定是否处理请求,确保了请求的动态处理和解耦。