编程 代码可以无限变坏:为什么沉船比喻误导了我们对技术债务的理解

2026-09-06 11:10:16

代码可以无限变坏:为什么"沉船"比喻误导了我们对技术债务的理解

软件工程师 Zach Kehs 发表了一篇文章《There's No Limit to How Bad Code Can Get》,挑战了用"沉船"等比喻描述代码库质量的常见做法。文章的核心观点是:技术债务没有破产、没有清算、没有干净的重置,那些暗示存在底线的比喻给了我们虚假的安全感。软件属于抽象领域,不像建筑或桥梁那样受物理规律约束——你可以永远给建筑加楼层,它最终会倒塌,但软件没有这样的限制,代码总是可以变得更糟。

"沉船"比喻的问题

文章从作者十多年前在亚马逊的经历讲起。他刚加入亚马逊时,在一个处理订单的团队工作。表面上看,订单处理的逻辑很简单:写一些东西到数据库,调用其他团队的服务做验证或更新记账。团队估计,维护和演进这个系统不需要超过二十几个工程师。

然而,实际情况是这个组织有数百人,系统已经变得如此庞大和复杂,以至于不可能学会它的全部工作方式。很少有人在这个组织待超过几年,制度性知识已经流失。结果是代码中充满了"闹鬼的墓地"(haunted graveyards)——那些没有人敢碰的代码,因为谁也不知道改了会出什么问题。

恐惧压制了任何简化现有系统的努力(而这种努力本身也得不到奖励)。每种订单类型的业务规则都是很久以前由已经不在的人决定的。这些规则有时能在一个过时的、自称为"活文档"的文件中找到,但更多时候根本找不到任何书面记录。自己追踪行为也不容易,因为系统的很多部分跨越了团队边界,代码不容易访问。

软件没有物理底线

文章的核心论点是:软件属于抽象领域,不受物理世界的约束。

物理世界有底线

  • 一栋建筑可以加楼层,但最终会因为结构负荷而倒塌
  • 一座桥梁可以增加荷载,但最终会因为材料强度而断裂
  • 一辆汽车可以增加复杂度,但最终会因为物理空间而无法继续

这些物理约束意味着存在一个客观的"底线"——超过这个点,系统就会物理性地失效。

软件没有底线

软件没有这样的约束:

  • 可以永远增加新的间接层
  • 可以永远降低性能
  • 可以永远增加耦合
  • 可以永远制造更多的"闹鬼墓地"
  • 可以永远让代码更难理解

代码质量没有客观的下限。它可以一直变坏,直到业务本身无法继续运营——而不是因为代码到达了某个假设的底线。

技术债务的真实风险

文章指出,技术债务的真正风险不是代码质量到达某个底线,而是:

1. 业务先于代码沉没

"业务会在代码质量到达假设底线之前就沉没。"这是文章最关键的洞察。技术债务不会像财务债务那样有一个明确的违约点,它会逐渐侵蚀组织的能力,直到业务无法继续。

2. 制度性知识流失

当系统变得太复杂,没有人能理解全部时,制度性知识就开始流失。人员流动加速了这个过程——老员工离开,新员工无法快速上手,系统的维护成本不断上升。

3. 恐惧驱动的开发

"闹鬼墓地"导致恐惧驱动的开发。开发者不敢修改现有代码,只能在外面加新的层。这进一步增加了复杂度,形成恶性循环。

4. 没有干净的重置

与财务债务不同,技术债务没有破产清算。你不能宣布"代码破产"然后重新开始——重写的成本和风险通常极高,而且重写过程中还会引入新的技术债务。

对工程实践的启示

1. 不要被虚假的安全感误导

"代码还没到最差"不是一个有效的论据。因为代码可以无限变坏,"还没到最差"只意味着它还可以变得更差,而不是它还安全。

2. 主动简化,而不是被动应对

简化现有系统的努力通常得不到奖励(因为"没坏就不要修"的心态),但这正是防止技术债务累积的关键。应该在工程文化中鼓励和奖励简化工作。

3. 投资制度性知识

文档、代码注释、架构决策记录(ADR)、onboarding 流程——这些都是防止制度性知识流失的投资。它们的回报可能不会立即显现,但长期来看是技术债务的最佳对冲。

4. 设定质量红线

虽然代码质量没有客观底线,但组织可以设定主观的质量红线。例如:

  • 代码覆盖率不低于某个阈值
  • 圈复杂度不超过某个限制
  • 新代码必须有设计文档
  • 定期进行架构评审

这些红线不能阻止代码变坏,但可以减缓恶化的速度。

总结

这篇文章挑战了我们对技术债务的常见理解。用"沉船"比喻代码库是误导性的,因为它暗示存在一个底线——超过这个点船就会沉。但软件没有物理约束,代码可以无限变坏。技术债务的真正风险是业务先于代码沉没,而不是代码到达某个假设的底线。理解这一点有助于我们建立更健康的工程文化,主动简化、投资知识管理、设定质量红线,而不是被动地等待"沉船"的那一刻。

来源:https://zachkehs.com/blog/theres_no_limit_to_how_bad_code_can_get/

推荐文章

程序员茄子在线接单