Chain of Responsibility(职责链)设计模式 是一种行为型设计模式,它允许多个对象依次处理一个请求,而无需知道请求的发送者或最终处理者。这种模式通过创建一条“职责链”,将请求沿着链传递,直到被某个对象处理或到达链的末端。
职责链模式将请求的处理逻辑分离到一系列的处理者对象中,客户端只需发出请求,无需关心具体由谁处理。每个处理者都有机会处理请求,或者将请求传递给下一个处理者。
Handler(抽象处理者)
ConcreteHandler(具体处理者)
Client(客户端)
以下是一个模拟支持不同请求类型的职责链的示例。
from abc import ABC, abstractmethod
# 抽象处理者
class Handler(ABC):
def __init__(self, next_handler=None):
self.next_handler = next_handler
def set_next(self, handler):
self.next_handler = handler
@abstractmethod
def handle(self, request):
pass
# 具体处理者:处理 DEBUG 级别日志
class DebugHandler(Handler):
def handle(self, request):
if request["level"] == "DEBUG":
print(f"[DEBUG] {request['message']}")
elif self.next_handler:
self.next_handler.handle(request)
# 具体处理者:处理 INFO 级别日志
class InfoHandler(Handler):
def handle(self, request):
if request["level"] == "INFO":
print(f"[INFO] {request['message']}")
elif self.next_handler:
self.next_handler.handle(request)
# 具体处理者:处理 ERROR 级别日志
class ErrorHandler(Handler):
def handle(self, request):
if request["level"] == "ERROR":
print(f"[ERROR] {request['message']}")
elif self.next_handler:
self.next_handler.handle(request)
# 客户端
if __name__ == "__main__":
# 创建职责链
error_handler = ErrorHandler()
info_handler = InfoHandler(error_handler)
debug_handler = DebugHandler(info_handler)
# 发送请求
requests = [
{"level": "DEBUG", "message": "This is a debug message."},
{"level": "INFO", "message": "This is an info message."},
{"level": "ERROR", "message": "This is an error message."},
{"level": "WARNING", "message": "This is an unhandled warning message."},
]
for req in requests:
debug_handler.handle(req)
输出:
[DEBUG] This is a debug message.
[INFO] This is an info message.
[ERROR] This is an error message.
职责链模式适合表单验证,每个验证器负责一种验证规则。
class Validator(ABC):
def __init__(self, next_validator=None):
self.next_validator = next_validator
def set_next(self, validator):
self.next_validator = validator
@abstractmethod
def validate(self, data):
pass
class LengthValidator(Validator):
def validate(self, data):
if len(data) < 5:
print("Validation failed: Length is less than 5.")
return False
if self.next_validator:
return self.next_validator.validate(data)
return True
class DigitValidator(Validator):
def validate(self, data):
if not any(char.isdigit() for char in data):
print("Validation failed: No digit in input.")
return False
if self.next_validator:
return self.next_validator.validate(data)
return True
class SpecialCharValidator(Validator):
def validate(self, data):
if not any(char in "!@#$%^&*()" for char in data):
print("Validation failed: No special character in input.")
return False
if self.next_validator:
return self.next_validator.validate(data)
return True
if __name__ == "__main__":
# 创建验证链
validator_chain = LengthValidator(DigitValidator(SpecialCharValidator()))
# 测试输入
test_inputs = ["abc", "abcd1", "abc1!", "abc!"]
for input_data in test_inputs:
print(f"Validating: {input_data}")
if validator_chain.validate(input_data):
print("Validation successful!")
print("-" * 30)
职责链可用于处理不同种类的 API 请求。
class APIHandler(ABC):
def __init__(self, next_handler=None):
self.next_handler = next_handler
def set_next(self, handler):
self.next_handler = handler
@abstractmethod
def process_request(self, request):
pass
class AuthHandler(APIHandler):
def process_request(self, request):
if request.get("authenticated"):
print("Authentication successful.")
if self.next_handler:
self.next_handler.process_request(request)
else:
print("Authentication failed. Request denied.")
class LoggingHandler(APIHandler):
def process_request(self, request):
print(f"Logging request: {request}")
if self.next_handler:
self.next_handler.process_request(request)
class DataHandler(APIHandler):
def process_request(self, request):
print("Processing data...")
print("Data processed successfully.")
if __name__ == "__main__":
# 创建职责链
data_handler = DataHandler()
logging_handler = LoggingHandler(data_handler)
auth_handler = AuthHandler(logging_handler)
# 模拟请求
request = {"authenticated": True, "data": "sample data"}
auth_handler.process_request(request)
职责链模式通过将请求的处理分解为多个处理者,提高了系统的灵活性和扩展性。它适用于多层次处理需求或需要解耦请求与处理逻辑的场景。不过,使用时需注意链的长度和请求未处理的风险。Python 的动态特性也为职责链模式的实现提供了更多的简洁性和灵活性。