2023-7-11-第十六式职责链模式

简介: 2023-7-11-第十六式职责链模式

😉一、基础概念

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许多个对象按照顺序处理请求,而不需要显式指定接收者。每个处理对象都可以决定是否处理请求以及将请求传递给下一个对象。

在责任链模式中,通常有一个抽象处理器(Handler)作为基类,定义了处理请求的接口方法,并维护一个指向下一个处理器的引用。具体的处理器(Concrete Handler)继承抽象处理器,并实现自己的处理逻辑。每个处理器都能够根据自身的职责决定是否能够处理请求,如果可以,则进行处理,否则将请求传递给下一个处理器。

责任链模式的主要优点包括:

  • 解耦发送者和接收者:发送者无需知道处理请求的具体处理器,只需将请求传递给第一个处理器即可。
  • 可灵活添加或删除处理器:由于处理器之间通过引用链连接,因此可以方便地添加新的处理器或调整处理器的顺序,以满足不同的业务需求。
  • 支持动态组合:可以通过动态配置处理器的顺序和组合关系,实现不同的处理流程。

然而,责任链模式也存在一些注意事项:

  • 请求可能无法被处理:如果所有的处理器都无法处理某个请求,会导致请求没有得到处理,需要避免这种情况的发生。
  • 可能引起性能问题:由于请求会依次经过多个处理器,如果责任链过长或者处理器逻辑复杂,可能会影响性能。

总之,责任链模式非常适合处理具有多个处理环节且每个环节处理逻辑独立的场景,比如请求的处理流程是可变的、需要动态组合的情况下。


🐱‍🐉二、职责链模式实现

以下是一个简单的C++实现示例,展示了如何使用责任链模式:

#include <iostream>
// 抽象处理器
class Handler {
public:
    virtual void setNextHandler(Handler* next) = 0;
    virtual void handleRequest(int request) = 0;
};
// 具体处理器A
class ConcreteHandlerA : public Handler {
private:
    Handler* nextHandler;
public:
    void setNextHandler(Handler* next) override {
        nextHandler = next;
    }
    void handleRequest(int request) override {
        if (request <= 10) {
            std::cout << "ConcreteHandlerA 处理请求 " << request << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(request);
        }
    }
};
// 具体处理器B
class ConcreteHandlerB : public Handler {
private:
    Handler* nextHandler;
public:
    void setNextHandler(Handler* next) override {
        nextHandler = next;
    }
    void handleRequest(int request) override {
        if (request > 10 && request <= 20) {
            std::cout << "ConcreteHandlerB 处理请求 " << request << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(request);
        }
    }
};
// 具体处理器C
class ConcreteHandlerC : public Handler {
private:
    Handler* nextHandler;
public:
    void setNextHandler(Handler* next) override {
        nextHandler = next;
    }
    void handleRequest(int request) override {
        if (request > 20 && request <= 30) {
            std::cout << "ConcreteHandlerC 处理请求 " << request << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(request);
        }
    }
};
int main() {
    // 创建具体处理器对象
    ConcreteHandlerA handlerA;
    ConcreteHandlerB handlerB;
    ConcreteHandlerC handlerC;
    // 设置处理器之间的关系
    handlerA.setNextHandler(&handlerB);
    handlerB.setNextHandler(&handlerC);
    // 发送请求
    handlerA.handleRequest(5);
    handlerA.handleRequest(15);
    handlerA.handleRequest(25);
    return 0;
}

在上述示例中,我们定义了三个具体的处理器(ConcreteHandlerA、ConcreteHandlerB和ConcreteHandlerC),它们分别处理不同范围的请求。每个处理器都实现了setNextHandler方法来设置下一个处理器,并实现了handleRequest方法来处理请求或将请求传递给下一个处理器。

在main函数中,我们创建了具体处理器对象,并按照顺序设置处理器之间的关系。然后,我们通过调用第一个处理器的handleRequest方法发送请求,整个请求会依次经过处理器链进行处理,直到找到能够处理该请求的处理器,或者到达链的末尾。

运行代码,你将看到输出结果如下:

ConcreteHandlerA 处理请求 5
ConcreteHandlerB 处理请求 15
ConcreteHandlerC 处理请求 25

