如何简化从缓冲区读取数据包时的大量重复if-else代码
如何简化从缓冲区读取数据包时的大量重复if-else代码
嘿,看你这段代码被一堆重复的if-else占满了,肯定维护起来头疼吧?这种基于固定字节标识来执行不同逻辑的场景,用命令映射表来重构绝对是最佳选择,能把冗余代码一键清空,以后加新命令也超方便!
核心思路
把每个命令的标识(rx_buffer前两个字节)、需要返回的额外数据、要执行的操作,都封装成一个统一的结构体,然后把所有命令放到一个数组里。主逻辑只需要遍历这个数组找匹配项,统一处理重复的逻辑(比如设置OK响应),再执行对应操作即可。
具体实现步骤(以C语言为例,适配你的嵌入式场景)
定义命令处理结构体
这个结构体用来存每个命令的所有规则,按需调整字段:#include <string.h> #include <stdint.h> // 定义命令处理的结构体,按需扩展字段 typedef struct { uint8_t cmd_byte1; // 命令第一个字节 uint8_t cmd_byte2; // 命令第二个字节 uint8_t extra_tx_len; // 额外要返回的tx数据长度(0表示无) const uint8_t* extra_tx_data; // 额外tx数据的指针 void (*callback)(uint32_t param); // 要执行的回调函数(NULL表示无) uint32_t callback_param; // 回调函数需要的参数 } CommandHandler;填充命令映射表
把你所有的if-else分支都转换成表中的一行,集中管理所有规则:// 假设你的原有函数是这些 void change_light_intensity(uint32_t intensity); void change_volume(uint32_t vol); // 填充命令表,新增/修改命令只需要在这里操作 const CommandHandler cmd_table[] = { {0xAA, 0x88, 0, NULL, change_light_intensity, 1000}, {0xBB, 0x89, 2, (const uint8_t[]){0x34, 0x12}, NULL, 0}, {0x3D, 0x76, 0, NULL, change_volume, 38}, // 其他所有命令都按这个格式添加即可 };重构主逻辑
用遍历映射表代替一堆if-else,统一处理重复逻辑:// 初始化tx_buffer为默认的NO响应 tx_buffer[0] = 'N'; tx_buffer[1] = 'O'; // 获取当前收到的命令标识 uint8_t received_cmd1 = rx_buffer[0]; uint8_t received_cmd2 = rx_buffer[1]; // 遍历命令表查找匹配项 size_t table_len = sizeof(cmd_table) / sizeof(cmd_table[0]); for (size_t i = 0; i < table_len; i++) { const CommandHandler* current_cmd = &cmd_table[i]; if (current_cmd->cmd_byte1 == received_cmd1 && current_cmd->cmd_byte2 == received_cmd2) { // 统一设置OK响应 tx_buffer[0] = 'O'; tx_buffer[1] = 'K'; // 如果有额外的tx数据,复制到缓冲区 if (current_cmd->extra_tx_len > 0 && current_cmd->extra_tx_data != NULL) { memcpy(&tx_buffer[2], current_cmd->extra_tx_data, current_cmd->extra_tx_len); } // 如果有要执行的回调,带参数调用 if (current_cmd->callback != NULL) { current_cmd->callback(current_cmd->callback_param); } // 找到匹配后跳出循环,不用继续遍历 break; } }
为什么这比原来的代码好?
- 彻底消除重复代码:所有分支里重复的
tx_buffer[0] = 'O'; tx_buffer[1] = 'K';只需要写一次 - 扩展性拉满:新增命令只需要在
cmd_table里加一行,不用写新的if-else,也不会破坏原有逻辑 - 维护成本骤降:所有命令规则都集中在一处,找问题、改逻辑都不用在一堆分支里翻找
- 灵活性高:如果以后需要加统一逻辑(比如命令校验、日志打印),只需要在遍历循环里加一次,不用改每个分支
额外优化小技巧
如果你的系统资源非常紧张(比如小型MCU),也可以把命令表按标识排序,用二分查找代替遍历,进一步提升查找效率,但一般情况下普通遍历的开销完全可以忽略~
内容来源于stack exchange
相关产品推荐
相关产品推荐

