QT 事件驱动架构
很多大型系统工业软件、机器人系统、自动驾驶、复杂 Qt 应用在规模变大以后都会逐渐引入事件驱动架构Event Bus / Event Driven Architecture。原因很简单当系统模块越来越多时模块之间的调用关系会爆炸式增长最终变得无法维护。我用一个逐步演化的真实思维过程来解释。一、最初阶段直接调用最直观系统刚开始只有几个模块UIMotorControllerCameraController调用关系很简单UI → MotorController UI → CameraController代码类似voidMainWindow::onStartClicked(){motorController.start();cameraController.capture();}问题不大。二、系统变大调用关系开始爆炸后来系统增加很多模块MotorControllerCameraControllerLightControllerNetworkControllerDataLoggerAlarmSystemUI此时如果还是直接调用会变成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);CameraControllerif(cameraError)alarm.raise(camera error);NetworkControllerif(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();autoresultinspect.detect();network.send(result);模块互相依赖。事件驱动MotionController ↓ Event: MoveDone CameraController ↓ Event: ImageCaptured InspectionController ↓ Event: InspectionDone结构MotionController ↓ EventBus ↓ CameraController ↓ EventBus ↓ InspectionController九、系统结构变化没有 EventBusA → B → C → D有 EventBusA → 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.coloradmin.cn/o/2416584.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!