这个示例展示了职责链模式的基本使用方式。你可以根据具体场景和需求,扩展和定制处理器的逻辑,并设置不同的处理器顺序以满足业务要求。


🎉三、模块之间的关系

在责任链模式中,模块之间的关系可以分为以下几种角色和交互方式:

  1. 抽象处理器(Handler):
  • 定义了处理请求的接口方法。
  • 维护一个指向下一个处理器的引用。
  1. 具体处理器(Concrete Handler):
  • 继承自抽象处理器,并实现处理请求的具体逻辑。
  • 可以决定是否处理请求,如果无法处理,则将请求传递给下一个处理器。
  • 可以设置下一个处理器的引用,建立处理器链。
  1. 请求发送者(Client):
  • 创建处理器对象,并设置它们之间的关系,形成处理器链。
  • 将请求发送给第一个处理器来触发处理链的执行。
  1. 处理器链(Chain of Responsibility):
  • 由多个具体处理器组成的链状结构。
  • 每个处理器负责处理一部分请求,或将请求传递给下一个处理器。
  • 处理器链的顺序通常按照业务逻辑进行设置。

在责任链模式中,请求从发送者开始,经过处理器链的依次处理,直到找到能够处理该请求的处理器。处理器链的顺序是通过设置每个处理器的下一个处理器来建立的。处理器可以根据自身的职责决定是否能够处理请求,并可以选择将请求传递给下一个处理器。

通过这种方式,责任链模式实现了请求发送者和接收者之间的解耦,使得请求的处理流程可以动态调整和扩展。每个处理器都只需要关注自己的业务逻辑,而不需要知道整个处理流程的细节。

总之,责任链模式中的模块之间通过处理器链的方式相互连接,形成一条处理路径。处理器链的建立和处理器之间的交互,使得多个处理器能够协同工作来处理请求,提高系统的灵活性和可扩展性。


🐱‍🚀四、注意事项

在使用责任链模式时,需要注意以下几个事项:

  1. 避免形成循环链:在设置处理器之间的关系时,需要确保不会形成循环链,即一个处理器的下一个处理器不能再回到自身或者前面的处理器。否则,请求可能会陷入无限循环。
  2. 保证请求能够被处理:处理器链中至少应该有一个处理器能够处理请求,否则请求将无法得到处理。因此,在设计和配置处理器链时,需要确保每个请求都能够被正确地处理或传递给下一个处理器。
  3. 不要过度使用责任链:责任链模式适用于一系列相互独立且可变的处理环节,但并不是所有的场景都适合使用责任链模式。如果处理环节之间的耦合度很高,或者处理器之间的顺序和组合关系不常发生变化,那么使用责任链模式可能会增加系统复杂性,不利于维护和理解代码。
  4. 注意性能问题:由于请求经过多个处理器进行处理,如果责任链过长或者处理器逻辑复杂,可能会影响系统的性能。在实际使用中,需要根据具体情况进行评估和测试,以确保责任链模式的性能满足需求。
  5. 合理划分职责:每个处理器应该只关注自己的职责范围内的请求处理,不要将不相关的逻辑放在同一个处理器中。这有助于提高代码的可读性和可维护性。

总之,使用责任链模式时需要注意合理设计处理器链、避免循环链的出现,确保请求能够被正确处理或传递,以及关注性能问题和职责的划分。正确使用责任链模式可以提高系统的灵活性和可扩展性,但也需要根据具体情况进行评估和权衡。


🎂五、使用场景

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

  1. 处理流程具有多个环节:当业务操作需要经过一系列处理环节,每个环节可能由不同的处理器负责处理时,可以使用责任链模式。例如,订单处理系统中的订单审核、支付、发货等环节。
  2. 动态组合和调整处理流程:如果处理流程的组合和顺序需要根据不同情况进行动态调整,责任链模式可以提供灵活性。通过添加、删除或重新排列处理器,可以实现不同的处理流程。
  3. 解耦请求发送者和接收者:使用责任链模式可以解耦请求发送者和具体的处理器,使得发送者无需知道哪个处理器会处理请求。这样可以简化发送者的代码,且方便增加新的处理器。
  4. 多个对象可以处理同一请求:在某些情况下,一个请求可能被多个对象中的一个处理,而不是固定的某个对象。责任链模式允许多个对象按照顺序尝试处理请求,直到找到能够处理的对象。
  5. 避免请求的发送者与接收者之间的耦合:使用责任链模式可以降低请求发送者与接收者之间的耦合度。发送者只需将请求发送给第一个处理器,而不需要关心具体的处理器是谁,从而增加了系统的灵活性和可扩展性。

