你的技术债务可能不是债务,是遗产
技术债务这个比喻太深入人心了,以至于所有旧代码都被贴上了"债"的标签。重构计划里排满了"还债"任务,架构升级的理由是"降低技术债务",新人入职第一件事是听老人抱怨欠了多少债。
但仔细想想,你管它叫债,它就真的欠了什么吗?
债务这个比喻哪里不对
债务意味着你有偿还义务。你借了钱,必须还。到期不还,利息越滚越多,最终破产。
代码不是这样的。
一段跑得好好的代码,即使写法丑陋、架构混乱、没有测试覆盖,只要它在生产环境稳定运行,就没有人强迫你"还债"。业务的每一个需求都可能让你动这段代码,但你可以选择不动它——包一层,绕过去,新功能走新路径。
真正的问题不是"不还债会怎样",而是"你还了债能得到什么"。
大部分技术债务偿还计划高估了收益。重构一个模块,你的预期收益是什么?代码更整洁了,开发者体验更好了,将来改起来更方便了。但这些收益几乎无法量化。你很难说服老板说:"我花两个礼拜重构这个模块,将来的需求开发速度会提升百分之多少。"
而你需要放弃的成本是实实在在的:两个礼拜的业务产出,可能还有引入 bug 的风险。
这不是债务,这是投资。投资就得算回报,而不是用"还债"的道德感来绑架决策。
把遗产和债分开
我见过很多所谓的"技术债务",其实更像是遗产。
遗产的特征是:它曾经有价值,现在依然在产出,但你不想要它了。它不符合你的审美,不符合你的技术品味,不符合你对"好代码"的定义。
一个 2018 年写的 jQuery 模块,没有任何测试,全局变量满天飞,代码格式混乱。但它每天稳定处理着几万笔交易,从未出过大问题。
这是债务吗?按经典的定义,是的——没有测试就是技术债务。但这更像是一笔遗产:它有价值,能持续产出,你有权处置它,但没有义务"偿还"什么。
债务是必须还的,遗产是可以继承也可以放弃的。
这个区分不是咬文嚼字。把旧代码当债务,你会带着负罪感工作,总觉得欠了什么。把它当遗产,你会理性地评估:处理这笔遗产的收益是否大于成本?
什么时候它真的是债
当然,有些代码确实是债务。
特征很明确:你不处理它,它会在未来持续给你带来成本。不是"看着不爽"的心理成本,而是真金白银的工程成本。
比如,一个数据模型和三个业务系统强耦合。每次改其中一个系统,另外两个也有概率出问题。这种耦合让你每次需求迭代的成本都在增加——这就是利息。
比如,一个没有回滚机制的部署流程。每次上线都是一次赌博,出了问题只能硬着头皮热修。这种风险是持续存在的——这也是利息。
再比如,一个只掌握在一个人手里的核心模块。这个人请假那天,整个团队都不安心。这种单点依赖每天都在积累风险——这还是利息。
真正的技术债务有一个简单判断标准:不处理它,你的工程成本会不会随时间持续增加? 如果会,那是债。如果不会——只是"丑"但稳定运行——那是遗产。
重构的真实动机
把技术债务和遗产区分开之后,你会发现大部分重构计划的真实动机不是"还债",而是以下几种:
一种是技术审美。老代码写得丑,新来的工程师看不惯,想用更"正确"的方式重写。这没什么错,但别包装成还债。你得承认这是在满足自己的审美需求,然后诚实地评估值不值得花这个成本。
一种是架构升级的前置条件。你想引入微前端,但现有代码不支持;你想上 TypeScript,但项目全是 JS。这时候重构确实有价值,但价值不来自"减少技术债务",而来自"支撑下一步业务发展"。
一种是降低团队认知负荷。一个模块太复杂,新人看不懂,改代码总出问题。这确实会持续增加工程成本,算真正的债。但边界要划清楚:是认知负荷增加了成本,还是你只是觉得代码丑?
最后一种——也是最诚实的——是为了自己能睡好觉。每天维护一坨你无法理解的代码,精神压力是真实的。这不丢人,但别用"技术债务"来包装个人偏好。
什么时候该动遗产
既然遗产没有"必须处理"的义务,那什么情况下值得动?
我自己的判断标准是三条,满足任意一条就值得考虑:
它在阻碍业务。 不是"可能会阻碍",是"现在就在阻碍"。产品提了一个需求,你说做不了,因为老代码架构不允许。这是最硬的理由,业务价值直接可量化。
它的维护成本可预见的会上升。 比如依赖的库即将停止维护,或者业务量增长即将触及它的性能瓶颈。这是风险驱动,需要预判但不需要精确量化。
团队要把这块代码交出去。 新人入职要接手这个模块,或者要交给外包团队。这时候代码的可读性和规范性不再只是审美问题,而是交接成本的问题。
如果三条都不满足——代码稳定运行,业务没有受阻,维护成本没有上升趋势,也没人要接手——那就别动它。让它继续当遗产,安安静静地跑着。
把精力花在更有价值的事情上,比动一坨跑得挺好的老代码对团队贡献大得多。
别用"还债"绑架决策
"技术债务"这个词最大的危害,是它自带道德压力。
欠债不还是不道德的。所以当你提议"还债"时,反对的人看起来就像是不负责任。这导致很多团队在做技术决策时,不自觉地偏向"还债"——因为在道德叙事上,还债永远是对的。
但如果你换一种说法:"我提议花三个星期重构这个模块,预期收益是代码更整洁,但业务功能不会有任何变化。"这个提案的优先级立刻就降下来了。
这不是因为团队不重视代码质量,而是因为团队有更紧迫的事情要做。
我不是说重构不重要。我是说,把重构包装成"还债"是一种语言上的欺凌——它用道德感代替了理性分析,让决策变得不客观。
把旧代码当遗产,你就不得不回答一个更诚实的问题:处理这笔遗产的投入,跟别的投入相比,到底哪个更值得?
这个问题的答案,往往比"我们欠了多少技术债务"有用得多。
添加新评论