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

QT 事件驱动架构

很多大型系统(工业软件、机器人系统、自动驾驶、复杂 Qt 应用)在规模变大以后,都会逐渐引入事件驱动架构(Event Bus / Event Driven Architecture)

原因很简单:

当系统模块越来越多时,模块之间的调用关系会爆炸式增长,最终变得无法维护。

我用一个逐步演化的真实思维过程来解释。


一、最初阶段:直接调用(最直观)

系统刚开始只有几个模块:

  • UI
  • MotorController
  • CameraController

调用关系很简单:

UI → MotorController UI → CameraController

代码类似:

voidMainWindow::onStartClicked(){motorController.start();cameraController.capture();}

问题不大。


二、系统变大:调用关系开始爆炸

后来系统增加很多模块:

  • MotorController
  • CameraController
  • LightController
  • NetworkController
  • DataLogger
  • AlarmSystem
  • UI

此时如果还是直接调用,会变成:

UI → MotorController UI → CameraController UI → LightController MotorController → Logger MotorController → Alarm CameraController → Logger CameraController → Network Network → Controller

模块之间的关系变成一个蜘蛛网结构

A → B A → C B → D C → D D → E E → B

这叫:

强耦合系统

问题:

1️⃣ 修改一个模块可能影响很多模块
2️⃣ 新增功能需要改很多代码
3️⃣ 很难理解系统结构


三、真实案例:增加一个“报警系统”

假设系统需要增加一个新模块:

AlarmSystem

需求:

  • 电机过载报警
  • 温度过高报警
  • 网络断开报警

如果是直接调用:

MotorController 要加:

if(overload)alarm.raise("motor overload");

CameraController:

if(cameraError)alarm.raise("camera error");

NetworkController:

if(disconnect)alarm.raise("network error");

问题:

❌ 每个模块都要修改
❌ 未来新增模块还要继续改

这就是耦合地狱


四、工程师的思考:能不能让模块不互相认识?

工程师开始思考:

如果模块之间不直接调用,而是发布消息,会不会更好?

于是出现:

事件驱动架构


五、事件驱动架构的核心思想

模块之间不直接调用。

而是:

发布事件

订阅事件

通过一个EventBus(事件总线)连接。

结构变成:

Module A → EventBus → Module B

模块之间互相不知道对方存在


六、例子:电机完成运动

传统调用:

MotorController → CameraController

代码:

motorController.moveDone();cameraController.capture();

问题:

MotorController 必须知道 CameraController。


事件驱动:

MotorController → EventBus CameraController ← EventBus

代码:

发布事件:

eventBus.publish("MotorMoveDone");

订阅事件:

eventBus.subscribe("MotorMoveDone",[](){camera.capture();});

MotorController 不知道 CameraController。


七、增加新功能时的变化

假设我们新增:

Logger

记录电机完成事件。

传统方式:

需要修改:

MotorController CameraController

事件方式:

只需要:

Logger 订阅事件

代码:

eventBus.subscribe("MotorMoveDone",[](){logger.log("motor finished");});

原代码完全不需要改


八、再举一个真实设备流程

自动检测设备流程:

移动平台 → 拍照 → 图像检测 → 上传结果

传统调用:

MotionController ↓ CameraController ↓ InspectionController ↓ NetworkController

代码:

motion.move();camera.capture();autoresult=inspect.detect();network.send(result);

模块互相依赖。


事件驱动:

MotionController ↓ Event: MoveDone CameraController ↓ Event: ImageCaptured InspectionController ↓ Event: InspectionDone

结构:

MotionController ↓ EventBus ↓ CameraController ↓ EventBus ↓ InspectionController

九、系统结构变化

没有 EventBus:

A → B → C → D

有 EventBus:

A → EventBus B → EventBus C → EventBus D → EventBus

模块只依赖:

EventBus

系统耦合大幅下降。


十、再举一个复杂例子(工业软件)

事件:

TemperatureHigh

订阅者可能有:

AlarmSystem Logger UI CoolingController

发布者:

SensorController

代码:

发布:

eventBus.publish("TemperatureHigh");

订阅:

eventBus.subscribe("TemperatureHigh",[](){alarm.trigger();});eventBus.subscribe("TemperatureHigh",[](){logger.log();});eventBus.subscribe("TemperatureHigh",[](){ui.showWarning();});

