一、C语言遗产的现状与挑战:为什么需要重构?
说实话,我入行二十年,见过太多C语言遗留系统了。有的跑在航天器上,有的控制着核电站,还有的支撑着银行的核心交易系统。这些系统有个共同点——它们都「活着」,但活得越来越痛苦。
为什么?因为业务在变,硬件在变,安全要求在变,唯独那堆C代码,还停留在上世纪九十年代的模样。
核心观点:遗留系统不是垃圾,它是公司的核心资产。但资产不维护,就会变成负债。
1.1 遗留系统的典型特征
我在项目中遇到过一套运行了十五年的电信计费系统。打开源码的那一刻,我差点以为穿越了。嗯,这里我总结一下,遗留系统通常有这些「病征」:
- 全局变量满天飞——一个文件里十几个全局变量,函数之间靠全局变量传参,你改一个,全盘崩。
- 函数动辄上千行——一个函数干所有事,读文件、解析、计算、写日志、发消息,全塞在一起。
- 没有单元测试——甚至没有测试文档。改代码全靠「胆大心细」,上线全靠烧香。
- 硬编码无处不在——IP地址、端口号、超时时间,全写在代码里。换个环境?重编译吧。
- 注释要么没有,要么骗人——「这里修复了bug」——什么bug?为什么这么修?没人知道。
- 依赖老旧编译器/库——还在用VC++ 6.0,或者某个早已停止维护的第三方库。
我的经验:判断一个系统是不是遗留系统,最简单的办法——你问团队「这个函数是干什么的」,没人能完整回答。那就说明,该重构了。
1.2 为什么需要重构?
你可能会问:「系统跑得好好的,为什么要动它?」
这个问题我听过太多次了。说白了,不动它的代价,比动它的代价更大。
- 维护成本指数级上升——每加一个功能,改一个bug,都要花比新系统多3-5倍的时间。
- 人才流失——没人愿意维护一堆烂代码。优秀的工程师会走,留下的要么是新人,要么是混日子的。
- 技术债务利息太高——你今天不改,明天改的成本更高。拖得越久,利息越重。
- 安全风险——老代码往往存在缓冲区溢出、内存泄漏、未初始化变量等问题。在今天的网络安全环境下,这就是定时炸弹。
- 无法适应新需求——微服务?容器化?云原生?遗留系统根本跑不动。
警告:我曾经见过一个金融系统,因为不敢重构核心交易模块,结果每次升级都要停服4小时。后来竞争对手推出了7×24小时服务,他们直接丢了30%的市场份额。重构不是成本,是投资。
二、重构 vs 重写:决策模型
这是每个团队都会纠结的问题。我自己的经验是——不要非黑即白。重构和重写不是对立关系,而是一个连续谱。
2.1 什么时候该重构?
- 代码逻辑还在,只是结构混乱——比如函数太长、命名不规范、重复代码多。这种情况,重构性价比最高。
- 业务规则复杂且不明确——没人能说清楚某个模块到底在干什么。重写的话,你连需求都理不清。
- 系统还在频繁迭代——如果业务方每周都要提新需求,你不可能停下来重写。只能边重构边加功能。
- 团队对业务理解不够深——新人多,老人少。重写风险太大,不如逐步重构,边做边学。
2.2 什么时候该重写?
- 技术栈彻底过时——比如还在用16位编译器,或者依赖的操作系统已经停止支持。
- 架构无法扩展——单机架构要改成分布式,或者单体应用要拆成微服务。这种改动,重构几乎不可能。
- 代码质量太差,无法测试——函数之间耦合严重,全局变量到处都是,你改一行代码,不知道会影响哪里。这种代码,重构的成本比重写还高。
- 业务逻辑已经明确且稳定——如果业务方说「这个模块以后不会再变了」,那重写一个干净的版本,一劳永逸。
2.3 决策模型:四象限法
我习惯用一个简单的四象限来做决策。你想想看:
| 业务价值高 | 业务价值低 | |
|---|---|---|
| 代码质量高 | 保持现状,小修小补 | 逐步淘汰,不要投入 |
| 代码质量低 | 优先重构 | 考虑重写或替换 |
说白了,高价值 + 低质量 = 重构首选。低价值 + 低质量?别浪费时间了,直接换掉。
避坑指南:我曾经在一个项目中,团队花了半年时间重写一个「看起来很烂」的模块。结果重写完后发现,原来的代码里处理了十几个边缘情况,新代码一个都没考虑到。上线第一天就出事故。所以——不要轻易重写你不完全理解的代码。
三、知识体系总览
下面这张图,是我对本章内容的一个总结。它展示了遗留系统的现状、挑战,以及重构与重写的决策路径。
四、我的建议
最后,我想说几句掏心窝子的话。
重构不是炫技,不是把代码改成你喜欢的风格。重构是为了让系统活得更久、更健康。我见过太多团队,重构到一半就放弃了,因为「太累了」「业务催得紧」。结果呢?代码比以前更烂。
如果你问我,重构最重要的原则是什么?我的答案是:不要停。每天改一点点,每周重构一个函数,每月清理一个模块。一年下来,你会发现系统脱胎换骨。
记住:遗留系统不是一天建成的,也不是一天能改好的。但只要你开始改,它就在变好。
公众号:蓝海资料掘金营,微信 deep3321