在 1970 年代,当软件开发刚刚成为一个系统性工程时,人们借鉴了传统制造业的管理方法。制造业的生产流程是线性的:设计蓝图 → 采购材料 → 加工零件 → 组装成品 → 质量检验。每个阶段完成后进入下一个阶段,不能回头。
软件开发就照着这个模型来了:需求分析 → 系统设计 → 编码实现 → 测试验证 → 部署维护。
这就是"瀑布模型"——最早由温斯顿·罗伊斯在 1970 年的一篇论文中描述。它的特点是一步接一步,像水从瀑布顶端流下来一样,不会倒流。罗伊斯在他的论文中其实已经指出了这个模型的局限性——他写道"这种分阶段的方式风险很大,尤其是当你在第二阶段发现第一阶段的假设是错的时候"——但后来的实践者大多忽略了这个警告,把它当成了一张"做软件的标准配方"。
你可以想象一个典型的瀑布项目是怎么运作的:一开始,产品经理花三个月写了一份几百页的需求文档,里面详细描述了每一个功能、每一条业务规则、每一种用户角色。文档评审通过了,进入设计阶段。架构师花两个月画了厚厚一沓 UML 图,定义了数据库的每一个表和字段、每一个 API 的入参和出参。设计评审通过了,进入开发阶段。十几个开发花了大半年时间把这些设计变成代码。开发完成后,测试团队花了两个月验证。最终,产品上线了——距离最初写下第一行需求文档已经过去了一年半。
用户打开这个产品,发现界面是两年前流行的风格,有些功能他们早就不用那个方式做了,有些当时说好的需求做了一半因为"需求变了"但项目已经来不及改。这就是瀑布模型的典型结局。
你可能觉得"一个项目做一年半"是极端的例子——实际上,在 1980 到 1990 年代,一个大型软件项目的典型周期就是 18 到 36 个月。有些大型政府或金融机构的软件项目,从启动到交付甚至需要 5 年以上。在这段时间里,市场环境、用户习惯、竞争对手都可能发生了翻天覆地的变化。
瀑布模型在用"造桥"的方式"造软件"。问题是:软件不是桥。
桥的需求是明确的——你要建一座连接 A 点和 B 点的桥,承载多少吨重量,用多少年。这些信息在开工前就能确定,而且不会在中途改变。即便有变化(比如地质条件不理想),也只是施工方案的调整,而不是功能定义的改变。
但软件的需求几乎总是在变化的。用户看到原型后说"不对,我其实要的不是这样",竞争对手发布了一个新功能需要跟上,市场环境变了需要调整策略……瀑布模型无法应对这些变化。因为一旦进入编码阶段,你就不可能回到需求阶段去修改——至少在瀑布模型中,这是不鼓励的。在瀑布模型的项目中,如果你已经进入了"编码"阶段,下面几个月到一年的计划都已经排好了,团队已经根据原计划分配了任务。这时候你说"需求变了",意味着要重新走变更控制流程,重新评审,重新安排排期——整个项目可能因此延期数月。
结果就是:大量项目在几个月甚至几年后,交付了一个"按需求文档实现"的产品,但用户已经不需要它了。
有一个广为人知的数据:美国国防部的软件项目研究(Standish Group CHAOS Report)显示,1990 年代只有大约 16% 的软件项目按时按预算成功完成,超过 30% 的项目被彻底取消。那些被取消的项目,绝大多数不是因为技术上做不到,而是因为做到一半发现当初的需求已经没有意义了。
除了流程本身的问题,瀑布模型还制造了一种心理上的副作用:对变化的恐惧。
在瀑布模型中,变更意味着麻烦。变更意味着你要重新走审批流程、重新发布版本、重新协调团队。所以整个项目文化都在鼓励"一次做对",而不是"快速试错"。
这种文化对一个刚入行的开发者产生了深远的影响:你不敢问"为什么"——因为问了可能发现需求有问题,但修改需求太麻烦了,还不如照着文档做。你不敢说"我觉得这样更好"——因为你的建议意味着重新设计,而重新设计的成本太高了。你慢慢变成了一个"执行者"而不是一个"创造者"。
这种文化积累了几十年,变成了一套根深蒂固的行业惯性。即使到了敏捷和 Vibe Coding 的时代,很多开发者的第一反应仍然是"先把需求搞清楚再动手"——而不是"先做个粗糙的版本,跑起来再说"。这个心理习惯的改变,比工具的改变要难得多。
为了让瀑布模型的"为什么不适用"更加清晰,我把软件和物理产品的三个核心区别列出来:
区别一:软件是"可无限修改"的。 一座桥造好了,你不能把它拆了重建一段——成本是不可接受的。但软件改一个功能模块,理论上不需要重建整个系统。瀑布模型把软件当成了物理产品——一旦"浇注"就不能回头。但实际上,软件的美妙之处正在于它可以被反复修改,而且修改的成本远低于重新构建。
区别二:软件的使用方式在使用过程中才会被发现。 没有人会在住进一栋楼之前就发现"这个窗户的开关方向不对"——因为窗户的开关方向在图纸上就能确定。但一个有几十万用户的软件应用,你在发布之前永远不可能确切知道用户会在什么场景下使用它。有些你以为是"边缘功能"的模块被用户玩出了花,有些你花了大量精力的核心功能用户根本不碰。
区别三:软件的价值在于使用中,而不在于交付时。 一座桥的价值在它通车的瞬间就确定了。一个软件的价值在它被使用的那一刻才开始,而且会随着用户的反馈和产品的迭代不断提升。瀑布模型把"上线"当作终点,但实际上,"上线"只是软件生命周期的起点。
瀑布模型最大的价值不是它"成功过"——事实上它很少成功——而是它教会了后来的开发者一个重要的教训:在软件中,变化的成本是递减的,不是递增的。
在制造业中,你在设计阶段改一个零件的尺寸可能只需要几个小时,但到了产线上改可能就是几天甚至几周。软件恰好相反:一个功能在你写代码之前改它,成本几乎为零;在代码写完之后改,成本稍高但在可接受范围;在产品上线之后改,可能需要迁移数据、处理兼容性、通知用户——成本反而更高。
这个"变化成本递减"的特性,是所有现代软件开发方法论的基础前提。因为变化在早期是便宜的,所以你应该在早期多变化——多试、多问、多验证。不要等到把需求文档写到 100 页才开始做——做一个粗糙的原型给用户看,几分钟就知道方向对不对。
所以后来所有的软件工程方法论——敏捷、DevOps——本质上都在做同一件事:缩短反馈循环,让变化在成本最低的阶段发生。 这个思路会一直延续到 Vibe Coding 中。
从 Vibe Coding 的角度看瀑布模型,你会发现一个讽刺的事实:瀑布模型的核心假设——"需求可以在开始前完全确定"——恰好是 Vibe Coding 最不需要的东西。Vibe Coding 不需要你一开始就想清楚所有需求,它鼓励你先说个大概,看结果,再调整。瀑布模型禁止你在一半改变主意,Vibe Coding 把"改变主意"当成了工作流程的核心环节。
所以瀑布模型不仅仅是"过时了"——它是 Vibe Coding 在哲学层面上的反面。理解瀑布模型为什么失败,就是理解 Vibe Coding 为什么有效。
问 AI:
"用瀑布模型来做软件开发和用 Vibe Coding 来做,最核心的三个区别是什么?请用具体的场景解释,不要讲抽象概念。"
在得到回答后,追问一个具体场景:
"如果我正在用瀑布模型做一个电商 App,做到一半发现用户更喜欢抖音式的短视频购物而不是搜索式购物,我会怎么办?如果用 Vibe Coding,我会怎么办?"