DAB实现中用到的主要设计模式

news/2025/2/1 9:17:07/文章来源:https://www.cnblogs.com/Rong-/p/18696168

DAB C++ 版本设计模式应用实践

1. 命令模式 (Command Pattern)

设计目标

  • 模块解耦:实现各模块独立编译、测试、运行,消除模块间直接依赖
  • 扩展准备:为桥接模式实现奠定基础
  • 依赖倒置:通过命令对象反转模块依赖方向
  • 耦合降低:将模块间耦合简化为命令对象耦合

1.1 MQTT 模块实现

#pragma once
#include <string>
#include <vector>
#include <functional>/*** @class HiMqttClient* @brief MQTT 客户端核心类,提供连接管理、消息发布订阅等功能* * @note 采用命令模式实现消息处理回调机制*/
class HiMqttClient {
public:// 连接管理接口static void start(const char* ip, int port, const char* user, const char* password, const char* clientId);static void stop();// 消息管理接口static void subscribe(const std::vector<std::string>& topics);static bool publish(const char* topic, const char* body);// 命令模式回调设置static void onTopic(const std::function<void(const char*, const char*, const char*, const char*)>& func);
};

设计亮点

  • 通过 onTopic() 设置命令对象实现消息处理解耦
  • 支持模块独立单元测试
  • 消除与其他业务模块的循环依赖

1.2 Topic 处理器实现

#pragma once
#include <map>
#include <functional>
#include "context/dab_context.h"/*** @class TopicHandler* @brief 基于命令模式的主题处理器* * @note 使用注册机制替代传统 switch-case 分支处理*/
class TopicHandler {
public:// 生命周期管理static void init(int maxThreads);static void destroy();// 命令注册接口static void registerHandler(const std::map<std::string, std::function<void(DABContext&)>>& handles);// 统一消息入口static void onTopic(const char* topic, const char* body,const char* response_topic, const char* correlation_data);
};

创新点

  • 动态注册机制实现处理逻辑可配置化
  • 统一消息入口简化调用链路
  • 天然支持多线程处理

1.3 上下文对象设计

#pragma once
#include "context/dab_status.h"
#include "context/dab_request.h"
#include "context/dab_response.h"/*** @class DABContext* @brief 请求处理上下文对象* * @note 采用命令模式封装消息发布功能*/
class DABContext {
public:// 状态管理接口bool is_ok() const;void success();void clientFail(const char* out_log, const char* inner_log = nullptr);// 消息发布命令接口static void setPublishFunc(const std::function<void(const char*, const char*)>& func);static void publish(DABContext& context);// 数据成员DABStatus status;DABRequest request;DABResponse response;
};

技术优势

  • 隐藏 MQTT 实现细节
  • 支持多种消息发布策略
  • 上下文自包含设计简化单元测试

1.4 日志模块实现

#pragma once#include <functional>/*** @enum DABLogLevel* @brief 日志级别枚举定义*/
enum class DABLogLevel { INFO, WARNING, ERROR, FATAL, ALWAYS };namespace dab {/*** @brief 日志回调设置接口* @param callback 日志处理函数原型:*        void(日志级别, 文件名, 函数名, 行号, 日志内容)*/void set_log_callback(std::function<void(DABLogLevel, const char*, const char*, int, const char*)> callback);// 日志宏定义#define DABLOG_INFO(...)  dab::writeLog(DABLogLevel::INFO, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)#define DAB_ASSERT(expr, desc) \do { if (!(expr)) { \dab::on_assert_fail(__FILE__, __FUNCTION__, __LINE__); \}} while(0)
}

核心价值

  • 灵活适配不同日志实现
  • 支持运行时日志策略切换
  • 提供丰富的调试信息

2. 桥接模式 (Bridge Pattern)

设计目标

  • 架构解耦:分离抽象与具体实现
  • 独立演进:各模块可独立变化
  • 统一接口:提供标准化服务能力

系统桥接实现

void publish(const char* topic, const char* body) {HiMqttClient::publish(topic, body);     
}extern "C" int runDabService() {// 初始化各模块TopicHandler::init(DABProperties::max_handle_threads);DABHandler::init();// 桥接关键点HiMqttClient::onTopic(TopicHandler::onTopic);DABContext::setPublishFunc(publish);// 订阅与注册HiMqttClient::subscribe(DABHandler::getTopics());TopicHandler::registerHandler(DABHandler::getTopicHandles());// 启动服务HiMqttClient::start(DABProperties::mqtt_ip.c_str(), DABProperties::mqtt_port, ...);return 0;
}

桥接优势

  • 业务逻辑与通信协议解耦
  • 模块间通过抽象接口通信
  • 新增协议支持成本最低化

3. 适配器模式 (Adapter Pattern)

设计目标

  • 接口标准化:统一不同系统的接口规范
  • 依赖倒置:反转系统接口依赖方向
  • 扩展支持:为策略模式实施奠定基础

