当前位置: 首页 > news >正文

Python设计模式:责任链模式

1. 什么是责任链模式?

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

1.1 模式内容

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

处理者接口(Handler)

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

class Handler:"""处理者接口"""def set_next(self, handler):self.next_handler = handlerreturn handlerdef 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 = handlerreturn handlerdef handle(self, level, message):if self.next_handler:return self.next_handler.handle(level, message)return Noneclass 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 = approverreturn approverdef approve(self, request):if self.next_approver:return self.next_approver.approve(request)return Noneclass 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. 输出结果
    • 通过发送不同金额的请求,系统能够根据请求的金额返回相应的处理结果。每个处理者根据自己的处理逻辑决定是否处理请求,确保了请求的动态处理和解耦。

http://www.mrgr.cn/news/96816.html

相关文章:

  • Foldseek快速蛋白质结构比对
  • 【C++初阶】---类和对象(下)
  • 【Linux】系统文件的权限管理
  • Ubuntu修改用户名
  • Spring 面经
  • k8s运维面试总结(持续更新)
  • Python入门(5):异常处理
  • 基础算法篇(3)(蓝桥杯常考点)—图论
  • uniapp APP端在线升级(简版)
  • 量子计算与人工智能融合的未来趋势
  • 机器人--ros2--IMU
  • 图片边缘采样
  • dubbo http流量接入dubbo后端服务
  • Android学习之计算器app(java + 详细注释 + 源码)
  • 在Windows下使用Docker部署Nacos注册中心(基于MySQL容器)
  • 华为交换综合实验——VRRP、MSTP、Eth-trunk、NAT、DHCP等技术应用
  • MySQL数据库学习笔记1.SQL(1)
  • 使用 GitHub Pages 快速部署静态网页
  • Mysql之事务(下)
  • Linux安装Ubuntu24.04系统 并安装配置Nvidia 4090 显卡驱动