
软件开发模型系列(四):迭代开发 ------ 先让东西跑起来,再慢慢变好
前面三种模型(瀑布、V 模型、螺旋)有一个共同假设:项目有明确的起点和终点。但互联网时代来了------软件上线不是结束,而是开始。迭代开发改变了这个基本假设。

1、什么是迭代开发
迭代开发(Iterative Development) 的核心思想很简单:不要试图一次做对所有事情。先做一个能跑的简陋版本,然后通过一轮又一轮的反馈和改进,逐步逼近最终目标。
#mermaid-svg-3cZpBPJdHMhVZ6tk{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3cZpBPJdHMhVZ6tk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3cZpBPJdHMhVZ6tk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3cZpBPJdHMhVZ6tk .error-icon{fill:#552222;}#mermaid-svg-3cZpBPJdHMhVZ6tk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3cZpBPJdHMhVZ6tk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3cZpBPJdHMhVZ6tk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3cZpBPJdHMhVZ6tk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3cZpBPJdHMhVZ6tk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3cZpBPJdHMhVZ6tk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3cZpBPJdHMhVZ6tk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3cZpBPJdHMhVZ6tk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3cZpBPJdHMhVZ6tk .marker.cross{stroke:#333333;}#mermaid-svg-3cZpBPJdHMhVZ6tk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3cZpBPJdHMhVZ6tk p{margin:0;}#mermaid-svg-3cZpBPJdHMhVZ6tk .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3cZpBPJdHMhVZ6tk .cluster-label text{fill:#333;}#mermaid-svg-3cZpBPJdHMhVZ6tk .cluster-label span{color:#333;}#mermaid-svg-3cZpBPJdHMhVZ6tk .cluster-label span p{background-color:transparent;}#mermaid-svg-3cZpBPJdHMhVZ6tk .label text,#mermaid-svg-3cZpBPJdHMhVZ6tk span{fill:#333;color:#333;}#mermaid-svg-3cZpBPJdHMhVZ6tk .node rect,#mermaid-svg-3cZpBPJdHMhVZ6tk .node circle,#mermaid-svg-3cZpBPJdHMhVZ6tk .node ellipse,#mermaid-svg-3cZpBPJdHMhVZ6tk .node polygon,#mermaid-svg-3cZpBPJdHMhVZ6tk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3cZpBPJdHMhVZ6tk .rough-node .label text,#mermaid-svg-3cZpBPJdHMhVZ6tk .node .label text,#mermaid-svg-3cZpBPJdHMhVZ6tk .image-shape .label,#mermaid-svg-3cZpBPJdHMhVZ6tk .icon-shape .label{text-anchor:middle;}#mermaid-svg-3cZpBPJdHMhVZ6tk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3cZpBPJdHMhVZ6tk .rough-node .label,#mermaid-svg-3cZpBPJdHMhVZ6tk .node .label,#mermaid-svg-3cZpBPJdHMhVZ6tk .image-shape .label,#mermaid-svg-3cZpBPJdHMhVZ6tk .icon-shape .label{text-align:center;}#mermaid-svg-3cZpBPJdHMhVZ6tk .node.clickable{cursor:pointer;}#mermaid-svg-3cZpBPJdHMhVZ6tk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3cZpBPJdHMhVZ6tk .arrowheadPath{fill:#333333;}#mermaid-svg-3cZpBPJdHMhVZ6tk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3cZpBPJdHMhVZ6tk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3cZpBPJdHMhVZ6tk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3cZpBPJdHMhVZ6tk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3cZpBPJdHMhVZ6tk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3cZpBPJdHMhVZ6tk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3cZpBPJdHMhVZ6tk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3cZpBPJdHMhVZ6tk .cluster text{fill:#333;}#mermaid-svg-3cZpBPJdHMhVZ6tk .cluster span{color:#333;}#mermaid-svg-3cZpBPJdHMhVZ6tk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3cZpBPJdHMhVZ6tk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3cZpBPJdHMhVZ6tk rect.text{fill:none;stroke-width:0;}#mermaid-svg-3cZpBPJdHMhVZ6tk .icon-shape,#mermaid-svg-3cZpBPJdHMhVZ6tk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3cZpBPJdHMhVZ6tk .icon-shape p,#mermaid-svg-3cZpBPJdHMhVZ6tk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3cZpBPJdHMhVZ6tk .icon-shape .label rect,#mermaid-svg-3cZpBPJdHMhVZ6tk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3cZpBPJdHMhVZ6tk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3cZpBPJdHMhVZ6tk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3cZpBPJdHMhVZ6tk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-3cZpBPJdHMhVZ6tk .stage>*{fill:#dbeafe!important;stroke:#2563eb!important;stroke-width:1px!important;color:#1e3a8a!important;}#mermaid-svg-3cZpBPJdHMhVZ6tk .stage span{fill:#dbeafe!important;stroke:#2563eb!important;stroke-width:1px!important;color:#1e3a8a!important;}#mermaid-svg-3cZpBPJdHMhVZ6tk .stage tspan{fill:#1e3a8a!important;} 基于上一轮反馈
基于上一轮反馈
第 3 轮 · V2.0
需求分析
设计
编码
测试
交付/反馈
第 2 轮 · V1.1
需求分析
设计
编码
测试
交付/反馈
第 1 轮 · V1.0
需求分析
设计
编码
测试
交付/反馈
和瀑布模式的关键区别:
text
瀑布:一次交付整个系统,中间没有用户反馈
迭代:每次交付一个可运行的版本,不断根据反馈调整方向
2、迭代开发的历史:比你想象的早得多

