Software Architect · 模块 03

技术债不是烂代码的同义词。它是一种妥协——必须是有意识的、被记录在案的,并且总有一天要偿还的。

Debt quadrant · interest · repayment strategy

§ 01

当债务为你买到了时间,它就是有用的。当团队根本不知道自己已经借了钱,它就是危险的。

不是所有烂代码都是技术债

贷款和被偷的钱包都是财务问题。但处理它们的方式完全不同。

technical debt 出现在团队有意识地选择了一个"当下更便宜"的方案,并且清楚地理解未来的代价。例如:"在拿到第一批付费客户之前,我们不做完整的 multi-tenant 模型。"——这是债。

但"我们没写测试,是因为忘了",或者"没有人理解 invariants"——这不是债,这是 engineering discipline 的缺陷。把什么都叫成技术债是危险的:业务方就分不清哪里是战略性的妥协,哪里只是单纯的活儿没干好。

利息比本金更重要

家门口的一个小坑天天让你心烦。森林深处的一个大坑可能多年都没人在意。

债务的利息,就是它给变更带来的减速。如果债压在开发的 hot path 上,即使本金不大也很贵。如果债压在很少被碰的迁移脚本里,也许是可以容忍的。

架构师评估的不只是"它有多丑",而是"我们为它付费的频率有多高"。所以 debt register 里应该记录 impact、owner、trigger for repayment 和 risk。

§ 02

当一笔债有理由,也有偿还策略,它就变得可管理。

例子:暂时单 region

新店先开第一家门店,不会在第一单成交之前就先把全国物流建起来。

团队先在单一 region 上线 SaaS,尽管他们知道 enterprise 客户后续一定会要求 data residency。这个决策被写进 ADR:暂时只用单 region,因为还没有提出这个要求的客户;触发重新评估的条件是首个 enterprise 合同,或欧盟用户占比达到 20%。

这就是合理的 deliberate debt。它有理由、有边界,也有重新审视的触发条件。

"以后重写"如果没有日期也没有条件,就不是计划,只是一句咒语。

团队为 billing 写了一套没有 idempotency 的实现,理由是"用户量还小"。这是危险的:一次错误就可能立刻烧掉钱和信任。这种债不合理——风险和省下的工作量根本不成比例。

并非所有债都一样。在 payments、security、数据、以及具有法律意义的操作上承担债务,要求远比其他地方更硬的论证。

自检
  • 我们为什么要背上这笔债? - 谁负责偿还? - 哪个信号会让我们回头处理? - 如果这笔债真的爆掉,哪些用户会受伤?