嵌入式设计模式之策略模式(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测试
代码冗余 相似功能重复实现 策略复用,减少重复代码
扩展性差 修改影响范围大 符合开闭原则,易于扩展

策略模式本质上为嵌入式系统提供了**"算法即插件"的能力,非常适合需要灵活应对多种场景**的嵌入式应用场景。

相关推荐
个 人 练 习 生23 分钟前
C++中的内存管理
开发语言·c++·经验分享·学习
上海广测检测科技有限公司36 分钟前
蓝牙耳机俄罗斯EAC认证详解:欧亚经济联盟体系下TWS与头戴式的合规路径
经验分享
浩瀚地学1 小时前
deepagents学习打卡day08
经验分享·笔记·python·学习·agent
焱焱枫1 小时前
OceanBase 为什么要多一层 Unit 和 ResourcePool?Tenant 直接分 CPU 内存不行吗?多租户资源模型一次讲透
经验分享
LCDduhui1 小时前
LCD屏幕中常见的液晶屏驱动芯片有哪些
经验分享
Zane19941 小时前
同一段单例代码,为什么在高并发下偶尔会创建出两个实例?聊聊哪种单例实现才是真的安全
设计模式
AlexCookie2 小时前
低空周报(第五期)2026年9月21日‑9月27日|多地新版适飞空域落地,西安低空大会集中产业对接,eVTOL政企签约释放商业化信号
经验分享·企业微信·创业创新·低空经济·行业周报
Carl_奕然2 小时前
【智能体】Loop 的四种设计模式之:Agent Loop(2026 最新版)
人工智能·设计模式·语言模型
上海广测检测科技有限公司2 小时前
LoRa模块SRRC型号核准判定解析:微功率目录边界与核准触发条件
经验分享
文飞AI智能写作2 小时前
文献阅读笔记怎么做,写综述时才能找到依据
经验分享·大学生·论文写作·文飞ai