很多人以为迭代开发是 2000 年代敏捷运动之后才出现的新东西。但事实上,迭代开发的实践比瀑布模型更早。
| 时间 | 事件 |
|---|---|
| 1930s | Walter Shewhart(贝尔实验室)提出统计过程控制和持续改进循环的概念(后被 Deming 发展为 PDCA/PDSA 循环) |
| 1950s | W. Edwards Deming 将 Shewhart 的循环推广到日本工业界,深刻影响了丰田生产系统 |
| 1960s | NASA 的水星计划(Project Mercury)使用迭代开发 |
| 1971 | IBM 的 Harlan Mills 提出"软件应该通过增量开发来成长" |
| 1977-80 | IBM 团队用 17 轮迭代(每轮约 8 周)开发了航天飞机的主飞行控制软件 |
| 1986 / 1995 | Frederick Brooks 在《没有银弹》(1986)中主张"软件应增量式地生长(grow, don't build)";1995 年在《人月神话》20 周年纪念版中更直接宣称"瀑布模型是错的" |
| 1990s | Rational Unified Process(RUP)将迭代开发系统化、商业化 |
历史的有趣之处:迭代开发不是"发明出来替代瀑布的",它一直就存在。瀑布模型在 1970-1990 年代的大规模流行,反而是一段历史上的弯路------很大程度上要归因于美国国防部 DOD-STD-2167 标准对 Royce 论文的误读。
3、迭代 vs 增量:一个重要区分

这两个词经常被混用(包括在很多教材中),但它们指向的是两个不同的维度:
| 维度 | 迭代(Iterative) | 增量(Incremental) |
|---|---|---|
| 关注点 | 时间维度:重复同一个过程 | 产品维度:叠加新的功能 |
| 工作方式 | 同一个功能反复打磨、改进 | 每次增加一个完整的新功能块 |
| 比喻 | 画家画一幅肖像,先画轮廓,再逐步细化 | 盖房子一间一间盖,每间盖好就是成品 |
| 核心问题 | "我们做对了吗?"(学习与修正) | "接下来交付什么?"(功能分解) |
在实际项目中,两者往往是结合的:
text
微信的发展:
迭代的维度 → 聊天功能从文字→语音→视频,不断打磨
增量的维度 → 先有聊天,再加朋友圈,再加支付,再加小程序
现代 Scrum 框架(详见本系列第六篇)实际上同时包含了这两个维度:每个 Sprint 是一个迭代 (重复相同的仪式和周期),而每个 Sprint 结束时交付的是一个增量(可用的产品功能切片)。
4、迭代开发的核心优势