典型应用

  1. 日志适配器:将系统日志接口转换为 DAB 标准日志接口
  2. 服务适配:封装平台特性接口为统一服务接口

适配收益

  • 业务代码不依赖具体实现
  • 新增平台支持只需实现适配器
  • 保持核心逻辑稳定性

4. 策略模式 (Strategy Pattern)

应用场景

场景 实现策略 优势
电视环境 真实硬件接口实现 完整功能支持
云端环境 Mock 接口实现 无硬件依赖的自动化测试
单元测试 内存型轻量实现 快速测试执行

策略配置

// 测试环境初始化示例
void dabInit() {DABContext::setPublishFunc([](const char* t, const char* b) {DABLOG_ALWAYS("Test Publish: %s -> %s", t, b);});TopicHandler::registerHandler({{"test/topic1", [](DABContext& ctx){ /* Mock处理逻辑 */ }},{"test/topic2", [](DABContext& ctx){ /* Mock处理逻辑 */ }}});
}

策略优势

  • 运行时动态切换实现
  • 环境隔离保证测试可靠性
  • 并行支持多种部署方案

5.单例模式

在DAB的实现中,有意回避了单例模式,使用静态类代替。
```cppclass TopicHandler {public:static void init(int maxThreads);   // 显式初始化static void destroy();              // 显式资源释放static void registerHandler(/*...*/);TopicHandler() = delete;            // 禁止实例化};```
**设计考量**:
1.  **生命周期可控**:通过`init()`/`destroy()`明确管理资源
2.  **测试友好**:支持不同测试用例的独立初始化
3.  **避免全局状态**:每个模块维护自身静态数据
4.  **编译期约束**:`= delete`禁止非法操作**对比传统单例**:
*   不强制全局唯一实例
*   无隐式初始化顺序问题
*   支持多环境配置(测试/生产)

6. 测试体系设计

1. 测试环境搭建

#include <gtest/gtest.h>
#include "dab/dab_api.h"// 全局测试环境类
class TestEnv : public testing::Environment {
public:void SetUp() override { dabInit(); }    // 测试用例初始化void TearDown() override { dabDestory(); } // 测试资源回收
};// 核心初始化逻辑
namespace {// 模拟消息发布函数void publish(const char* topic, const char* body) {DABLOG_ALWAYS("[TEST] Topic:%s\nPayload:%s", topic, body);}void dabInit() {DABProperties::device_id = "TEST_DEVICE"; // 设置测试设备IDTopicHandler::init(5);    // 初始化消息处理线程池DABHandler::init();       // 业务处理器初始化DABContext::setPublishFunc(publish); // 注入模拟发布器// 注册Topic处理函数TopicHandler::registerHandler(DABHandler::getTopicHandles());}void dabDestory() {TopicHandler::destroy();  // 清理消息处理器DABHandler::destroy();    // 清理业务处理器}
}// 测试主入口
int main(int argc, char** argv) {testing::InitGoogleTest(&argc, argv);testing::AddGlobalTestEnvironment(new TestEnv);return RUN_ALL_TESTS();
}

2. 设计模式应用解析

设计模式 应用场景 实现要点
命令模式 消息处理函数注册 通过registerHandler注册处理闭包
桥接模式 业务处理与MQTT通信解耦 setPublishFunc实现协议隔离
策略模式 测试环境与生产环境配置切换 DABProperties动态配置

3.测试辅助工具实现

1. Topic处理工具类

