使用Proxy设计模式来增强类的功能:ToastProxy和DesktopToast的设计关系

使用代理模式来增强类的功能:ToastProxy和DesktopToast

Documentation: v1.0.0 Specified for Version v1.12.0,First Release in 2025/7/12

Documenation belongs to Projects: Charliechen114514/CCIMXDesktop: This is a Simple Desktop with Common Utilities for Embedded Device System using Qt6

前言

​ 这个算设计模式的部分,笔者当时正在设计的是如何让我的Desktop支持扩展的从Protocol Json Buffer转换到我的Toast可以识别的Meta Info的问题。这也是笔者写下这篇设计文档的原因——设计文档鸽了一个月(之前一直认为这个项目还没有成型的框架,因此迟迟没有动笔)

关于Proxy设计模式

​ 笔者很早就学习过设计模式,至少接触过一部分,Proxy,英语好的朋友知道,这是代理的意思。代理大伙都知道代理人,替本人出任做工作的代理人。这里我们说的代理,就是提供一个新的类代理旧的类,当然,如果是完全做一样的事情,我们没必要请出Proxy,对吧。那么,Proxy显然要比原先的类多做一部分工作,在笔者看来,Proxy设计模式是对原对象一次无痛(什么是无痛的?指的是不会改动原有类的任何功能,通过和其他类的协作达到增强原有类可以做的事情)扩展。

​ 现在说说笔者遇到的问题,看过笔者DesktopToast源码的朋友就知道,DesktopToast是一个简单的通知栏滑动类,实际上,我们最关心也是他最本职的功能是这个:

class DesktopToast : public QWidget {Q_OBJECT
public:/*** @brief Construct a new Desktop Toast object* * @param parent */explicit DesktopToast(QWidget* parent = nullptr);/*** @brief set_message push the toast display into the* toast display sessions* @param message* @note this will make a queue like display.* so, if the toast is currently animating, it will not display the new* messages immediately, but wait until the current message is finished*/void set_message(const QString& message);... // 下面的工作是私有成员,set message就是告诉我们的 toast显示什么东西,很简单吧!

​ 非常好,但是现在呢,笔者正在抽象一个服务类,简单的讲,就是监听一个特定的文件夹下的json文件解析满足ToastMetaProtocol要求格式的json文件,一旦监听到新的文件,我们就做解析转换,发送信号交给一个类处理并且做显示,由于我们使用的是Qt,他是按照信号的方式进行传递的,笔者经过权衡考虑,认为设计一个类来作为代表,比堆一大堆函数的串行调用要靠谱(真不敢想后者的可扩展性。。。)

​ 经过笔者的一番折腾,现在我们的Server类非常的干净

/*** @brief The ToastPostServer class* This is a server of toast infomation level*/
class ToastPostServer : public DesktopServerBase {Q_OBJECT
public:ToastPostServer(DesktopToast* toast, const QString& monitoring_path, QObject* parent);private:// 这里就是放Toast嘛?显然不行!ToastReceiver* receiver;
};

​ 其中Receiver类也很简单,他将监听到的新的Json file转化成我规定的ToastMetaProtocol对象,在一次信号发射中携带ToastMetaProtocol对象走出去,但是现在问题来了,我们的DesktopToast本身不支持ToastMetaProtocol,而且他是特定于我们桌面系统的一个类,如果我强行修改了DesktopToast类,我之后就没法在其他地方复用了,这咋办呢?我也不想继承,因为我不想对其他冗余的接口占用(虽然也是办法,但是实际上后面我还会增强关于Toast本身的调用,我还要修改一大堆代码防止客户调用父类的Partial的功能乱改一通)。归根揭底,是因为我们在这里是要求DesktopToast类按照一定的顺序和其他相关的类进行协作,本质上不算DesktopProxy对象的工作,我们不能强行算在DesktopToast头上。

​ 这就是下面这个类的功能了:

#ifndef TOASTPROXY_H
#define TOASTPROXY_H
#include "core/server/toast_file_gen_and_receiver/ToastMetaProtocol.h"
class DesktopToast;
class ToastProxy : public QObject {
public:ToastProxy() = delete;explicit ToastProxy(DesktopToast* toast, QObject* parent);
public slots:void process_toastMeta(const ToastMetaProtocol& protocolMeta);private:DesktopToast* toast;
};#endif // TOASTPROXY_H

​ ToastProxy作为代理对象,增强(延展)了我们的DesktopToast的功能

