Qt C++设计模式->责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象有机会处理请求,而不需要明确指定哪个对象处理。通过将这些对象连成一条链,请求沿着链传递,直到有对象处理它为止。该模式的主要目标是使请求的发送者与接收者解耦,且能够动态调整处理链。
责任链模式的应用场景
责任链模式适用于当有多个对象可以处理一个请求,但具体由哪个对象处理在运行时才能确定的情况。它可以避免发送者和处理者之间的紧耦合。常见的应用场景包括:
-
事件处理机制:例如GUI中的事件分发,某个控件未处理时,会传递给上层控件。
-
日志处理:日志请求可以通过不同的级别(如DEBUG、INFO、ERROR)进行处理,责任链可以动态调整处理链。
责任链模式的核心
-
处理者(Handler):每个处理者对象都包含对下一个处理者的引用,请求从第一个处理者开始,沿着链条依次传递。
-
请求(Request):可以是客户端发出的任何类型的请求,如事件、命令或任务。
每个处理者都有两个选择:
-
处理请求。
-
将请求传递给下一个处理者。
责任链模式示例代码
假设你正在开发一个简单的日志系统,日志可以按照不同的级别(例如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)。每个类都重写了
canHandle和handle方法,根据日志级别处理相应的请求。 -
客户端代码:客户端通过责任链发送不同级别的日志请求,链中的每个处理者依次判断是否处理该请求,未处理则传递给下一个处理者。
责任链模式的优点
-
解耦请求发送者与处理者:请求发送者不需要知道具体哪个处理者会处理请求,减少了对象之间的耦合。
-
灵活的请求处理链:可以在运行时动态修改处理链的结构,比如在链中添加或移除处理者,或者改变处理者的顺序。
-
职责分离:每个处理者只关注处理自己能处理的请求,其余的请求交给下一个处理者处理,实现了职责的分离。
责任链模式的缺点
-
可能导致请求处理无响应:如果没有合适的处理者能够处理请求,可能会导致请求被忽略。为了避免这一问题,可以在链的末端添加一个默认处理者,来处理所有未被处理的请求。
-
性能开销:责任链的请求会被多个处理者依次传递,可能会导致链条过长,从而影响性能。
适合使用责任链模式的情况
-
需要动态定义请求的处理顺序:在需要根据运行时条件动态定义处理顺序时,责任链模式非常适合。
-
多个对象可以处理相同的请求:当多个对象可以处理同一类请求,但具体由哪个对象处理在运行时才确定时,使用责任链模式可以避免硬编码多个if-else语句。
-
希望减少请求发送者与处理者的耦合:责任链模式能够很好的解耦请求的发送者与请求的处理者,增加系统的灵活性。
Qt中的责任链模式应用
在Qt开发中,责任链模式可以用于事件处理机制。例如,Qt中的事件分发机制(QEvent)中,事件从最底层的组件传递到父组件,直到有组件处理该事件为止,这就是责任链模式的典型应用。此外,日志系统、命令处理等场景也可以通过责任链模式实现灵活的请求处理。
责任链模式能够很好地解耦请求发送者与处理者,同时提供了动态调整请求处理流程的能力,适合用于多个对象能够处理请求的场景。
相关文章:
Qt C++设计模式->责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象有机会处理请求,而不需要明确指定哪个对象处理。通过将这些对象连成一条链,请求沿着链传递,直到有对象处理它为止。该模式…...
paypal支付v2.0(php)支付代码
第一步:获取access_token: <?php$clientId ; // 替换为你的 PayPal Client ID $clientSecret ; // 替换为你的 PayPal Client Secret// PayPal API 请求的 URL $url "https://api-m.sandbox.paypal.com/v1/oauth2/token";// 初始化 cURL $ch …...
基于Python的自然语言处理系列(23):DrQA
在本篇文章中,我们将实现 DrQA 模型,该模型最初由论文 Reading Wikipedia to Answer Open-Domain Questions 提出。DrQA 是一种用于开放域问答系统的端到端解决方案,最初包括信息检索模块和深度学习模型。本次实现中,我们主要探讨 DrQA 的深度学习模型部分。 1. 数据加载 …...
誉天Linux云计算课程学什么?为什么保障就业?
一个IT工程师相当于干了哪些职业? 其中置顶回答生动而形象地描绘道: 一个IT工程师宛如一个超级多面手,相当于——加班狂程序员测试工程师实施工程师网络工程师电工装卸工搬运工超人。 此中酸甜苦辣咸,相信很多小伙伴们都深有体会。除了典…...
无人机控制和飞行、路径规划技术分析
无人机控制和飞行、路径规划技术是现代无人机技术的核心组成部分,它们共同决定了无人机的性能和应用范围。以下是对这些技术的详细分析: 一、无人机控制技术 无人机控制技术主要涉及飞行控制系统的设计、传感器数据的处理以及指令的发送与执行。飞行控…...
【C++】模拟实现红黑树
🦄个人主页:修修修也 🎏所属专栏:实战项目集 ⚙️操作环境:Visual Studio 2022 目录 一.了解项目功能 二.逐步实现项目功能模块及其逻辑详解 📌实现RBTreeNode类模板 🎏构造RBTreeNode类成员变量 🎏实现RBTreeNode类构…...
离线安装docker
背景描述 项目需要在研发环境虚拟机上安装docker部署应用。 所在的服务器是一个内网,无法访问到外网环境。 服务器OS版本是 麒麟V10 linux 安装docker 安装包下载 获取所需版本的docker binary包,官方链接https://download.docker.com/linux/stati…...
MySQL高阶2066-账户余额
目录 题目 准备数据 分析数据 总结 题目 请写出能够返回用户每次交易完成后的账户余额. 我们约定所有用户在进行交易前的账户余额都为0, 并且保证所有交易行为后的余额不为负数。 返回的结果请依次按照 账户(account_id), 日期( day ) 进行升序排序…...
《RabbitMQ篇》Centos7安装RabbitMQ
安装RabbitMQ 安装包网盘下载地址 链接:https://pan.baidu.com/s/1bG_nP0iCdAejkctFp1QztQ?pwd4mlw 先上传安装包到服务器(erlang-23.3.4.11-1.el7.x86_64.rpm和rabbitmq-server-3.9.16-1.el7.noarch.rpm)然后使用指令安装 # 安装 erlang r…...
昇思学习打卡营第31天|深度解密 CycleGAN 图像风格迁移:从草图到线稿的无缝转化
1. 简介 图像风格迁移是计算机视觉领域中的一个热门研究方向,其中 CycleGAN (循环对抗生成网络) 在无监督领域取得了显著的突破。与传统需要成对训练数据的模型如 Pix2Pix 不同,CycleGAN 不需要严格的成对数据,只需两类图片域数据,…...
跟我学C++中级篇——空值的定义
一、空值 在提到c/c的空值时,先扯远一些。谈一谈数学中的0,0的出现要晚于其它的数,而0的出现却引发了数学的极大的发展和进步。而在计算机科学中,在使用一个变量时,它的值的可能性有很多,其中,…...
(三)Mysql 数据库系统全解析
一、Mysql 数据库 数据库的作用和优势 作用:集中化存储结构性的数据。优势: 减小数据冗余,避免数据的重复存储。保证数据的真实有效和唯一性,提高数据的质量。方便数据共享访问,使得不同的用户和应用可以方便地获取所需…...
SAP HCM 0001信息类型一个月内有多个成本中心
一般跨部门调动时候,成本中心都会变化,SAP默认都是读取wpbp的最后一一条数据,但是今天过账会读取两个单位的成本中心,一直都觉得很奇怪,SAP如何都拆分出这样的情况, 没办法只有debug,初始化系统…...
字节输入流
1.是什么 字节输入流(Byte Input Stream)在Java中是用来读取原始字节流的数据。Java的java.io包提供了多种字节输入流类,其中InputStream是所有字节输入流类的超类。以下是关于字节输入流的详细解释和举例: 字节输入流的概念&…...
深度学习-----------------机器翻译与数据集
目录 机器翻译与数据集下载和预处理数据集预处理步骤词元化词汇表该部分总代码 固定长度阶段或填充该部分总代码 转换成小批量数据集用于训练训练模型总代码 机器翻译与数据集 import os import torch from d2l import torch as d2l下载和预处理数据集 #save d2l.DATA_HUB[fr…...
SOMEIP_ETS_151: SD_Send_triggerEventUINT8Reliable_Eventgroup_2
测试目的: 验证DUT在Tester订阅事件组后,能够响应Tester触发的triggerEventUINT8Reliable方法,并将TestEventUINT8Reliable事件发送到订阅请求中端点选项指定的IP地址和端口。 描述 本测试用例旨在确保DUT能够正确处理事件组的订阅请求&am…...
32 C 语言指针的长度与运算(指针加减整数、指针自增自减、同类型指针相减、指针的比较运算)
目录 1 指针的长度 2 指针与整数的加减运算 3 指针自增与自减 4 同类型指针相减 5 指针的比较运算 6 测试题 1 指针的长度 在 C 语言中,sizeof 运算符可以用来计算指针的长度。指针的长度实际上与指针所指向的数据类型无关,而是与系统的位数&…...
【系统架构设计师】经典论文:轮软件三层架构设计
更多内容请见: 备考系统架构设计师-核心总结目录 文章目录 摘要正文总结摘要 本人于 2022 年 1 月参与了中石化 XX 油田 XX 采油厂“用电管理系统”的项目建设,该系统建设目标是实现分单位、分线路、分系统评价、优化、考核,全面提升采油厂用 电管理水平。在该项目组中我担…...
(C语言贪吃蛇)13.实现贪吃蛇四方向的移动
目录 前言 原代码预览 解决方法⚠️ 运行效果 总结 前言 我们上节通过Linux线程实现了两个while(1)同时运行,这样就可以一边控制方向一遍刷新出贪吃蛇的身体节点了。本节我们就来实现贪吃蛇四方向的移动。 (此图片为最终效果) 原代码预览 我们之前的代码是通过…...
Spring Boot + MyBatis 项目中常用注解详解(万字长篇解读)
Spring Boot MyBatis 项目中常用注解详解 在现代Java开发中,Spring Boot和MyBatis是两大热门框架,广泛应用于构建高效、可维护的企业级应用。两者结合使用,可以充分发挥各自的优势,提高开发效率和代码质量。在这个过程中&#x…...
RK Android14 开机自启APP分析与使用
文章目录 前言 一、功能补丁 二、如何使用 1. 应用补丁 2. 设置自启动应用 3. 获取应用包名和Activity 4. 验证 总结 前言 根据客户需要,有时需要设置第三方的apk进行开机自启动。 一、功能补丁 功能分析: 系统启动完成后,自动启动系统属性 persist.sys.start.app 中配置的…...
2026年,正规GEO优化排名公司将如何引领行业新潮流?
在AI搜索全面普及的当下,GEO(生成式引擎优化)成为企业突破曝光瓶颈的核心赛道。到2026年,正规GEO优化排名公司将凭借其专业能力和创新策略,引领行业迈向新的发展阶段。以[上海铪铪网络科技有限公司]为例,我…...
Python无锁并发避坑手册(20年C Python核心贡献者亲授:从字节码级锁定到原子内存序的17个致命盲区)
第一章:Python无锁并发的本质与GIL真相Python常被误认为“天生支持多线程并发”,但其核心限制源于全局解释器锁(Global Interpreter Lock, GIL)。GIL并非语言规范,而是CPython解释器为内存管理安全而引入的互斥机制——…...
Flink的反压机制
目录 1. 什么是反压? 2. Flink 反压机制的演变 第一代:基于 TCP 的传播(Flink 1.5 之前) 第二代:基于信用制的反压(Flink 1.5+,当前版本) 3. 基于信用制的反压详解 核心组件 工作流程(对应上图) 优势 4. 如何识别和处理反压? 识别(通过 Flink Web UI) …...
UNIX设计哲学:一切皆文件的原理与应用
1. UNIX 设计哲学的核心:"一切皆文件"在计算机操作系统的演进历程中,UNIX系统以其简洁而强大的设计哲学独树一帜。作为一名长期与UNIX/Linux系统打交道的开发者,我深刻体会到"一切皆文件"这一理念对整个计算机领域产生的…...
大厂真实高频的 LLM 大模型面试 36 题例题详解
一、基础原理篇(8 题) 1. 什么是 Transformer?核心结构是什么? 答:Transformer 是基于自注意力机制的 seq2seq 模型,完全替代 RNN 结构。核心结构: Encoder(编码)+ Decoder(解码) 多头注意力(Multi-Head Attention) 前馈网络 FFN 层归一化、残差连接举例:GPT 只…...
中文NLP入门首选:bert-base-chinese预训练模型快速部署指南
中文NLP入门首选:bert-base-chinese预训练模型快速部署指南 1. 为什么选择bert-base-chinese模型 如果你刚开始接触中文自然语言处理,bert-base-chinese绝对是最佳起点。这个由Google发布的预训练模型,已经成为中文NLP领域的"瑞士军刀…...
高效搭建个人知识管理系统:基于kepano-obsidian的完整指南
高效搭建个人知识管理系统:基于kepano-obsidian的完整指南 【免费下载链接】kepano-obsidian My personal Obsidian vault template. A bottom-up approach to note-taking and organizing things I am interested in. 项目地址: https://gitcode.com/gh_mirrors/…...
Megatron-LM源码解析:Tensor与Sequence并行训练中的通信优化策略
1. Megatron-LM并行训练基础概念 在分布式训练领域,Megatron-LM已经成为大规模语言模型训练的事实标准框架。我第一次接触这个框架时,就被它精妙的并行设计所震撼。Tensor并行和Sequence并行是其中两种核心并行策略,理解它们的通信机制对优化…...
Go语言中的正则表达式
Go语言中的正则表达式 1. 正则表达式的基本概念 正则表达式是一种用于匹配字符串中字符组合的模式。在Go语言中,正则表达式通过regexp包来实现。 2. 基本用法 2.1 编译正则表达式 package mainimport ("fmt""regexp" )func main() {// 编译正则…...
