1. 一个具体问题
一个文件上传功能目前只使用一种存储服务,团队却提前开发四种存储适配器和复杂切换策略,理由是以后可能迁移。两个月后真正的需求变成离线导入,先前预留的扩展点没有派上用场,却仍要维护和修补。
2. 一句话解释
不要仅因为设想未来可能需要,就现在实现额外功能;用真实需求决定能力的加入时机。
3. 出处与原意
YAGNI 是 You Aren’t Gonna Need It 的缩写,与极限编程实践密切相关。Martin Fowler 的解释强调不要实现推测性的能力,同时指出它依赖持续重构和可演进设计。它不是反对思考未来,也不是放弃架构质量。
4. 原理与机制
提前实现功能有三类成本:当下开发成本、持续维护负担,以及让未来真正需求更难落地的复杂性。未来需求不确定时,等待还保留了利用新信息的价值。但等待有前提:系统应有基本测试、清晰边界和可修改性,否则“以后再做”可能变成无法承受的重写。区分能力建设和设计卫生很重要;修复难懂代码、补必要监测,不等于添加没人使用的功能。
推迟实现与留下记录可以同时进行。团队可以记录将来迁移时需要考虑的约束,却不必马上创建所有适配器与开关。若一次技术试验能低成本消除关键不确定性,它也可能值得提前做,因为目的在于获取信息,而不是交付推测功能。需要警惕的是试验代码无意进入长期维护路径;验证结束后应明确保留、删除或正式实现的决定。
5. 一个完整案例
假设案例:十人的研究团队要上传实验文件,目前只有一个存储提供方。开发者先用一个清楚的存储接口封装上传和下载,写好失败处理,不实现未用的四套后端。后来团队提出本地离线采集,新的需求要求断点续传和同步状态,远比原先设想的切换提供方复杂。因为核心代码仍可测试,团队按真实场景加入本地队列。先前没有做的适配器节省了时间,已有边界又避免了所有业务代码直接依赖供应商细节。
6. 适用条件与反例
适合需求变化快、功能价值尚未证实的产品开发。不可逆的数据格式、隐私与安全要求、已确定的容量约束需要提前考虑,不能拿 YAGNI 当作忽略它们的借口。对已经签订的交付要求,讨论的是实现顺序,而非是否存在需求。
7. 今天可以尝试的行动
审查待办中的“预留”“以后可能”“通用支持”,为每项找出实际用户和触发日期。没有依据的能力先删除或记为假设;同时保留使未来修改容易的测试与边界。下一轮再根据事实决定是否重新加入。