引论:让重构带来实际价值 | 1.重构理论基础: Refactoring的历史 Refactoring的本质 代码重构:Code Refactoring 模块重构:Big Refactoring 架构重构:Architectural Refactoring
2.C程序重构管窥: a)充分利用C语言:#define、#ifdef、static、union、…… 代码重构实例:用static与注释将一个.c文件的常量、变量、函数完美层次化 b)解决痛点问题:全局变量太多、多任务执行太乱 代码重构实例:按“采集-分析-执行”组织battery.c/safe.c/led.c模块间关系
3.本课内容概览: 60个技术+1套管理方法 |
分钟级重构:必备日常局部重构18技 | 4.从圈复杂度说起: 代码难维护的原因 如何让新手也能维护 C语言的9个执行变向语句
5.C的日常局部重构: 技0--引入三元表达式 技0--引入else if结构 技0--引入switch结构 技1--特殊情况提前return 技2--提炼复合判断函数 技3--提炼统一判断函数 技4--提炼统一状态转换函数 技5--借助逻辑重组,消除很傻很正确的if泥团 技6--借助数据结构,消除很傻很正确的if泥团 技7--将if-else逻辑简化为init-if逻辑 技8--封装global count var计数和判断,提供event接口 技9--封装global flag var的清零和判断,提供event接口 ……案例 ……练习
6.多函数的优化:提炼函数 技10--提炼局部变量加工函数 技11--提炼共用help私有函数 ……案例 ……练习
7.多函数的优化:合并函数 技12--合并代码重复的函数,加参数 技13--合并骨架雷同的函数,加参数 技14--合并#ifdef #else定义的多个函数 技15--数据不同算法相同,统一到宏或模板 技16--数据不同算法相同,统一到void*处理函数 ……案例 ……练习
8.多函数的优化:便捷接口函数 技17-- #define便捷接口函数 技18--二次封装便捷接口函数 ……案例 ……练习 |
模块重构:让模块维护不再痛苦24技 | 9.《人月神话》说:没有银弹? 信息隐藏 没有信息隐藏,模块化就没有意义
10.信息隐藏! 技1--常量私有化 技2--变量static化 技3--函数static化 技4--.c文件的内部结构规范 技5--.c文件的文件命名规范
11.数据结构 技6---引入结构体,集中管理多个相关变量 技7---引入配置数组,集中管理配置型常量 技8---引入下标常量,简化配置数组的使用 技9---引入union结构,支持多数据类型 技10--引入cmdBlock,集中管理多cmd var 技11--引入dataBlock,集中管理多state var 技12--将过大的globalStruct泥球拆分成dataBlock、cmdBlock 技13--优化数据结构来简化操作 ……案例 ……练习
12.接口暴露! 技14--接口函数moduleFunc()式命名 技15--任务函数的xxxx_xxxTask()式命名 技16--封装global count var计数和判断,提供event接口 技17--封装global flag var的清零和判断,提供event接口 技18--为event提供receive函数和peek函数 技19--#define便捷接口函数 技20--二次封装便捷接口函数 技21--借便捷接口避免暴露bool型参数 ……案例 ……练习
13.性能第一波 技22--去除float运算 技23--乘除运算变移位运算 技24--提供直接操作模块内部数据的指针 ……案例 ……练习 |
架构重构:阅读代码的大技巧 | 14.如何阅读嵌软代码,才能快速理解架构、画出架构 ……练习 技1:while(1)+ISR结构的快速架构理解 ……练习 技2:OS下多任务结构的快速架构理解 ……练习 技3:协议报文解析—调度—处理的快速架构理解 |
架构重构:多任务及通信优化14技 | 15.嵌软独有的复杂性 运行时的精细化控制 裸露的中断、时钟、时限、任务小而多 通盘分析多任务的必要性 建模练习:任务分布图、任务协作图
16.任务模块化 技1---按采集/分析/执行分解任务 技2---[采集]--dataBlock-->[分析]--cmdBlock-->[执行]模式 技3---显式命名采集/分析/执行任务函数(collect/analyse/action) ……案例 ……练习
17.中断处理 ISR与外界通信 技4---ISR抛出信号量 技5---ISR写全局变量 时钟中断 技6---ISR负责计数+生成事件 技7---将处理分离到时间片任务 ……案例 ……练习
18.通信优化 技8---隐藏任务+队列,暴露同步接口函数 技9---将过大的globalStruct泥球拆分成dataBlock、cmdBlock 技10--显式命名gxxDataBlock、gxxCmdBlock全局变量 ……案例 ……练习
19.性能第二波 硬实时 技11--由ISR处理紧急任务 控制执行频率 技12--变while(1)执行为时间片执行 处理OverLoad 技13--控制采样率 技14--控制取样率,抛弃部分采样 ……案例 ……练习 |
架构重构:“底层规范、中层聪明”12技 | 20.嵌软分层规律 Layer就是一组Code Module 横向分层 纵深封装 技1—各层模块文件名命名规范 技2—提炼通用Svc模块 ……案例 ……练习
21.Drv等底层模块 技3—将硬件相关代码分离到Drv模块 ……案例 ……练习
22.HAL与Svc层抽象:纵深封装 技4—Hal模块封装Drv模块 技5—Svc模块封装Hal与Drv模块 技6—借函数指针结构体支持底层可替换 ……案例 ……练习
23.HAL与Svc层抽象:状态机 技7—统一的FSMCore作为高层event生成器 技8—提炼统一状态转换函数 技9—引入状态机配置数组 ……案例 ……练习
24.HAL与Svc层抽象:协议子系统 技10--将粗糙的uint8_t[]报文结构升级成struct 技11--将报文codec代码从Drv模块中分离出来 (协议模块硬件无关/功能无关) 技12--构建管道-过滤器架构 技13--Packet Adapter作为可插拔过滤器 ……案例 ……练习 |
架构重构:4种需求变更的设计应对 | 需求变更 A类:不同厂商的器件 B类:不同类型的器件 C类:不同网络或协议 D类:不同功能或算法 ……案例
A类应对——drv.c 局部改变,接口不变 •实例分析
B类应对——drv.c 改变,hal 不变 •实例分析
C类应对——设计支持协议的新增与适配 •实例分析
D类应对——自底向上,逐级优化设计 •实例分析 |
成功架构重构的关键步骤与管理原则 | 本课程模块大纲不公开
要不要文档? 要不要预先设计? 代码改改改过程中有没有里程碑供风险评估? 全面重构从哪一层开始? …… |