第三章 架构重构方法论:绞杀者模式、修缮者模式、重构优先级矩阵

架构重构这事儿,说起来容易做起来难。我见过太多团队,一上来就喊着「我们要重写整个系统」,结果呢?半年过去了,新系统没跑起来,老系统也改不动了。说白了,重构不是推翻重来,而是有策略地逐步改善。

这一章,我跟你聊聊三种实战中摸爬滚打出来的重构策略。它们不是什么高深理论,而是我在多个嵌入式项目里真刀真枪用过的招数。

3.1 绞杀者模式(Strangler Fig Pattern)

这个名字挺有意思,绞杀者是一种植物,它缠绕在宿主树上慢慢生长,最终取代宿主。用在软件重构上,意思就是:不直接删除旧代码,而是在旧系统外围构建新功能,逐步把旧模块替换掉。

我在一个工业控制器的项目里用过这招。那套系统跑了七八年,主控模块的代码耦合得跟麻花似的。客户要求加新协议支持,但旧代码一动就崩。怎么办?

我的做法是:在旧系统旁边搭一个新模块,通过一个适配层跟旧系统通信。新协议全部走新模块,旧协议继续跑老代码。等新模块稳定了,再把旧模块的功能一点点迁移过来。

核心思路: 新旧共存,逐步替换,风险可控。

具体步骤是这样的:

  1. 识别边界 — 找到旧系统中可以被替换的独立功能模块。
  2. 建立适配层 — 写一个接口层,让新旧系统能互相调用。
  3. 增量替换 — 每次只替换一个功能点,测试通过后再继续。
  4. 清理旧代码 — 旧模块完全被替代后,删掉它。

你想想看,这跟外科手术似的,一刀一刀切,而不是拿大锤砸。我建议你在以下场景用绞杀者模式:

  • 旧系统还在线上跑,不能停机
  • 旧代码没有单元测试,不敢大改
  • 团队对新架构还不熟悉,需要时间学习
注意: 适配层本身会引入额外复杂度。我曾经在一个项目里适配层写得太厚,结果新老系统都依赖它,反而成了新的瓶颈。记住,适配层要轻量,只做协议转换,别塞业务逻辑。

3.2 修缮者模式(Builder Pattern)

绞杀者模式适合替换大模块,但有些时候,你不需要替换整个模块,只需要在原有基础上「修修补补」。这就是修缮者模式——在旧代码内部做局部改造,不改变外部接口。

我记得有个传感器数据采集的项目,采集线程里塞了一大堆业务逻辑:数据校验、滤波、存储、报警判断……全揉在一个函数里。每次改需求,都得动那个函数,改完就出bug。

我没急着重写,而是用了修缮者模式:

  • 先把数据校验抽成一个独立函数
  • 再把滤波算法单独拎出来
  • 存储和报警也各自拆开

每次只拆一个功能,拆完就跑测试。一个月下来,那个大函数从800行变成了80行,每个小模块都能单独测试。外部接口没变,但内部结构清爽多了。

我的经验: 修缮者模式最适合「代码烂但功能稳定」的模块。别想着一步到位,每次重构只改善一个点。我给自己定了个规矩:每次提交代码,至少让某个函数的圈复杂度降低1。

修缮者模式的核心原则:

  1. 接口不变 — 外部调用者感知不到变化
  2. 小步改造 — 每次只重构一个内部细节
  3. 测试先行 — 改之前先写测试,确保行为不变
  4. 持续集成 — 每次改动都要能编译通过、跑通测试

3.3 重构优先级矩阵

好,现在你知道了两种模式,但问题来了:先改哪个模块?

我见过不少团队,一上来就挑最烂的模块下手,结果改到一半发现那个模块其实很少被调用,投入产出比极低。这就是典型的「用战术勤奋掩盖战略懒惰」。

我的做法是画一个重构优先级矩阵,横轴是「模块变更频率」,纵轴是「代码质量评分」。这样一画,四个象限就出来了:

象限 变更频率 代码质量 优先级 策略
第一象限 高 低 最高 立即重构(绞杀者或修缮者)
第二象限 高 高 中 保持,定期评审
第三象限 低 低 低 记录问题,暂不处理
第四象限 低 高 最低 不动它

你看,第一象限的模块才是你的「心腹大患」——经常要改,但代码又烂。这种模块不改,每次改需求都是在刀尖上跳舞。

怎么给代码质量打分?我一般看这几个指标:

  • 圈复杂度 — 超过15就要警惕,超过30必须重构
  • 函数长度 — 超过200行的函数,基本是「万金油」
  • 耦合度 — 改一个地方,要动几个文件?超过3个就算高耦合
  • 测试覆盖率 — 低于30%的模块,改起来心里没底
避坑指南: 我曾经在一个项目里,花了两周重构一个「代码质量极低但几乎没人改」的模块。结果重构完了,业务方说这个模块下个月就要被新系统替代了。白干了。所以记住:优先级矩阵的横轴「变更频率」比纵轴「代码质量」更重要。

下面这张图是我常用的重构决策流程,你可以参考:

重构优先级决策流程 识别所有模块 评估变更频率(高/低) 评估代码质量(高/低) 高变更+低质量? 是 立即重构 否 放入低优先级队列 说明: 高变更 + 低质量 = 最高优先级。其他组合按矩阵表格策略处理。

3.4 三种策略如何选?

好了,现在你有了三种武器:绞杀者、修缮者、优先级矩阵。怎么搭配使用?

我个人的习惯是这样的:

  • 模块边界清晰,且需要替换整个功能 → 用绞杀者模式
  • 模块内部混乱,但功能稳定,接口不能变 → 用修缮者模式
  • 不知道从哪下手 → 先画优先级矩阵,找到第一象限的模块
一个小技巧: 优先级矩阵不是画一次就完事了。我每两个迭代(sprint)会重新评估一次。因为业务在变,模块的变更频率也在变。上个月没人动的模块,这个月可能就成了热点。

最后说一句:重构不是炫技,是投资。你把时间花在刀刃上,代码质量会给你回报。花错了地方,那就是沉没成本。优先级矩阵就是帮你做这个判断的。