namespace {// 生成标准Topic格式std::string formatTopic(const std::string& baseTopic) {std::ostringstream oss;oss << "dab/" << DABProperties::device_id << "/" << baseTopic;return oss.str();}
}// 统一测试入口函数
void onTopicTest(const std::string& topic, const std::string& request) {TopicHandler::onTopic(formatTopic(topic).c_str(),  // 格式化请求Topicrequest.c_str(),             // 测试请求载荷"_response/" + formatTopic(topic).c_str(), // 响应Topic""                           // 关联数据);
}

2. 工具类设计亮点

  1. Topic规范化:自动添加设备ID前缀
  2. 响应隔离:生成专用的响应Topic通道
  3. 异常防护:内置空指针检查等安全机制
  4. 日志追踪:自动记录测试消息流向

4.应用功能测试案例

1. 应用管理测试集

TEST(DABHandler, ApplicationManagement) {// 基础功能测试onTopicTest("applications/list", "{}"); // 空参数查询// 典型场景测试onTopicTest("applications/launch", R"({"appId":"YouTube"})"); // 标准应用启动// 带参数启动测试onTopicTest("applications/launch", R"({"appId": "Netflix","parameters": ["-KEY", "https%3A%2F%2Fwww.example.com%2F","-STANDALONE_PARAM"]})");// 状态管理测试onTopicTest("applications/get-state", R"({"appId":"YouTube"})");// 退出机制测试onTopicTest("applications/exit", R"({"appId":"YouTube"})"); // 常规退出onTopicTest("applications/exit", R"({"appId":"YouTube","background":true})"); // 后台退出
}

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

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

相关文章

对比使用DeepSeek与文新一言,了解DeepSeek的关键技术论文

DeepSeek是国内大模型技术的新秀,最近也在业界和媒体界火爆出圈,所以想学习一下其技术。 大模型时代,学习知识,当然首先想到利用大模型,由于在过去一年,对DeepSeek使用不多,所以想和文新一言(4.0 Turbo)对比使用。 通过对比,针对同一个问题“DeepSeek发扬开源文化,将…

Cisco NX-OS Software Release 10.5(2)F - 网络操作系统软件

Cisco NX-OS Software Release 10.5(2)F - 网络操作系统软件Cisco NX-OS Software Release 10.5(2)F - 网络操作系统软件 NX-OS 网络操作系统 请访问原文链接:https://sysin.org/blog/cisco-nx-os-10/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.orgCisco NX-OS…

pdf处理--tts(待重写)

1.提取正文2.裁剪页眉 https://smallpdf.com/cn/crop-pdf#r=crop-pages3.拆分4.ocr 效果图--白描:效果图--4Videosoft PDF Converter Ultimate:5.阅读器与tts引擎 开源阅读:https://github.com/gedoor/legado tts-server-android:https://github.com/jing332/tts-server-an…

INFINI Labs 产品更新 | Console 发布 TopN 功能,Easysearch 新增 Rollup 能力等

INFINI Labs 产品全新发布!此次更新为大家带来了 Console 的全新 TopN 功能,让您能够更高效地定位最关键的节点或索引;Easysearch 新增 Rollup 能力,大幅提升监控指标的存储周期并优化分析体验;此外,Framework 还修复了多项缺陷并进行了多处优化。欢迎下载体验,探索更多…

03-一个例子

登录被测系统bysms双击运行runserver.bat 访问页面:http://127.0.0.1/mgr/sign.html 账号:byhy,密码:88888888 可以直接在pycharm的Terminal中运行hytest,不需要打开命令行窗口 浏览器驱动的打印信息: 禁止 chromedriver 日志写屏1 from selenium import webdriver 2 3 …

blog tips

markdown 内嵌 html 使图片并排点击查看代码 <div style="display: flex; gap: 10px; justify-content: space-between;"><img src="图片1地址" style="width: 49%; height: auto;"/><img src="图片2地址" style="…

【数学】已知正方形相邻两点坐标求另外两点坐标

已知正方形相邻两点(a,b)与(c,d)坐标公式: \( (x_3,y_3) = (c + (b-d), d - (a-c)) \\ (x_4,y_4) = (a + (b-d), b - (a-c)) \\ (x_5,y_5) = (a - (b-d), b + (a-c)) \\ (x_6,y_6) = (c - (b-d), d + (a-c)) \)

25.1.31小记

多态类型声明类型 : 定义时候的类型 动态类型 : 运行到那里的时候对应的具体类型 向上造型(cast) : 将子类类型的对象赋给父类的变量 (不能将一个父类的变量赋予一个子类的变量) 赋值运算符 : 将管理者管理的对象进行改变(改变的是指针)其中造型(cast)的意义是将某…

MacOS修改应用快捷键的一般思路

具体步骤为:使用CheatSheet软件查看菜单项名称 在系统设置中修改菜单项的快捷键举个例子:修改Chrome中左右切换tab的快捷键(系统语言为英文,中文同理) 默认采用Ccontrol Tab和Control + Shift + Tab(或Command Shift [和Command Shift ])可以左右切换tab。 现在希望将其…

UE4.27, 模块实践, Slate的UI开发 (一)

1. 基本概念1.1. Slate是虚幻UI框架设计的底层,该框架中最基本的类是SWidget1.1.1.显然,我们容易注意到,直属于该框架的类拥有着指定的命名规则,即以S开头1.2. UMG, UWidget, Slate关联1.2.1. UMG:Unreal Motion Graphics UI Designer 虚幻的图形界面设计工具1.2.2. 单纯Sl…

Brainfly: 用 C# 类型系统构建 Brainfuck 编译器

Brainfly: 用 C# 类型系统构建 Brainfuck 编译器Brainfuck 简介 Brainfuck 是由 Urban Mller 在 1993 年创造的一门非常精简的图灵完备的编程语言。 正所谓大道至简,这门编程语言简单到语法只有 8 个字符,每一个字符对应一个指令,用 C 语言来描述的话就是:字符 含义> ++…

01-hytest简介

参考教程:http://vip3.byhy.net/auto/pyatframework/hytest-01/ 安装:pip3 install hytest hytest对应的python版本要求:Python3.6或者更高版本 运行hytest自动化测试:打开命令行窗口 切换到自动化代码根目录 运行hytest,运行hytest其实就是运行python -m hytest.run 如果…