意图债务是软件生成速度快于任何人能解释其何以成立时累积的延迟理解。它是系统本应做什么、实际做什么,以及维护者仍可按需重建什么之间不断扩大的空隙。经典技术债务是延迟的清理,意图债务是延迟的领悟——它在某次出故障、而房间里无人能说出代码为何如此成形时到期。
生成移除了一道曾默默发挥作用的约束:缓慢的书写节奏把理解作为副作用强加进来。去掉摩擦,理解就不再免费到来。
- 生成代码干净抵达并通过每一项检查,却从未有人在头脑中持有它的完整形状。
- 技术债务活在产物里;意图债务活在人与产物之间的空隙里。
- 你可以重构凌乱的代码,却无法重构回从未被记录的意图。
- 当代码读起来好到足以压制怀疑时,理解空隙增长最快。
- 覆盖率、延迟和绿色构建可以维持,同时解释系统的能力在衰减。
- 偿还不是清理;而是被捕捉为可执行期望的重新推导。
意图债务与技术债务有何不同?
意图债务指的是承载一套无人能在不从行为重新推导的情况下说出其推理的软件之成本。它是团队与其代码之间关系的属性,而非代码本身的属性。两套系统可以字节级相同却携带不同的意图债务,因为债务按谁仍能解释产物来衡量,而非按产物如何阅读。
这一区分之所以重要,是因为两种债务在利息下表现不同。技术债务坐落在产物中;意图债务坐落在人与产物之间的空隙中。你可以通过重构偿还凌乱代码。你无法通过重构回到从未被记录的意图,只能缓慢重建——靠阅读、猜测、并对照行为测试。
一个团队可以交付通过每一项检查、干净扩展、读起来良好的功能,却仍携带巨大的意图债务——因为从未有人类作者在头脑中持有完整形状。产物是干净的。背后的理解缺失。这种缺失直到代码自身无法回答的变更请求到来时才宣告自己。
经典技术债务总是部分可见。它表现为重复、评审者可指认的缠结、明显长大超过其名字的函数。意图债务藏得更好,因为通常标示疏忽的表面——丑陋代码——正是生成最先抛光的表面。
| 属性 | 经典技术债务 | 意图债务 |
|---|---|---|
| 所在位置 | 在产物中 | 在人与产物之间的空隙中 |
| 如何显现 | 可见混乱、缠结、重复 | 直到变更或缺陷到来才可见 |
| 如何偿还 | 重构代码 | 重新推导并记录推理 |
| 干净代码的作用 | 减少它 | 隐藏它 |
什么是理解空隙?
理解空隙是团队负责的代码量与其任一成员能从第一性原理推导、辩护或安全修改的量之间可测量的距离。它在构建期间往往不可见,在修复期间则无可辩驳。团队在功能按时落地时很少察觉空隙;它在缺陷落入无人读过的区域那一刻才察觉。
使空隙不同于普通不熟悉之处在于:它不再像从前那样随资历缩小。在手写系统里,建造某区域的人理解它,那种理解缓慢老化。在生成系统里,作者身份与理解在创建时就分离,资历不再保证有人持有模型。
- 理解空隙
- 团队拥有的代码与其成员能从第一性原理重建的代码之间的距离。
- 延迟理解
- 创建时从未被捕获、之后通常在压力下必须重建的推理。
- 持有的代码与托管的代码
- 人能按需解释的代码是持有的;仅仅跑在团队仓库里的代码只是托管的。
为何意图债务会复利而非保持平坦?
意图债务沿三条轴复利,每一条都在有人察觉前把空隙再撑大一点。危险的是复利。单个无法解释的模块是可管理的负债;同一模式贯穿一个季度的交付,就变成行为被集体拥有、却无人个体持有的系统。
体量是显见的轴。生成系统以更大单元抵达——整模块、整流程——因此未读表面增长快于阅读容量。第二是看似合理。生成代码流畅;读起来像细心作者所写,从而压制本会触发细看的怀疑。第三是周转。每一次再生丢弃上一次建立的心智模型;理解重置,而代码继续前进。
陷阱在于:这些都不登记在团队通常盯着的仪表盘上。覆盖率维持。延迟维持。构建是绿的。被侵蚀的是更安静的属性:一位称职的维护者在不便时刻拿到失败用例时,能在不从头重新推导系统的情况下定位原因的概率。
无人亲写的代码由谁维护?
断层线穿过一个问题——坏了谁维护——而生成系统往往答得很差。维护一向假定链条上游某处有一位知道为何做此决定的作者。当作者是流程而非人时,这一假定悄然失效,义务落在值班者身上。
意图债务在此不再抽象。成本由特定时刻的特定人支付:在时间压力下面对陌生代码、无可咨询的原作者、无可倚靠的记录理由的维护者。其唯一出路是重建,在最糟的时机、对着最高的赌注进行。
成本也在时间上不公平地再分配。生成系统的团队捕获速度;往往由不同人组成的后续团队继承理解空隙。因为收益与账单落在不同肩上,债务容易背上、难以拒绝。
能否测量团队实际持有多少意图?
有用的测试是解释测试。挑选系统中任意非琐碎路径,问团队中是否有人能在不重读代码的情况下讲述它为何如此、改动会坏什么。通过路径的比例,粗略衡量团队实际持有多少意图,相对仅托管多少。
注意解释测试不衡量什么。它不谈当下的质量、风格或正确性。一条路径可以完美仍未通过测试,因为通过要求人承载推理,而不只是结果。这正是生成代码往往跳过的属性。
定期运行测试,而非一次。理解会腐坏;上季度通过的路径,若其间被再生,即使行为未变,本季度也可能失败。随时间跟踪通过率,把隐形负债变成团队可与既有可信数字并列监视的数字。
什么真正偿还意图债务?
偿还意图债务不是重构;是被捕捉的重新推导。操作顺序使之可行,因为在错误海拔恢复的理解会在需要前蒸发,而均匀铺开于系统的努力大多浪费在无人会触碰的路径上。
- 定位最高流量路径——维护者在压力下会遇到的那些——并把工作限定于此。
- 通过阅读行为而非注释,重建每条背后的意图,并用平白文字把为何写在代码旁。
- 把找回的意图编码为断言与具名测试,使理解作为可执行期望而非记忆挺过下一次再生。
- 标记仍未被解释的区域,使空隙可见,而非被假定已关闭。
- 按节奏回访,因为每次再生都可能悄然重开你曾关闭的路径。
这一顺序之所以有效,是因为它把理解从私人状态转为耐久产物。只存在于一人头脑中的理解本身也是一种债务——人离开它就离开。写成测试的理解留下来,并在后续再生违背它本应保护的意图时大声失败。重点不是理解一切。而是精确知道什么仍未被理解。
瓶颈接下来移向何处
从这里开始变难的,正是使生成有价值的同一件事:与理解脱钩的速度。随着系统更多部分以写好的形式抵达,稀缺技能不再是生产,而是重建——站在无人亲写的代码前、足够快地重建推理以安全改动它的能力。
表现好的团队往往把理解当作自有维护成本的资产,与代码一并预算。他们不仅衡量交付了什么,也衡量仍能被解释什么。他们把解释测试通过率下降当作值得行动的信号,正如更早时代对待缺陷数上升。
理解空隙不会自行关闭,因为撑大它的力量正是团队赖以推进的力量。前方的工作是学会以那种速度前进,同时把意图与产物之间的距离保持得足够短,以便在关键时刻跨过。这个领域正慢慢发现:瓶颈从来不是写软件。它过去是、现在仍是:理解得足够好,才能无所畏惧地改动它。
F.A.Q.