4.1、风险前置,而不是后置
text
瀑布: 迭代:
需求 设计 编码 测试 V1: 需求→设计→编码→测试→反馈
↓
最大的风险在最后 V2: 需求→设计→编码→测试→反馈
才发现 ↓
V3: ...
最大的技术风险和需求理解风险在 V1 就被发现了
4.2、用户可以尽早看到产品
这带来的好处远超"让用户开心":
- 用户可以在看到实际产品后给出更准确的反馈(而不是对着需求文档凭空想象)
- 错误的产品方向在投入还不多的时候就会被纠正
- 用户可以边用边学,需求质量逐轮提高
4.3、团队可以在过程中学习
text
第一轮:大家还在磨合,代码质量一般
第二轮:对业务更理解了,架构可以调整
第三轮:找到了最佳实践,效率大幅提升
瀑布模型的一次性开发剥夺了团队这种学习机会。
5、迭代开发的挑战

5.1、架构容易退化
如果每一轮只关注"这轮要交付的功能",很容易出现:
#mermaid-svg-aHooLrFGvImfWx9z{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-aHooLrFGvImfWx9z .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-aHooLrFGvImfWx9z .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-aHooLrFGvImfWx9z .error-icon{fill:#552222;}#mermaid-svg-aHooLrFGvImfWx9z .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aHooLrFGvImfWx9z .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-aHooLrFGvImfWx9z .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aHooLrFGvImfWx9z .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aHooLrFGvImfWx9z .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-aHooLrFGvImfWx9z .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aHooLrFGvImfWx9z .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aHooLrFGvImfWx9z .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aHooLrFGvImfWx9z .marker.cross{stroke:#333333;}#mermaid-svg-aHooLrFGvImfWx9z svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aHooLrFGvImfWx9z p{margin:0;}#mermaid-svg-aHooLrFGvImfWx9z .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-aHooLrFGvImfWx9z .cluster-label text{fill:#333;}#mermaid-svg-aHooLrFGvImfWx9z .cluster-label span{color:#333;}#mermaid-svg-aHooLrFGvImfWx9z .cluster-label span p{background-color:transparent;}#mermaid-svg-aHooLrFGvImfWx9z .label text,#mermaid-svg-aHooLrFGvImfWx9z span{fill:#333;color:#333;}#mermaid-svg-aHooLrFGvImfWx9z .node rect,#mermaid-svg-aHooLrFGvImfWx9z .node circle,#mermaid-svg-aHooLrFGvImfWx9z .node ellipse,#mermaid-svg-aHooLrFGvImfWx9z .node polygon,#mermaid-svg-aHooLrFGvImfWx9z .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aHooLrFGvImfWx9z .rough-node .label text,#mermaid-svg-aHooLrFGvImfWx9z .node .label text,#mermaid-svg-aHooLrFGvImfWx9z .image-shape .label,#mermaid-svg-aHooLrFGvImfWx9z .icon-shape .label{text-anchor:middle;}#mermaid-svg-aHooLrFGvImfWx9z .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-aHooLrFGvImfWx9z .rough-node .label,#mermaid-svg-aHooLrFGvImfWx9z .node .label,#mermaid-svg-aHooLrFGvImfWx9z .image-shape .label,#mermaid-svg-aHooLrFGvImfWx9z .icon-shape .label{text-align:center;}#mermaid-svg-aHooLrFGvImfWx9z .node.clickable{cursor:pointer;}#mermaid-svg-aHooLrFGvImfWx9z .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-aHooLrFGvImfWx9z .arrowheadPath{fill:#333333;}#mermaid-svg-aHooLrFGvImfWx9z .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-aHooLrFGvImfWx9z .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-aHooLrFGvImfWx9z .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aHooLrFGvImfWx9z .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-aHooLrFGvImfWx9z .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aHooLrFGvImfWx9z .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-aHooLrFGvImfWx9z .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-aHooLrFGvImfWx9z .cluster text{fill:#333;}#mermaid-svg-aHooLrFGvImfWx9z .cluster span{color:#333;}#mermaid-svg-aHooLrFGvImfWx9z div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-aHooLrFGvImfWx9z .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-aHooLrFGvImfWx9z rect.text{fill:none;stroke-width:0;}#mermaid-svg-aHooLrFGvImfWx9z .icon-shape,#mermaid-svg-aHooLrFGvImfWx9z .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aHooLrFGvImfWx9z .icon-shape p,#mermaid-svg-aHooLrFGvImfWx9z .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-aHooLrFGvImfWx9z .icon-shape .label rect,#mermaid-svg-aHooLrFGvImfWx9z .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aHooLrFGvImfWx9z .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-aHooLrFGvImfWx9z .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-aHooLrFGvImfWx9z :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-aHooLrFGvImfWx9z .stage>*{fill:#dbeafe!important;stroke:#2563eb!important;stroke-width:1px!important;color:#1e3a8a!important;}#mermaid-svg-aHooLrFGvImfWx9z .stage span{fill:#dbeafe!important;stroke:#2563eb!important;stroke-width:1px!important;color:#1e3a8a!important;}#mermaid-svg-aHooLrFGvImfWx9z .stage tspan{fill:#1e3a8a!important;}#mermaid-svg-aHooLrFGvImfWx9z .pain>*{fill:#fee2e2!important;stroke:#dc2626!important;stroke-width:1px!important;color:#7f1d1d!important;}#mermaid-svg-aHooLrFGvImfWx9z .pain span{fill:#fee2e2!important;stroke:#dc2626!important;stroke-width:1px!important;color:#7f1d1d!important;}#mermaid-svg-aHooLrFGvImfWx9z .pain tspan{fill:#7f1d1d!important;} 第 1 轮:快速上线,架构随意 → 能跑
第 2 轮:加新功能,打补丁 → 还能跑
第 3 轮:再加功能,更多补丁 → 勉强能跑
第 4 轮:架构崩溃,需要重写 → 跑不动了
这就是"技术债"的积累。迭代开发需要比瀑布模型更强的架构自律------每次迭代都花时间重构和还技术债。
5.2、对用户的时间和参与度要求更高
迭代模式需要用户持续参与每个版本的反馈。如果用户组织"太忙了,下一版再看",反馈循环就会断裂,迭代开发的核心优势就丧失了。
6、迭代开发 vs 瀑布模型:一个具体对比

