Python设计模式详解之22 ——职责链模式

Chain of Responsibility(职责链)设计模式详解

Chain of Responsibility(职责链)设计模式 是一种行为型设计模式,它允许多个对象依次处理一个请求,而无需知道请求的发送者或最终处理者。这种模式通过创建一条“职责链”,将请求沿着链传递,直到被某个对象处理或到达链的末端。


1. 定义

职责链模式将请求的处理逻辑分离到一系列的处理者对象中,客户端只需发出请求,无需关心具体由谁处理。每个处理者都有机会处理请求,或者将请求传递给下一个处理者。


2. 适用场景

  1. 多个对象可以处理同一请求,但具体由谁处理需要在运行时决定。
  2. 希望避免请求发送者和接收者之间的耦合
  3. 需要动态指定处理请求的链路或顺序

3. 结构

  1. Handler(抽象处理者)

    • 定义处理请求的方法,并持有对下一个处理者的引用。
  2. ConcreteHandler(具体处理者)

    • 实现处理请求的逻辑。如果不能处理请求,则将请求传递给下一个处理者。
  3. Client(客户端)

    • 创建并配置职责链,向链的起始处理者发送请求。

4. Python 实现

以下是一个模拟支持不同请求类型的职责链的示例。

示例:日志记录系统

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.

5. 优点和缺点

优点

  1. 解耦:请求的发送者和接收者解耦,客户端无需知道具体哪个对象会处理请求。
  2. 灵活性:职责链可以动态地添加或移除处理者。
  3. 扩展性:可以很容易地添加新的处理者,而无需修改现有代码。

缺点

  1. 请求可能未被处理:如果没有处理者能够处理请求,则请求可能被忽略。
  2. 调试复杂性:职责链中可能出现过长的链条,增加了调试的难度。

6. 扩展用法

6.1 表单验证系统

职责链模式适合表单验证,每个验证器负责一种验证规则。

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)

6.2 请求处理系统

职责链可用于处理不同种类的 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)

7. 总结

职责链模式通过将请求的处理分解为多个处理者,提高了系统的灵活性和扩展性。它适用于多层次处理需求或需要解耦请求与处理逻辑的场景。不过,使用时需注意链的长度和请求未处理的风险。Python 的动态特性也为职责链模式的实现提供了更多的简洁性和灵活性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拾工

雁过留声

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值