YAGNI
YAGNI 是软件开发中的一个经典原则,全称:
You Aren’t Gonna Need It
(你不会需要它的)
它源于 Extreme Programming(极限编程,XP)。
核心思想:
不要为未来可能发生的需求提前编写代码,只实现当前真正需要的功能。
一个典型例子
假设你要开发一个博客系统。
当前需求:
- 发表文章
- 编辑文章
- 删除文章
有些开发者会想:
将来可能支持:
- 多租户
- 多语言
- 插件系统
- 分布式部署
- 工作流审批
于是提前设计:
Content
├── BlogArticle
├── NewsArticle
├── ProductArticle
└── ...
再加各种抽象工厂、策略模式、插件机制。
结果:
- 代码复杂
- 开发变慢
- 大部分功能永远没用上
YAGNI 的做法:
class Article {
String title;
String content;
}
先把博客做好。
等真的出现「新闻文章」需求时,再重构。
YAGNI 不等于不设计
很多人误解:
YAGNI = 不考虑未来
实际上不是。
YAGNI 的意思是:
可以预留扩展点
例如:
interface Storage {
void save(File file);
}
这是合理抽象。
因为当前就存在:
- 本地存储
- OSS存储
两种实现。
不要为猜测的需求设计
例如:
interface StorageFactory {
Storage createStorage(
StorageType type,
Region region,
Tenant tenant,
...
);
}
实际上项目只有:
LocalStorage
这种抽象就是过度设计。
YAGNI 与 KISS 的区别
KISS
Keep It Simple, Stupid
保持简单。
关注:
解决方案不要复杂。
YAGNI
You Aren’t Gonna Need It
不要做未来需求。
关注:
不要实现暂时不需要的东西。
例如:
当前只需要导出 CSV。
KISS:
exportCsv()
不用设计复杂框架。
YAGNI:
不要提前实现:
exportPdf()
exportExcel()
exportWord()
因为用户还没要。
YAGNI 与 DRY 的冲突
另一个经典原则:
DRY(Don’t Repeat Yourself)
不要重复。
有时会与 YAGNI 冲突。
例如:
第一次出现:
formatUserName()
第二次出现:
formatOrderName()
很多人立即抽象:
formatName()
但实际上:
- 两个业务未来会分化
- 抽象反而增加复杂度
YAGNI 会建议:
先允许少量重复。
通常经验是:
Rule of Three(三次法则)
代码出现三次以上再考虑抽象。
在前端开发中的体现
不要提前封装组件
需求:
<Button />
出现一次。
不要立刻设计:
<BaseButton />
<PrimaryButton />
<SecondaryButton />
<DangerButton />
等多个页面真正需要时再抽象。
不要提前微前端
项目:
- 3 个页面
- 2 个开发者
不要因为未来可能扩展而上:
- 微前端
- Service Mesh
- 分布式架构
先用简单方案。
一句话理解
YAGNI 的本质是:
把复杂度推迟到真正需要的时候再引入。
很多项目的问题不是功能太少,而是:
为了未来可能发生的需求,提前写了大量永远不会被使用的代码。
遵循 YAGNI 通常能让代码库更小、更容易维护,也能避免“过度工程化”。
关联阅读:设计总纲见 design,SOLID / DRY / ETC 与本篇 YAGNI / KISS 互为补充。