C++ 事件总线(EventBus)实现嵌入式系统解耦
摘要:在嵌入式软件开发中,随着功能模块的增加,模块间的'相互调用'往往会导致代码耦合度指数级上升。修改 A 模块的代码,B、C、D 模块都要跟着改,牵一发而动全身。本文将抛弃传统的直接调用方式,基于 C++11 实现一个轻量级的发布 - 订阅(Publish-Subscribe)系统,彻底斩断模块间的依赖链。
一、架构之殇:为什么你的代码越来越难改?
假设我们要开发一个智能环境控制器,它有四个独立模块:
- 采集模块:读取温度传感器。
- 显示模块:LCD 屏幕显示数据。
- 网络模块:WiFi 上传数据。
- 控制模块:温度过高开启风扇。
1. 传统写法(高耦合)
在传统的面向过程编程中,采集模块的代码通常长这样:
// SensorTask.cpp
#include "LcdDriver.h" // 依赖 LCD
#include "WifiModule.h" // 依赖 WiFi
#include "FanControl.h" // 依赖 风扇
void Sensor_Read_Loop() {
float temp = HAL_ADC_Read(); // 噩梦的开始:采集者必须知道所有消费者的存在
LCD_ShowTemp(temp); // 直接调用
WiFi_Upload(temp); // 直接调用
if (temp > 30) Fan_On(); // 直接调用
}
2. 痛点分析
- 依赖地狱:采集模块依赖了其他所有模块的头文件。如果你想把这个采集算法移植到另一个没有 WiFi 的项目中,你必须手动删除所有 WiFi 相关的代码。
- 扩展性差:如果老板说:'加一个蜂鸣器,温度高了报警'。你得去改
SensorTask.cpp,重新编译采集模块。这违背了'开闭原则'(对扩展开放,对修改关闭)。
二、破局之道:引入'事件总线'
我们要引入一个中间人(Broker)。
- 采集者只管喊一声:'温度变了,现在是 35 度!'(发布事件)
- 显示/网络/风扇只管告诉中间人:'如果温度变了,记得叫醒我。'(订阅事件)