新增功能只需要:

新增订阅者

十一、事件驱动带来的巨大好处

1 模块解耦

模块互相不认识。


2 可扩展

新增功能:

新增订阅者

不用修改旧代码。


3 更符合现实世界

现实世界就是事件驱动:

门打开 → 灯亮 门打开 → 摄像头启动 门打开 → 报警系统记录

4 易于并发

事件可以:

异步处理 多线程处理

十二、Qt 为什么非常适合事件架构

Qt 本身就是事件驱动框架

例如:

Signal → Slot

本质就是:

Event → Listener

例子:

connect(button,&QPushButton::clicked,this,&MainWindow::onClicked);

这其实就是一个小型 EventBus。


十三、大型系统为什么几乎都用事件架构

因为系统规模一大,就会出现:

模块数量 ↑ 调用关系 ↑↑ 复杂度 ↑↑↑

EventBus可以把:

N² 的调用关系

变成:

N 的关系

这是复杂度降低的关键


十四、一句话理解 EventBus

普通架构:

模块直接打电话

事件架构:

模块在广播电台发布消息 需要的人自己收听

http://www.jsqmd.com/news/486238/

相关文章:

  • Thinkphp和Laravel框架都支持基于微信小程序的城市公交查询系统 web pc 小程序手机端
  • 石家庄自闭症干预机构全攻略|写给迷茫的家长,每一步都有方向 - 品牌测评鉴赏家
  • 2026年工地/矿山/工程车辆洗车台推荐:陕西聚壹环保科技全系产品助力环保清洁 - 品牌推荐官
  • 上海交大首创PlanViz:计算机使用任务中的智能图像生成新基准
  • 2026郑州自闭症康复机构全攻略:为“星星的孩子”照亮前路 - 品牌测评鉴赏家
  • 智造赋能全域突破:2026中国风机五大领军企业重塑通风生态 - 深度智识库
  • 2024提示工程架构师趋势:自主代理AI的7个革命性提示策略
  • 2026净化车间承建服务商排行榜助拿生产许可证:祖传秘方申请批号/祛痘淡斑妆字号申报代办/秘方备案代办代工/选择指南 - 优质品牌商家
  • 2026六大城市高端腕表“表带养护”终极档案:从鳄鱼皮到904L钢,这些细节决定你的表带寿命 - 时光修表匠
  • Ddrops滴卓思维生素d3怎么样?3款测评医生推荐避坑安心选 - 品牌排行榜
  • 初创团队选哪家短信平台?优质短信供应商盘点 - Qqinqin
  • 新西伯利亚大学推出“Pisets“:让机器写字员听懂每一句话
  • 游戏行业选哪家短信接口?应对高频注册与消息通知 - Qqinqin
  • 智造未来,精准封藏:2026年五金配件包装机实力厂家深度测评与前瞻推荐 - 深度智识库
  • B端拓客核验难题:精准度与成本,到底该怎么平衡?氪迹科技法人号码核验工具
  • 石家庄自闭症干预机构全攻略:为“星星的孩子”照亮前行之路 - 品牌测评鉴赏家
  • MCP 协议详解:构建 AI 助手的通用接口
  • 爱丁堡大学突破:AI实现无标注数据驱动的世界规律自我进化学习
  • 杭州爱彼/南京宝珀/无锡帝舵维修指南:36个高端腕表维修避坑+六城正规网点实测 - 时光修表匠
  • AI检索工具项目话术
  • 【Personal Skills】用系统思维看问题:结构、反馈与杠杆点
  • UC伯克利和UCSF研究团队发现:AI模型“节食“后竟然变得更加偏见!
  • 新生儿D3选购指南:3款热门产品测评,哪款才是安心首选? - 品牌排行榜
  • PAT 乙级 1034
  • YOLOv11涨点改进| CVPR 2026 | 全网独家首发、特征融合改进篇| 引入SRFusion 空间细化多级融合,含多种创新融合改进,涨点可直接发论文,适合裂缝图像检测,小目标检测任务高效涨点
  • Win10 -> Win11 升级机制 导致应用不可用
  • 计科-计网4-数据链路层「整理」
  • 2026上门收购红木家具公司推荐指南 - 优质品牌商家
  • 金库合约Vault
  • 第四篇:Dubbo 本地存根 (Stub) 和 本地伪装 (Mock) 的核心总结