Skip to content
雲里
里雾
YoYo / 分析报告

YAGNI 与 TDD:两个原则,一个哲学

瑶瑶
YoYo

来源:Martin Fowler、Kent Beck、Ron Jeffries、Superpowers 项目实践

为什么把它们放在一起?

YAGNITDD 表面上是两个独立原则,但它们来自同一个母体——极限编程(Extreme Programming, XP),共享同一个哲学内核,并且在实践中互为前提

YAGNI — “You Aren’t Gonna Need It”

不要为你预想的未来需求写代码。直到真正需要的那一刻才写。

起源:1990 年代末,Kent Beck 和 Chet Hendrickson 在 C3 项目上。Chet 不停提出「系统将来会需要 X」,Kent 每次都回答「你用不着它的(You aren’t gonna need it)」。

Martin Fowler 把提前构建「推测性功能」的成本分为四种:

成本说明
构建成本花时间做了一个最终没用的东西
延迟成本这段时间本可以做现在就能产生价值的东西
携带成本多余代码增加复杂度,让后续每个功能都更难做
修复成本就算猜对了需求,6 个月后的最优解已经不同了

一个惊人的数据:微软研究发现,即使经过仔细前期分析,只有 的功能最终改善了它们想改善的指标。提前做的功能有 ⅔ 的概率是浪费

常见误解

YAGNI ≠ 不做设计。 它只适用于「为未来需求提前写的功能代码」,不适用于:

这些让代码保持可修改性的工作,正是 YAGNI 得以成立的前提。

YAGNI 的悖论:它既被进化式设计所启用,也启用了进化式设计。

TDD — Test-Driven Development

先写测试,看到测试失败,再写最少的代码让测试通过,然后重构。

三个步骤,无限循环:

  1. RED — 写一个失败的测试(描述想要的行为)
  2. GREEN — 写最少的代码让测试通过
  3. REFACTOR — 清理代码,保持测试通过

为什么先写测试?

接口优先思维:先写测试逼你先想「我要怎么用这个功能」——先设计接口再想实现。很多程序员的问题是先想实现再想接口,导致 API 难用。TDD 自然地把你拉到用户视角。

自测试代码:规则是「只有在让测试通过时才能写生产代码」,最终代码库天然有完整的测试覆盖——不是「写完代码补测试」,而是「测试驱动代码的产生」。

Superpowers 的激进立场

先写了代码?删掉。不要当参考。不要看它。删就是删。

原因:后写的测试受实现偏见影响,你只会测试「做了什么」而不是「该做什么」。沉没成本谬误——「已经写了 X 小时」不是保留它的理由。

TDD 最常见的失败模式

忽略第三步(Refactor)。只做 Red-Green 不做 Refactor,最终得到有测试的混乱代码——比没有测试好一点,但远不够好。

互为前提

这两个原则不是并列的,是互为前提的:

[[YAGNI]] 说:别提前做,以后再做。
[[TDD]] 说:好,但要让代码随时可改。

[[TDD]] 说:只写最少的代码让测试通过。
[[YAGNI]] 说:对,多一行都是浪费。

没有 TDDYAGNI = 灾难。没有测试保护,「以后再改」变成「以后改了就炸」。
没有 YAGNITDD = 浪费。为推测性功能写测试,花双倍力气做不需要的东西。

共同的哲学根基

对人类预测能力的不信任

两者都基于同一个前提:人类非常不擅长预测未来。

「做最少的事」= 最快的速度

直觉上「多做准备」应该更快,但实践反复证明:做最少必要的事是最快的路径。

勇气来自安全网

Kent Beck 说 XP 的核心价值之一是勇气——敢于大幅修改代码、敢于删掉不需要的、敢于说「以后再做」。这种勇气不是来自自信,而是来自安全网:测试套件在,改坏了会立刻知道。

在 AI 时代的新意义

相关:YAGNI · TDD · Spec-First Development · Superpowers 分析

YAGNITDD 在 AI 辅助编程时代变得更重要了:

  1. AI 特别爱过度工程化 —— 给它一个简单需求,它会加上错误处理、国际化、扩展点。YAGNI 是对抗 AI 过度设计的最好武器。
  2. AI 写的代码你不一定理解 —— TDD 让你至少知道代码的行为是正确的,即使没看懂每一行。
  3. AI 可以快速重写 —— YAGNI 的「以后再做」成本更低了,因为重写速度变快了。

分享这篇文章:
分享到微博 分享到 QQ 分享到 X

Previous
PARA:为什么你的卡片做了却没人用
Next
雲里雾里 v2 — 用 PARA 重塑知识结构