设计模式-行为型-责任链模式

news/2025/2/27 10:47:43

1. 责任链模式概述

责任链模式(Chain of Responsibility Pattern) 是一种行为型设计模式,它允许多个对象依次处理请求,形成一条处理链。每个对象都包含对下一个对象的引用,如果它无法处理请求,则将请求传递给下一个对象。

责任链模式的主要特点

  • 降低耦合:请求的发送者和接收者解耦,发送者无需关心请求由谁处理。

  • 动态组合处理者:可以在运行时决定请求的处理顺序。

  • 增强灵活性:可以方便地增加或修改处理逻辑。

责任链模式的核心角色

  1. Handler(处理者接口):定义处理请求的方法,并包含一个指向下一个处理者的引用。

  2. ConcreteHandler(具体处理者):具体实现处理逻辑,如果无法处理请求,则传递给下一个处理者。

  3. Client(客户端):创建责任链,并向链的起点发送请求。


2. 责任链模式的 Python 实现

2.1 经典实现

python">class Handler:
    """处理者基类"""
    def __init__(self, successor=None):
        self.successor = successor  # 指向下一个处理者
    
    def handle_request(self, request):
        if self.successor:
            self.successor.handle_request(request)
python">class ConcreteHandlerA(Handler):
    def handle_request(self, request):
        if request == "A":
            print("ConcreteHandlerA 处理请求 A")
        elif self.successor:
            self.successor.handle_request(request)
python">class ConcreteHandlerB(Handler):
    def handle_request(self, request):
        if request == "B":
            print("ConcreteHandlerB 处理请求 B")
        elif self.successor:
            self.successor.handle_request(request)
python"># 创建责任链
handler_chain = ConcreteHandlerA(ConcreteHandlerB())

# 发送请求
handler_chain.handle_request("A")  # 由 ConcreteHandlerA 处理
handler_chain.handle_request("B")  # 由 ConcreteHandlerB 处理
handler_chain.handle_request("C")  # 无处理者响应

2.2 使用装饰器优化责任链

python">class Handler:
    def __init__(self):
        self.next_handler = None
    
    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

class AuthHandler(Handler):
    def handle(self, request):
        if request.get("auth", False):
            print("AuthHandler: 认证成功")
            return super().handle(request)
        print("AuthHandler: 认证失败")
        return None

class LoggingHandler(Handler):
    def handle(self, request):
        print("LoggingHandler: 记录日志")
        return super().handle(request)

# 创建责任链
handler_chain = AuthHandler()
handler_chain.set_next(LoggingHandler())

# 处理请求
request = {"auth": True}
handler_chain.handle(request)  # 认证成功 -> 记录日志

3. 责任链模式的优缺点

优点

降低耦合:请求的发送方和处理方解耦,灵活性提高。

动态组合处理者:可以根据需求动态修改责任链结构。

增强扩展性:新增处理逻辑时,只需增加新的处理者,无需修改已有代码。

缺点

请求可能未被处理:如果责任链没有合适的处理者,可能导致请求未被处理。

调试困难:由于请求可能经过多个处理者,调试可能较为复杂。

可能影响性能:如果责任链过长,可能导致请求的处理变慢。


4. 适用场景

责任链模式适用于以下场景:

  1. 多个对象可以处理同一请求,但具体由哪个对象处理在运行时确定(如日志记录、事件处理)。

  2. 希望避免请求发送者和接收者之间的强耦合(如权限验证)。

  3. 希望能动态调整处理者的顺序(如拦截器、过滤器链)。


5. 责任链模式的实际应用

5.1 Web 框架中的请求处理

在 Web 框架(如 Flask、Django)中,中间件(Middleware)通常采用责任链模式。例如:

python">class Middleware:
    def __init__(self, next_middleware=None):
        self.next = next_middleware
    
    def process_request(self, request):
        if self.next:
            return self.next.process_request(request)