  • 接收上层组件(如 ToastReceiver)传来的 ToastMetaProtocol 对象;
  • 解析并转化为 DesktopToast 可处理的格式;
  • DesktopToast 发起消息展示;
  • 为未来可能新增的中间处理(如日志、过滤、限流等)提供扩展点。

​ 这里的一个具体的增强就体现在process_toastMeta,一方面我们的对象可以接受其他对象对我们DesktopToast的通知,而不是直接沟通增加强耦合,而是去隔一层ToastProxy的转化功能发给DesktopToast可以听懂的功能,这样的话,任何的扩展的协作的功能,都可以直接在ToastProxy上加,丝毫不会影响两侧使用这个类做事情和被要求做的事情的类的任何一点行为。这就是代理模式在这里的一次使用。

​ 现在有了这个类,我们的调用链看起来就像:

ToastPostServer|v
ToastReceiver  --- (signal: protocolMetaReady) -->  ToastProxy  --- (call) --> DesktopToastv
ToastReceiver  --- (signal: protocolMetaReady) -->  ToastProxy  --- (call) --> DesktopToast

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/89860.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89860.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

瑞芯微2025开发者大会之见闻

序言本人参加了2025年的瑞芯微开发者大会,在展览区看到了很多有意思的音视频产品,下面按照产品类型分类给大家做一下展示。期间并没有将所有展出物进行拍摄,但是基本已经覆盖大部分内容。1、RK3566该芯片内置DSP音频处理器,蓝牙5.…

【最新】Java的几种设计模式详解及适用业务场景

✅ 1. 单例模式(Singleton) 定义:确保类只有一个实例,并提供全局访问点。优点:节省资源、控制访问。场景:数据库连接池、日志管理器、配置中心。代码要点: 构造方法私有静态变量保存唯一实例公共…

单链表的手动实现+相关OJ题

目录 链表的介绍 单链表的手动实现 单链表的基本框架 打印链表: 获取表长: 头插法新增节点: 尾插法新增节点: 在指定下标插入: 链表的查找 删除链表中第一个出现的key: 删除链表中所有key值 链表…

梯度提升之原理

简介 梯度提升主要是基于数学最值问题 数学描述 目标函数为 obj(θ)∑i1nl(yi,y^i(t))∑k1tw(fk)obj(\theta) \sum_{i1}^n l(y_i, \hat y_i^{(t)}) \sum_{k1}^t w(f_k)obj(θ)i1∑n​l(yi​,y^​i(t)​)k1∑t​w(fk​) 其中ttt表示集成的树的个数,y^i(t)y^i(t−1)…

[学习] Hilbert变换:从数学原理到物理意义的深度解析与仿真实验(完整实验代码)

Hilbert变换:从数学原理到物理意义的深度解析与仿真实验 文章目录Hilbert变换:从数学原理到物理意义的深度解析与仿真实验一、数学原理二、作用与物理意义1.构造解析信号2.相位移动特性3.应用场景三、仿真实验实验1:正弦信号的Hilbert变换实验…

对话弋途科技:当AI重构汽车大脑,一场车载操作系统的“觉醒年代“开始了

(图片来源:Pixels)站在未来看历史,AI汽车刚刚开始。数科星球原创作者丨苑晶编辑丨大兔当特斯拉的自动驾驶仍在全球引发争议时,中国智能汽车战场已悄然开启第二幕。从"四个轮子的大手机"到"移动智能空间…

❗机器学习量化交易模型全面剖析报告基于因子库的机器学习交易模型构建指南

目录 第一章:机器学习在加密货币量化交易中的应用概述 范式转变:从传统因子到机器学习驱动的策略 为什么选择机器学习?机遇、挑战与核心概念 机遇 挑战 核心概念 第二章:为机器学习准备您的因子库 理解量化因子作为机器学…

内容创作智能体:多模态内容生成的完整解决方案

内容创作智能体:多模态内容生成的完整解决方案 🌟 嗨,我是IRpickstars! 🌌 总有一行代码,能点亮万千星辰。 🔍 在技术的宇宙中,我愿做永不停歇的探索者。 ✨ 用代码丈量世界&…

测试学习之——Pytest Day4

Pytest作为Python中功能强大且易于使用的测试框架,深受开发者喜爱。它不仅提供了简洁的测试编写方式,还通过丰富的配置选项、灵活的标记机制和强大的数据驱动能力,极大地提升了测试效率和可维护性。本文将深入探讨Pytest的配置意义与层级、常…

【软件系统架构】系列七:系统性能——路由器性能深入解析

目录 一、路由器的核心功能 二、路由器性能核心指标 1. 吞吐量(Throughput) 2. 并发连接数(Session Capacity) 3. 每秒连接数(CPS,Connections Per Second) 4. 转发延迟(Laten…

【数据结构】第一讲 —— 概论

【数据结构】第一讲 —— 概论 文章目录【数据结构】第一讲 —— 概论1.1 基本概念和常用术语1.2 了解数据结构1. 数据结构2. 数据的逻辑结构3. 数据的物理结构(存储结构)4. 数据的运算1.3 算法的描述和分析1.3.1 算法的描述1.3.21.1 基本概念和常用术语…

全面解析MySQL(2)——CRUD基础

1.CreateCreate(创建):添加新数据到数据库中#基础语法 insert into table_name (column1,column2,column3, ...) values (value1,value2,value3, ...);1.1 单行全列插入value中值的数量和顺序必须和column⼀致describe demo1; -----------------------------------…

某外企笔试总结——纯C语言

这里写自定义目录标题一、sizeof 计算(32位环境)二、简答题三、数据存储区域与可修改性四、字符串比较输出及原因五、数组指针运算输出六、字符串倒序代码错误排查七、下面程序可以把1维数组转为2维数组,然后调用 printArr2D 打印出数组内容&…

Qt Graphs 模块拟取代 charts 和 data visualization还有很长的路要走

近期关注 Qt 6.10 的分支进展, 发现了 Qt 6.10 的 charts 和 data visualization (以下简称 DV)已经被deprecated, 功能将会合并到 graphs 模块。如果后面 charts\ DV 被弃用,那算是很大的API变化了。从Qt 6.5 以后开始引入的 gra…

2025牛客暑期多校训练营2(部分补题)

题目链接:牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ B Bitwise Perfect 思路 考虑到由,那么只有变小的时候对答案的贡献才能够减少,从二进制的角度考虑什么时候变小,只有min(x,y)中的最高位1异或之后变…

Nginx的location匹配规则

Nginx的location匹配规则 为什么你的Nginx配置总是不生效? 改了Nginx配置无数次,reload命令执行了几十遍,浏览器访问时却依然返回404?运维工程师小张上周就遇到了这个问题:明明配置了location /static/ { root /var/ww…

USB 2.0 vs USB 3.0:全面技术对比与选择指南

USB 2.0 vs USB 3.0:全面技术对比与选择指南 引言 在当今数字时代,USB接口已成为连接设备与计算机的最普遍标准之一。从2000年USB 2.0的发布到2008年USB 3.0的问世,USB技术经历了显著的演进。本文将深入比较这两种广泛使用的USB标准&#xff…

DApp架构设计与开发流程指南

目录 DApp架构设计与开发流程指南 引言:DApp的核心特性 一、DApp架构设计 1.1 分层架构设计 各层核心组件: 1.2 典型架构模式 1.2.1 全去中心化架构 1.2.2 混合架构(推荐) 二、开发流程 2.1 敏捷开发流程 2.2 详细开发阶段 阶段1:需求分析与设计(1-2周) 阶段2:智能合约…

Windows下odbc配置连接SQL Server

一、查看SQL Server服务是否启动打开SQL Server 2022配置管理器查看SQL Server运行状态,可以设置 启动或停止服务二、windows下如何配置ODBC数据源1、Windows搜索栏中输入“ODBC数据源管理器”并选择“以管理员身份运行”来打开它2、添加新的数据源ODBC数据源管理器…

MySQL—表设计和聚合函数以及正则表达式

文章目录一、第一范式(原子性)二、第二范式(消除部分依赖)三、第三范式(消除传递依赖)四、表设计五、聚合函数六、正则表达式MySQL 的三大范式(1NF、2NF、3NF)是关系型数据库设计的核…