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
处理者接口(LogHandler):
LogHandler
类定义了处理请求的基本结构,包括设置下一个处理者的方法和处理请求的方法。通过这种方式,所有具体处理者都可以继承这个接口,确保它们具有一致的行为。
具体处理者(Concrete Handlers):
DebugLogHandler
、InfoLogHandler
、WarningLogHandler
和ErrorLogHandler
类分别处理不同级别的日志请求。每个处理者都实现了自己的handle
方法,检查请求的级别并决定是否处理该请求。如果当前处理者无法处理请求,它会调用super().handle(level, message)
将请求传递给下一个处理者。
客户端代码:
- 客户端创建了多个具体处理者,并通过
set_next
方法将它们连接成一条责任链。客户端只需将请求发送到链的起始点(debug_handler
),责任链会自动找到合适的处理者进行处理。
- 客户端创建了多个具体处理者,并通过
输出结果:
- 通过发送不同级别的日志请求,系统能够根据请求的级别返回相应的处理结果。对于未处理的请求(如 “TRACE”),系统返回
None
,表明没有处理者能够处理该请求。
- 通过发送不同级别的日志请求,系统能够根据请求的级别返回相应的处理结果。对于未处理的请求(如 “TRACE”),系统返回
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
- 处理者接口(Approver):
Approver
类定义了处理请求的基本结构,包括设置下一个审批者的方法和处理请求的方法。通过这种方式,所有具体审批者都可以继承这个接口,确保它们具有一致的行为。
- 具体处理者(Concrete Approvers):
Manager
、Director
、VicePresident
和President
类分别处理不同金额的请求。每个处理者都实现了自己的approve
方法,检查请求的金额并决定是否处理该请求。如果当前处理者无法处理请求,它会调用super().approve(request)
将请求传递给下一个处理者。
- 请求类(Request):
Request
类用于表示审批请求,包含请求的描述和金额。
- 客户端代码:
- 客户端创建了多个具体审批者,并通过
set_next
方法将它们连接成一条责任链。客户端只需将请求发送到链的起始点(manager
),责任链会自动找到合适的处理者进行处理。
- 客户端创建了多个具体审批者,并通过
- 输出结果:
- 通过发送不同金额的请求,系统能够根据请求的金额返回相应的处理结果。每个处理者根据自己的处理逻辑决定是否处理请求,确保了请求的动态处理和解耦。