Qt C++设计模式->责任链模式

devtools/2024/10/20 12:35:37/

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象有机会处理请求,而不需要明确指定哪个对象处理。通过将这些对象连成一条链,请求沿着链传递,直到有对象处理它为止。该模式的主要目标是使请求的发送者与接收者解耦,且能够动态调整处理链。

责任链模式的应用场景

责任链模式适用于当有多个对象可以处理一个请求,但具体由哪个对象处理在运行时才能确定的情况。它可以避免发送者和处理者之间的紧耦合。常见的应用场景包括:

  • 事件处理机制:例如GUI中的事件分发,某个控件未处理时,会传递给上层控件。

  • 日志处理:日志请求可以通过不同的级别(如DEBUG、INFO、ERROR)进行处理,责任链可以动态调整处理链。

责任链模式的核心

  • 处理者(Handler):每个处理者对象都包含对下一个处理者的引用,请求从第一个处理者开始,沿着链条依次传递。

  • 请求(Request):可以是客户端发出的任何类型的请求,如事件、命令或任务。

每个处理者都有两个选择:

  1. 处理请求。

  2. 将请求传递给下一个处理者。

责任链模式示例代码

假设你正在开发一个简单的日志系统,日志可以按照不同的级别(例如DEBUG、INFO、ERROR)进行处理。不同的日志级别可能需要不同的处理方式。

#include <QDebug>
#include <QString>// 抽象处理者类:定义日志处理接口
class Logger {
protected:Logger* next;  // 下一个处理者public:Logger() : next(nullptr) {}void setNext(Logger* nextLogger) {next = nextLogger;  // 设置下一个处理者}// 处理日志请求的方法void logMessage(const QString& level, const QString& message) {if (canHandle(level)) {handle(message);  // 当前处理者可以处理该请求} else if (next) {next->logMessage(level, message);  // 传递给下一个处理者} else {qDebug() << "Unhandled log level:" << level;}}virtual ~Logger() = default;protected:virtual bool canHandle(const QString& level) const = 0;  // 判断当前处理者是否能处理该请求virtual void handle(const QString& message) const = 0;    // 处理请求
};// 具体处理者类:处理DEBUG级别的日志
class DebugLogger : public Logger {
protected:bool canHandle(const QString& level) const override {return level == "DEBUG";  // 处理DEBUG日志}void handle(const QString& message) const override {qDebug() << "[DEBUG]:" << message;}
};// 具体处理者类:处理INFO级别的日志
class InfoLogger : public Logger {
protected:bool canHandle(const QString& level) const override {return level == "INFO";  // 处理INFO日志}void handle(const QString& message) const override {qDebug() << "[INFO]:" << message;}
};// 具体处理者类:处理ERROR级别的日志
class ErrorLogger : public Logger {
protected:bool canHandle(const QString& level) const override {return level == "ERROR";  // 处理ERROR日志}void handle(const QString& message) const override {qDebug() << "[ERROR]:" << message;}
};// 使用示例
int main() {// 创建具体处理者Logger* debugLogger = new DebugLogger();Logger* infoLogger = new InfoLogger();Logger* errorLogger = new ErrorLogger();// 设置责任链顺序:DEBUG -> INFO -> ERRORdebugLogger->setNext(infoLogger);infoLogger->setNext(errorLogger);// 发送不同级别的日志请求debugLogger->logMessage("DEBUG", "This is a debug message.");debugLogger->logMessage("INFO", "This is an info message.");debugLogger->logMessage("ERROR", "This is an error message.");debugLogger->logMessage("TRACE", "This is a trace message.");  // 未处理的日志级别// 清理内存delete debugLogger;delete infoLogger;delete errorLogger;return 0;
}

代码解析

  • Logger类:抽象处理者类,定义了处理日志请求的接口,并包含指向下一个处理者的指针。logMessage方法判断是否由当前处理者处理请求,如果不能处理,则传递给下一个处理者。

  • DebugLogger、InfoLogger、ErrorLogger类:具体处理者类,分别处理不同级别的日志(DEBUG、INFO、ERROR)。每个类都重写了canHandlehandle方法,根据日志级别处理相应的请求。

  • 客户端代码:客户端通过责任链发送不同级别的日志请求,链中的每个处理者依次判断是否处理该请求,未处理则传递给下一个处理者。

责任链模式的优点

  • 解耦请求发送者与处理者:请求发送者不需要知道具体哪个处理者会处理请求,减少了对象之间的耦合。

  • 灵活的请求处理链:可以在运行时动态修改处理链的结构,比如在链中添加或移除处理者,或者改变处理者的顺序。

  • 职责分离:每个处理者只关注处理自己能处理的请求,其余的请求交给下一个处理者处理,实现了职责的分离。

责任链模式的缺点

