Python设计模式:责任链模式

1. 什么是责任链模式?

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

1.1 模式内容

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

处理者接口(Handler)

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

python 复制代码
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)

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

python 复制代码
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)

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

python 复制代码
# 客户端代码
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)将日志消息发送到不同的处理者。使用责任链模式,可以灵活地处理不同级别的日志请求,并将请求的发送者和接收者解耦。

python 复制代码
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:审批流程中的责任链模式

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

python 复制代码
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. 输出结果
    • 通过发送不同金额的请求,系统能够根据请求的金额返回相应的处理结果。每个处理者根据自己的处理逻辑决定是否处理请求,确保了请求的动态处理和解耦。
相关推荐
猷咪7 分钟前
C++基础
开发语言·c++
IT·小灰灰8 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧10 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q11 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳011 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾11 分钟前
php 对接deepseek
android·开发语言·php
vx_BS8133015 分钟前
【直接可用源码免费送】计算机毕业设计精选项目03574基于Python的网上商城管理系统设计与实现:Java/PHP/Python/C#小程序、单片机、成品+文档源码支持定制
java·python·课程设计
2601_9498683615 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
gzxx2007sddx21 分钟前
windows vnpy运行过程及问题记录
python·量化·vnpy
星火开发设计29 分钟前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识