嵌入式设计模式之策略模式(1)

张开发
2026/4/14 15:05:19 15 分钟阅读

分享文章

嵌入式设计模式之策略模式(1)
痛点描述传统嵌入式代码中经常出现大量的if-else或switch-case判断不同算法或硬件配置// 传统做法条件分支臃肿 void sensor_control(SensorType type) { if (type TEMPERATURE_I2C) { i2c_init(); i2c_read_temp(); } else if (type HUMIDITY_UART) { uart_init(); uart_read_humidity(); } else if (type PRESSURE_SPI) { spi_init(); spi_read_pressure(); } // 新增传感器需要修改此处违反开闭原则 }策略模式解决方案// 使用策略模式后 void sensor_control(const SensorStrategy *strategy) { strategy-init(); strategy-read_data(); } // 新增传感器只需添加新策略无需修改现有代码2. 运行时动态配置痛点描述嵌入式系统经常需要根据环境变化如电池电量、网络状态、外设连接动态调整行为电池电量低时从高性能算法切换到节能算法传感器故障时切换到备用数据处理方案通信信号弱时切换调制方式或协议传统实现的困境// 硬编码配置无法动态适应 void communication_setup(void) { #ifdef POWER_SAVING_MODE setup_low_power_protocol(); // 编译时确定无法运行时切换 #else setup_high_perf_protocol(); #endif }策略模式优势// 根据电池电量动态切换 void update_communication_strategy(int battery_level) { if (battery_level 20) { comm_set_strategy(low_power_strategy); // 运行时切换 } else { comm_set_strategy(high_perf_strategy); } }3. 硬件资源冲突管理痛点描述嵌入式系统中硬件资源如DMA通道、定时器、中断有限多个功能可能竞争同一资源UART和SPI共享同一DMA通道不同传感器分时使用I2C总线算法切换时需要重新配置外设策略模式的资源管理void comm_set_strategy(CommunicationManager *mgr, const CommunicationStrategy *new_strategy) { if (mgr-strategy) { mgr-strategy-deinit(); // 释放当前硬件资源 } mgr-strategy new_strategy; mgr-strategy-init(); // 初始化新硬件配置 } // 确保资源安全切换避免冲突4. 测试和维护困难痛点描述嵌入式代码高度依赖硬件环境算法与硬件驱动紧耦合难以单元测试修改一个功能可能影响其他模块不同硬件平台移植困难策略模式的解耦效果// 可独立测试每个策略 void test_uart_strategy(void) { CommunicationStrategy *strategy uart_strategy; strategy-init(); strategy-send(test_data, len); // 可Mock硬件层进行测试 strategy-deinit(); } // 硬件平台移植时只需实现策略接口不影响业务逻辑5. 代码冗余和复用性差痛点描述相似功能在不同模块中重复实现// 模块A中的SPI操作 void module_a_spi_send(void) { spi_cs_low(); spi_transmit(data); spi_cs_high(); } // 模块B中类似的SPI操作但略有不同 void module_b_spi_send(void) { spi_cs_low(); delay(1); // 特殊延时要求 spi_transmit(data); spi_cs_high(); }策略模式的统一封装// 通用SPI策略支持差异化配置 const CommunicationStrategy spi_strategy_fast { .send spi_send_fast // 无延时版本 }; const CommunicationStrategy spi_strategy_slow { .send spi_send_slow // 带延时版本 }; // 避免代码重复提高复用性6. 系统可配置性差痛点描述传统嵌入式系统行为通常在编译时确定无法根据用户需求或环境变化调整固定使用某种滤波算法通信参数无法现场配置功能扩展需要重新烧录固件策略模式的动态性// 通过配置表实现灵活的策略映射 typedef struct { int scenario_id; const CommunicationStrategy *strategy; } StrategyConfig; StrategyConfig config_table[] { {SCENARIO_HIGH_SPEED, uart_strategy_1mbps}, {SCENARIO_LOW_POWER, i2c_strategy_slow}, {SCENARIO_RELIABILITY, spi_strategy_verified} }; void apply_scenario(int scenario) { // 根据场景ID动态切换策略 const CommunicationStrategy *strategy find_strategy(scenario); comm_set_strategy(comm_mgr, strategy); }总结策略模式解决的嵌入式核心痛点痛点传统方法的问题策略模式的解决方案条件分支复杂if-else嵌套难以维护算法封装消除条件判断静态配置编译时确定无法适应变化运行时动态切换资源冲突手动管理容易出错自动化的资源初始化和释放测试困难硬件依赖导致难以测试接口抽象便于Mock测试代码冗余相似功能重复实现策略复用减少重复代码扩展性差修改影响范围大符合开闭原则易于扩展策略模式本质上为嵌入式系统提供了**算法即插件的能力非常适合需要灵活应对多种场景**的嵌入式应用场景。

更多文章