  • 可能导致请求处理无响应:如果没有合适的处理者能够处理请求,可能会导致请求被忽略。为了避免这一问题,可以在链的末端添加一个默认处理者,来处理所有未被处理的请求。

  • 性能开销:责任链的请求会被多个处理者依次传递,可能会导致链条过长,从而影响性能。

适合使用责任链模式的情况

  • 需要动态定义请求的处理顺序:在需要根据运行时条件动态定义处理顺序时,责任链模式非常适合。

  • 多个对象可以处理相同的请求:当多个对象可以处理同一类请求,但具体由哪个对象处理在运行时才确定时,使用责任链模式可以避免硬编码多个if-else语句。

  • 希望减少请求发送者与处理者的耦合责任链模式能够很好的解耦请求的发送者与请求的处理者,增加系统的灵活性。

Qt中的责任链模式应用

在Qt开发中,责任链模式可以用于事件处理机制。例如,Qt中的事件分发机制(QEvent)中,事件从最底层的组件传递到父组件,直到有组件处理该事件为止,这就是责任链模式的典型应用。此外,日志系统、命令处理等场景也可以通过责任链模式实现灵活的请求处理。

责任链模式能够很好地解耦请求发送者与处理者,同时提供了动态调整请求处理流程的能力,适合用于多个对象能够处理请求的场景。


http://www.ppmy.cn/devtools/122918.html

相关文章

Midjourney 中文版:释放创意,绘就无限可能

在人工智能与艺术创作激情碰撞的时代浪潮中&#xff0c;Midjourney 中文版宛如一颗璀璨的明珠带来了前所未有的创作体验。在艺术与科技交织的奇幻世界里&#xff0c;Midjourney 中文版宛如一把神奇的钥匙&#xff0c;解锁了无限创意的宝藏。 只需微信扫码即可快速登陆&#xf…

【ubuntu】如何升级g++

sudo apt-get install -y software-properties-common sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt update sudo apt install g-7 -y 1&#xff09;software-properties-common software-properties-common是一个基础软件包&#xff0c;包含了add-apt-repo…

配置Nginx以支持通过HTTPS回源到CDN

要配置Nginx以支持通过HTTPS回源到CDN&#xff0c;你需要确保Nginx已正确配置SSL&#xff0c;并且能够处理来自CDN的HTTPS请求。以下是一个简化的Nginx配置示例&#xff0c;它配置了SSL并设置了代理服务器参数以回源到CDN&#xff1a; server {listen 443 ssl;server_name you…

Go基本数据结构

1.jdk丰富的数据结构 Jdk提供了许多基本数据结构的实现&#xff0c;这些数据结构是Java Collections Framework的一部分&#xff0c;位于java.util包中。以下是一些常见的数据结构&#xff1a; ArrayList&#xff1a;一个可调整大小的数组实现&#xff0c;支持快速随机访问。 …

数据结构--堆的深度解析

目录 引言 一、基本概念 1.1堆的概念 1.2堆的存储结构 1.3堆的特点 二、 堆的基本操作 2.1初始化 2.2创建堆 2.3插入元素 2.4删除元素 2.5堆化操作 2.6堆的判空 2.7获取堆顶元素 三、堆的常见应用 1. 优先队列 2. 堆排序 3. Top-k 问题 4. 图论中的应用 四…

计算机毕业设计hadoop+spark天气预测 天气可视化 天气大数据 空气质量检测 空气质量分析 气象大数据 气象分析 大数据毕业设计 大数据毕设

Hadoop天气预测系统开题报告 一、研究背景与意义 在信息化和大数据时代&#xff0c;天气数据已成为社会生活和经济发展中不可或缺的重要资源。天气预测系统作为现代气象学的重要组成部分&#xff0c;对于农业生产、交通管理、环境保护以及防灾减灾等方面都具有重要意义。然而…

YOLOv8 基于NCNN的安卓部署

YOLOv8 NCNN安卓部署 前两节我们依次介绍了基于YOLOv8的剪枝和蒸馏 剪枝&#xff1a;https://blog.csdn.net/qq_41335232/article/details/140823592 蒸馏&#xff1a;https://blog.csdn.net/qq_41335232/article/details/142717122 开源代码&#xff1a;li554/yolov8_depl…

大厂面试真题:阿里经典双重检测DCL对象半初始化问题

阿里面试题中提到的双重检测DCL&#xff08;Double-Checked Locking&#xff09;对象半初始化问题&#xff0c;是Java多线程编程中一个经典的问题。以下是对这一问题的详细解析&#xff1a; 一、双重检测锁&#xff08;DCL&#xff09;概述 双重检测锁是一种用于实现单例模式…