当前位置: 首页 > news >正文

使用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.dtcms.com/a/283905.html

相关文章:

  • suricata新增Mysql告警规则处理
  • 专业职业评估工具,多维度数据分析
  • 网络安全基础操作2
  • 第十四章 gin基础
  • Spring Boot 中 META-INF 的作用与功能详解
  • 荷塘水上闯关游戏:Python OpenGL 3D游戏开发实战详解
  • 简单实现一个接口限流
  • 逆向破解京东评论加密参数|Python动态Cookie解决方案
  • 基于 Electron + Vue 3 的桌面小说写作软件架构设计
  • 共用体(联合体)
  • React Native 基础tabBar和自定义tabBar - bottom-tabs
  • Python编程进阶知识之第二课学习网络爬虫(requests)
  • 【真·CPU训模型!】单颗i7家用本,4天0成本跑通中文小模型训练!Xiaothink-T6-mini-Preview 技术预览版开源发布!
  • 对话弋途科技:当AI重构汽车大脑,一场车载操作系统的“觉醒年代“开始了
  • 【理想汽车智驾方案介绍专题 -1】端到端+VLM 方案介绍
  • 113:路径总和 II
  • Go语言时间控制:定时器技术详细指南
  • uni-app 配置华为离线推送流程
  • Go语言高并发聊天室(三):性能优化与压力测试
  • 【物联网】基于树莓派的物联网开发【11】——树莓派无法启动修复解决方案
  • Transformer从入门到精通
  • Spring Boot整合阿里云OSS企业级实践:高可用文件存储解决方案
  • 【Docker基础】Docker-compose基础认知:从核心概念到实战解析
  • 闽南话里的俗语(俚语、谚语、歇后语)
  • S7-1200 模拟量模块全解析:从接线到量程计算
  • 苍穹外卖项目日记(day11)
  • Linux内核ICMP协议实现深度解析:网络控制的智慧引擎
  • 《C++初阶之STL》【auto关键字 + 范围for循环 + 迭代器】
  • 基于typescript严格模式以实现undo和redo功能为目标的命令模式代码参考
  • Python-TCP编程-UDP编程-SocketServer-IO各种概念及多路复用-asyncio-学习笔记