class AuthMiddleware(Middleware):
    def process_request(self, request):
        if not request.get("authenticated", False):
            return "403 Forbidden"
        return super().process_request(request)

class LoggerMiddleware(Middleware):
    def process_request(self, request):
        print(f"Logging request: {request}")
        return super().process_request(request)

# 构建责任链
middleware_chain = AuthMiddleware(LoggerMiddleware())

# 处理请求
request = {"authenticated": True}
response = middleware_chain.process_request(request)
print(response)

5.2 事件处理系统

如 GUI 事件处理、游戏开发中键盘/鼠标事件的传递。

5.3 任务审批流程

如公司审批流程,经理审批后交给总监,总监审批后交给 CEO。


6. 总结

责任链模式通过将多个处理者串联成链,使得请求可以沿着链传递,直到被合适的处理者处理。这种模式有效降低了对象之间的耦合,提高了系统的灵活性和可扩展性。

责任链模式适用于 请求处理具有层次性或顺序性的场景,如日志记录、权限校验、Web 中间件等。


http://www.niftyadmin.cn/n/5869977.html

相关文章

支持selenium的chrome driver更新到133.0.6943.141

最近chrome释放新版本:133.0.6943.141 如果运行selenium自动化测试出现以下问题,是需要升级chromedriver才可以解决的。 selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only s…

JAVA-如何理解Mysql的索引

一、索引的概念 索引是一种特殊的文件,包含着对数据表里所有记录的引用(指针/地址)。可以对表中的一列或多列创建索引, 并指定索引的类型,各类索引有各自的数据结构实现。 二、索引是什么,用来干嘛 数据库中的表、数据、索引之间的…

IO 和NIO有什么区别?

IO 与 NIO 的区别详解 Java 中的 IO(Input/Output) 和 NIO(New IO 或 Non-blocking IO) 是两种不同的输入输出处理机制,主要区别体现在设计模型、性能优化和应用场景上。以下是详细对比: 1. 阻塞与非阻塞模…

【C++笔记】C++11智能指针的使用及其原理

【C笔记】C11智能指针的使用及其原理 🔥个人主页:大白的编程日记 🔥专栏:C笔记 文章目录 【C笔记】C11智能指针的使用及其原理前言1.智能指针的使用场景分析2. RAII和智能指针的设计思路3. C标准库智能指针的使用4. 智能指针的原…

CentOS 7 日志切割实战:Logrotate 详解与配置指南

文章目录 CentOS 7 日志切割实战:Logrotate 详解与配置指南Logrotate 简介安装与配置文件确认安装配置文件结构 核心配置参数详解实战配置案例案例1:Nginx 日志切割案例2:按大小切割应用日志案例3:Java 程序日志 test.log 切割配置…

Nginx安装并配置https

一、安装nginx 1、nginx压缩包上传到 /usr/local目录下 2、解压Nginx 压缩包 cd /usr/local tar -zxvf nginx-1.19.2.tar.gz 3、配置 Nginx 编译选项 cd nginx-1.19.2 ./configure 4、编译和安装 Nginx make make install 5、启动 Nginx cd /usr/local/nginx/sbin…

Feign 类型转换问题解析:如何正确处理 `ResponseEntity<byte[]>` 返回值

在微服务架构中,Feign 是一种常见的用于服务间调用的客户端,它允许我们通过声明式接口来调用远程服务。使用 Feign 时,我们通常通过接口方法的返回类型来接收服务的响应体。然而,某些情况下,我们会遇到 Feign 无法正确解析响应体类型的问题,尤其是当服务返回一个如 Respo…

局部适应的分子标记筛选

各种方法被用来揭示与适应性进化一致的分子印记。FST离群值分析(fst)扫描基因组以寻找基因座特异性效应,假设其反映了多样化或平衡选择,如较高的(阳性离群值)或更低(负离群值)遗传分化(FST)与中性背景水平相比,分别(Beaumont & Balding, 2004; Beaumont & N…