综上所述,职责链模式适用于处理具有多个环节且每个环节处理逻辑独立、处理流程需要动态组合或调整的场景。它能够提供灵活性、解耦请求发送者和接收者,并支持多个对象处理同一请求的情况。


🍳参考文献

🧊文章总结

提示:这里对文章进行总结:

   本文讲了关于职责链模式的知识。


目录
相关文章
|
机器学习/深度学习 自然语言处理 PyTorch
VLLM (Very Large Language Model)
VLLM (Very Large Language Model) 是一种大型语言模型,通常具有数十亿或数万亿个参数,用于处理自然语言文本。VLLM 可以通过预训练和微调来执行各种任务,如文本分类、机器翻译、情感分析、问答等。
1740 1
|
弹性计算 JavaScript Linux
ElasticSearch备份与恢复-elasticdump工具
ElasticSearch备份与恢复-elasticdump工具
|
SQL 分布式计算 MaxCompute
MaxCompute SQL使用小技巧之时间日期处理
业务需求分析中经常会对时间日期进行处理,MaxComputer中也有很多关于日期的处理函数,文章就是对这些内置函数相互嵌套使用达到分析要求的分析
6584 0
|
3月前
|
人工智能 前端开发 程序员
小米送了我 16 亿 tokens,给我测爽了!手把手教你领取 附 Claude Code + MiMo-V2.5 实战测评
大家好,我是程序员鱼皮。 最近大模型圈儿一直在神仙打架,给我测的头发都快掉光了。。。 GPT5.5 放话:我理解力最强! DeepSeek V4 紧接着表示:我性价比最高! 这时候犄角旮旯里传来一个弱弱的声音:我。。。我免费送 16 亿 tokens。。。 定睛一看,是小米。 4 月 23 号,小米正式发布了 MiMoV2.5 系列大模型,旗舰版 MiMoV2.5Pro 是个万亿参数的 MoE 架
1417 0
|
5月前
|
存储 人工智能 运维
实验室数字孪生系统技术架构与实现
本文以某大学AB研究楼数字孪生项目为蓝本,提出面向实验室场景的五层技术架构,融合BIM、IoT、AI与三维可视化,实现风险实时感知、应急推演、环境自调节、跨系统协同及科研数据沉淀,推动实验室运维从被动响应迈向智能自治。(239字)
|
存储 人工智能 自然语言处理
AI时代新宠,向量数据库
这篇文章介绍了向量数据库在生成式人工智能应用和大语言模型发展中的重要性,并介绍了几种主流的向量数据库产品,包括Milvus、Pipecone、Chroma、Weaviate、pgvector等。这篇文章详细介绍了向量数据库的概念和主流产品,对于了解向量数据库在人工智能领域的应用具有很好的参考价值。转载来自知乎:https://zhuanlan.zhihu.com/p/664747312,很好的科普文,自己收藏用。
|
SQL 关系型数据库 MySQL
Docker下载安装Nacos并完成持久化配置
Docker下载安装Nacos并完成持久化配置
2015 1
Docker下载安装Nacos并完成持久化配置
|
Java
进制转换、原码、反码、补码及位运算详解
进制转换、原码、反码、补码及位运算的简单示例
2098 1
进制转换、原码、反码、补码及位运算详解
|
SQL 关系型数据库 PostgreSQL
PostgreSQL 9.5+ 高效分区表实现 - pg_pathman
PostgreSQL 9.5+ 高效分区表实现 - pg_pathman 作者 digoal 日期 2016-10-24 标签 PostgreSQL , 分区表 , pg_pathman , custom scan api 背景 目前PostgreSQL社区版本的分区
30632 34

热门文章

最新文章