PC开发有大约二十三种设计模式,在ARM开发中能有效用到的可能也就五六种。但这五六种,一旦用对了,代码质量会有质的提升。
状态机典例
几乎所有实时性要求高的ARM系统都涉及状态管理:通信协议解析、设备工作模式切换、UI 界面流转、电机控制......只要你的系统存在"在不同条件下做不同事情"的逻辑,就应该考虑状态机。

cpp
//一般逻辑
void motor_control(void) {
if (mode == 1) {
if (speed > 100 && temp < 80) {
// 正常运行逻辑...
if (error_flag) {
// 错误处理...
mode = 3;
}
}
} else if (mode == 2) {
// 又一堆嵌套...
} else if (mode == 3) {
// 继续嵌套...
}
}
//状态机思想
typedef enum { IDLE, RUNNING, FAULT, STOPPING } MotorState;
// 函数指针表 ------ 每个状态对应一个处理函数
static void (*state_handler[])(void) = {
[IDLE] = handle_idle,
[RUNNING] = handle_running,
[FAULT] = handle_fault,
[STOPPING] = handle_stopping,
};
void motor_control(void) {
state_handler[current_state]();
}
状态机最大的好处是:新增一个状态,只需要加一个处理函数,不用大改已有逻辑。 这就是开闭原则在ARM开发里最接地气的体现,很好地实现了代码的解耦。
观察者模式典例
观察者模式的典型场景是事件通知。比如一个传感器采集到数据后,可能需要同时通知 LCD 刷新显示、通知数据记录模块存储、通知通信模块上传。如果在采集函数里直接调用这三个模块,耦合就很高了。
实际上,传感器不需要知道谁在监听,只负责发通知

cpp
#define MAX_OBSERVERS 8
typedef void (*Observer)(int sensor_value);
static Observer observers[MAX_OBSERVERS];
static int observer_count = 0;
void register_observer(Observer cb) {
if (observer_count < MAX_OBSERVERS)
observers[observer_count++] = cb;
}
void notify_all(int value) {
for (int i = 0; i < observer_count; i++)
observers[i](value);
}
本质实现就是回调函数数组,传感器模块只管调 notify_all(),完全不用知道谁注册了、干了什么。模块之间解耦了,加新功能只要注册新回调就行。
策略模式典例
即"同一件事有多种做法,需要运行时切换"的场景。比如:一个通信模块,可能需要支持多种校验算法(CRC8、CRC16、CRC32),不同的协议用不同的校验。
cpp
/*
一般的处理是 switch 或者 if-else。
*/
typedef uint32_t (*CrcStrategy)(const uint8_t *data, size_t len);
typedef struct {
CrcStrategy calc_crc; // 当前使用的校验策略
// ... 其他配置
} CommConfig;
// 切换策略就是换个函数指针
void comm_set_crc(CommConfig *cfg, CrcStrategy strategy) {
cfg->calc_crc = strategy;
}
当然,ARM平台资源有限,搞这些抽象太浪费了。这话有一定道理。在 8 位单片机上,RAM 可能只有几百字节,Flash 也就几 KB,确实没资本搞复杂的抽象层。函数指针表虽然优雅,但每个指针也要占内存。在这类极端受限的平台上,直接写 if-else 反而是最务实的选择。同时,"代码又不需要频繁变动,何必过度设计"有些产品,出厂就定版了,代码可能一辈子不改。对这种项目,花时间做架构设计确实性价比不高。能跑就行,稳定压倒一切。另外,"团队里没人看得懂,反而增加维护成本"这一点其实挺致命的。如果你用了观察者模式,但团队其他人完全不了解这个概念,那调试的时候他们看到回调跳来跳去,只会更头疼。设计模式的前提是团队有共识。
在实际的开发中,从问题出发,而不是从模式出发。 不要想着"我要用观察者模式",而是想"传感器数据要通知好几个模块,怎么解耦"。当带着实际问题去找方案的时候,设计模式才真正有意义。
像优先级比较高的状态机,可以用在协议解析、模式切换、流程控制等;观察者模式,可以用在事件通知、传感器数据分发等;策略模式,可以用在算法切换、多平台适配等;单例模式,可以用在全局硬件资源管理等。