本节摘要:重构是在不改变外部行为的前提下重组代码结构。本节复盘青线输送段的一次真实返工:第一版"哪里需要写哪里"的逻辑在工艺调整面前瘫痪三天,重构成功能块分层后同类调整变成一行配置;由此提炼出识别下沉点、行为等价、小步提交三条重构纪律。
本章前四节都在讲"怎么写对",这一节讲"怎么写得不后悔"。它是全章的收官,因为重构是前面所有手法的再组织——状态机、PID、运动控制各写各的都对,堆进一个程序块里仍可能变成一锅粥。青线用三天返工换来这一课,学费由项目付,心得归你。
返工的起点是一次看似不起眼的工艺变更。青线输送段第一版逻辑按"段落"组织:一号段一个程序块,里面塞着启保停、堵料判断、段间联锁、启动链步序、故障处理,五套职责同居一屋。两周写完,仿真通过,一切美好——直到验收前一周,工艺提出调整:暂存段满仓时不再停整线,改为降速分流到备用通道。
这个变更在第一版结构里意味着什么?堵料判断散落在四个段的程序块里,各自内联写成不同形状的IF;改一个判据要动四个地方,而且每处的变量名与写法还都有细微差异——先改错一处,仿真才发现。三天后改完,第四天的评审会上有人问:"备用通道将来要是也满仓呢?"会议室安静了。当晚我们决定重构。

重构最难的不是动手,是决定"切哪里"。青线复盘后总结出三个下沉信号,符合任意一条的逻辑就是搬迁候选。一是复用信号:同一段判断在两处以上出现且形状相似——四个段的堵料判断正是如此;二是参数化信号:一段逻辑里埋着可调数值——堵料延时、启停间隔当初全写死在逻辑里;三是职责信号:一个程序块需要用超过一屏来描述它"负责什么"——第一版每段程序块的职责要写五行。
按信号扫描,输送段的五套职责全部中选:启停下沉到3.4节的Motor_FB,联锁下沉为Interlock_FB,堵料判据下沉为Jam_Detect_FB,启动链独立为Seq_Start_FB并把间隔与判据全部参数化。程序层只剩编排:四段各一行调用,读起来就是一张设备清单——2.4节"程序只编排"的规矩,至此才算真正落地。下沉的次序也有讲究:先搬最独立、最稳定的(启停),最后搬依赖最重的(启动链要调用前面所有块的反馈)——依赖少的先走,每一步的回归范围都最小。
重构最大的风险是"改好了结构、改坏了行为"。青线的三条纪律把风险摁住。第一,行为等价验证:重构前后各跑同一组仿真用例——正常启停、堵料、急停、断反馈,输出轨迹必须逐拍一致;这组用例在重构前先录制,成为重构的验收标准。第二,小步提交:一次只搬一个职责进功能块,搬完跑用例、提交版本库,绝不做"一晚上大搬家"——出错时能退回的最近一步就是上个提交。第三,重构期冻结功能:重构窗口里不接受任何新需求,结构与功能两件事永远不同时动。三条纪律的公共底座是仿真用例库——没有可重复的验证手段,再漂亮的纪律都只是愿望,这也是7.2节把用例库称为"重构保险"的原因。
// 重构后的程序层:四段输送,四行编排 Conv1_Line(Motor := Motor_FB_1, Jam := Jam_FB_1, IL := IL_FB_1); Conv2_Line(Motor := Motor_FB_2, Jam := Jam_FB_2, IL := IL_FB_2); Conv3_Line(Motor := Motor_FB_3, Jam := Jam_FB_3, IL := IL_FB_3); Conv4_Line(Motor := Motor_FB_4, Jam := Jam_FB_4, IL := IL_FB_4); // 那次工艺变更最终只改了 Jam_Detect_FB 内部与一个分流参数
| 检查项 | 问法 | 不合格的处置 |
|---|---|---|
| 复用扫描 | 这段判断是否在两处以上出现 | 下沉为功能块 |
| 魔法数字 | 逻辑里是否埋着写死的数值 | 提为参数进数据字典 |
| 职责陈述 | 一个块的职责要写几行 | 超过一屏就拆 |
| 行为等价 | 重构前后用例轨迹是否一致 | 不一致立即回退 |
| 提交粒度 | 这步改动能否单独回退 | 一次一个职责 |
青线是疼了才重构,聪明些的做法是在信号出现时就动。四个重构信号提前告诉你该动刀了:程序评审时某个块的职责陈述需要"以及"连接两次以上;变更单的影响分析开始频繁出现"波及多个段落";新同事读代码的提问集中在"这段在干嘛"而非"为什么这么干";仿真用例的维护成本超过逻辑本身的修改成本。四个信号命中任意两个,把重构排进下一个迭代窗口——重构的最佳时机永远是"还没疼的时候",因为它本质是把未来的疼提前分期偿还。
还要澄清一个误区:重构不等于重写。重写是推倒重来,风险与工期都不可控;重构是在行为等价的保护伞下小步搬家,每一步可回退。青线输送段的重构全程四天,其中三天在仿真里跑回归——写代码一天,验证三天,这个比例在重构里不是浪费,是保险费率。
重构最容易被管理层挑战的一点是"你只是把代码挪了个地方"。青线用三组数字回应。第一组是变更耗时:同类工艺变更从三天缩到两小时,这是最硬的通货。第二组是缺陷密度:重构后一个季度,输送段的联锁类报警从每周三点二次降到零点五次——逻辑没变,结构替逻辑挡住了手滑。第三组是评审速度:新逻辑块的评审时间从平均四十分钟缩到十五分钟,因为"一状态一块、一设备一类"的代码读起来有惯性。三组数字进复盘报告,重构从"工程师的洁癖"变成有投资回报的工程动作。
度量也反过来校准重构的度:如果某个功能块拆出后从未被第二处复用、变更时也从没单独改过它——它可能是一层多余的间接。结构服务变更,不是变更服务结构,度量是最好的裁判。
逻辑五手法到此齐装。下一章把设备间的语言接通:变频器、远程站与上位系统的通信课。