假设开发一个电商 APP,预计要 6 个月:
text
瀑布模式:
月1-2:需求分析(产出 200 页 PRD)
月3-4:系统设计
月5:编码
月6:测试 + 上线
→ 用户在第 6 个月才第一次看到 APP
迭代模式:
月1-2:第1轮(注册登录 + 商品浏览)→ 用户试用
月3-4:第2轮(搜索 + 购物车 + 下单)→ 用户试用
月5:第3轮(支付 + 订单管理)→ 用户试用
月6:第4轮(评价 + 推荐 + 优化)→ 正式上线
→ 用户在第一个月就能看到可运行的 APP
如果用户在第 2 轮反馈"搜索体验太差了,我们需要全文搜索而不是简单的关键词匹配"------在迭代模式下,第 3 轮就可以调整。在瀑布模式下,等你听到这个反馈,所有代码都写完了。
7、本篇要点速记
text
迭代开发 = 分轮交付 + 持续反馈 + 逐步完善
历史比瀑布模型更久远(NASA 1960s 就在用)。
关键区分:迭代(反复打磨)vs 增量(逐块叠加)
优点 → 风险前置、用户早参与、团队可学习
局限 → 架构退化、需要用户持续参与
一句话:不要一次把东西做好,要先把东西做出来,再把它做好。
8、迭代开发模型 vs 螺旋模型

迭代模型关注的是"产品如何成长",螺旋模型关注的是"风险如何降低"。
Iterative Development 的第一性原理:没有人第一次就能把产品做好。
产品质量不断逼近目标。迭代开发 = Continuous Improvement(持续改进)
螺旋模型第一性原理
螺旋模型认为第一性原理:真正的问题不是怎么开发?而是我根本不知道这个项目有没有坑。
每绕一圈风险越来越少。不是功能越来越多。而是未知越来越少。
关键词:Risk Reduction(风险降低)
螺旋包含了迭代,螺旋把"风险分析"放到了每一次迭代最前面。把最大的坑先踩出来。
text
软件开发
│
┌───────────┴───────────┐
│ │
Product Growth Risk Control
(产品成长) (风险控制)
│ │
▼ ▼
Iterative Development Spiral Model
螺旋模型 = 风险驱动的迭代开发(Risk-Driven Iterative Development)

两者看起来都在"一轮一轮地做事",但驱动力完全不同:迭代开发以"产品演进"为中心,螺旋模型以"风险演进"为中心。
也正因为如此,可以把螺旋模型理解为一种以风险管理为核心的迭代开发方法------它保留了迭代的形式,但重新定义了每一轮迭代最优先要解决的问题。

上一篇:螺旋模型
下一篇:敏捷开发 ------ 从"按计划行事"到"拥抱变化"