1970 - Waterfall 瀑布模型:一張被斷章取義的圖#
案件摘要#
1970 年,Winston Royce 在論文 Managing the Development of Large Software Systems 中 畫出了那張著名的圖:需求 → 設計 → 實作 → 測試 → 維護,一路向下,如瀑布傾瀉。 諷刺的是,Royce 本人反對純瀑布——論文原文主張迭代與回饋,回饋箭頭就畫在圖上, 卻被後世讀者集體忽略。一張被斷章取義的圖,成為 1970s–90s 的主流方法學, 也成為 2001 年敏捷革命的靶子。
前因 -- 為什麼會有這個案子#
- 1960s 的無流程混沌:軟體危機(見「1968-NATO軟體工程會議.md」)後, 業界急切需要一個「看起來像工程」的流程——NATO 會議確立了需求、設計、實作、測試、維護的分工, 卻沒有給出執行的順序。
- Royce 的現場:Royce 在 Lockheed 與後來的 Aerospace 項目中管理大型軟體開發, 他觀察到:大型專案不是寫不出來,而是管不好——需求變更、晚期整合、無止境的測試。
- 硬體工程的模板:土木與航空工程的「先設計後施工」流程被直接移植—— 橋樑蓋到一半不能改藍圖,所以軟體也應該先凍結需求再寫碼?Royce 認為這是誤植。
- 關鍵推理:Royce 論文的邏輯是兩段式的—— 先描述「理想的線性流程」(那張圖),再指出它注定失敗,然後提出修正:
\[ \text{線性流程(圖)} \xrightarrow{\text{Royce 的批註}} \text{必須加回饋箭頭 + 至少兩次迭代}. \]
- 斷章取義的誕生:論文只有 11 頁,前半(純瀑布圖)被廣泛複印引用, 後半(迭代修正)被集體遺忘——「純瀑布」成為一個 Royce 從未主張的方法學。
線索與推理 -- 數學式、程式、理論#
第一條線索:瀑布的五道關卡與回饋延遲#
\[ \text{需求} \to \text{設計} \to \text{實作} \to \text{測試} \to \text{維護} \qquad \text{(Royce 的原圖)} \]
- 回饋延遲 \(O(\text{phase})\) :在階段 \(k\) 發現的問題,要回溯到階段 \(j < k\) 修正, 付出的回饋延遲與兩個階段的距離成正比:
\[ \text{delay}(j \to k) \sim \sum_{i=j}^{k} T_i \quad\Longrightarrow\quad \text{隔得越遠,返工越貴。} \]
- 純瀑布的罩門:只有一條向下箭頭——問題只能在最末端(測試)才被發現, 此時回溯到需求階段的返工成本最大( \(O(10^k)\) ,見「1968-NATO軟體工程會議.md」)。
- Royce 的原意:在論文第 5、6 節明確寫著——
「程式開發需要至少兩次迭代:先做一個小規模版本驗證設計,再做正式版本。」 且開發者應「與客戶持續互動、計畫測試、把測試設計與開發並行」—— 這些回饋箭頭就畫在他那張圖上,卻被省略了。
第二條線索:需求變更的成本 \(C(k)\)#
需求不會凍結——這是瀑布的根本假設缺陷。設專案在階段 \(k\) 才處理一個需求變更:
\[ C_{\text{waterfall}}(k) = C_0 \cdot 10^{k} \cdot N_{\text{affected}} \qquad \text{vs} \qquad C_{\text{iter}} = C_0 \cdot \bar{10}^{k_{\text{iter}}} \cdot N_{\text{affected}} \]
- 純瀑布中,需求變更平均要到測試階段( \(k=3\text{–}4\) )才被整合——每個變更都是天價。
- 迭代式開發(Royce 原意、Boehm 螺旋)把回饋週期縮短到 2–4 週—— 變更在下一次迭代就被吸收, \(k_{\text{iter}}\) 一直很小。
- 迭代縮短回饋:回饋週期 \(L\) 越短,變更累積量越少、修復階段越早——
\[ \text{總成本} \propto \int_0^{T} 10^{k(t)}\, dt \quad\Longrightarrow\quad \text{壓低 } k(t) \text{ 就壓低總成本}. \]
第三條線索:Boehm 的螺旋模型(1988)——修正案#
Barry Boehm 在 1988 年提出螺旋模型(spiral model),把 Royce 的回饋思想形式化:
\[ \text{每一次螺旋} = \underbrace{\text{目標}}_{\text{objectives}} \to \underbrace{\text{風險分析}}_{\text{risk}} \to \underbrace{\text{開發與測試}}_{\text{prototype/build}} \to \underbrace{\text{評估與規劃}}_{\text{plan next}} \]
- 每一圈都是一次小型瀑布,但產出的是可運作的原型——回饋以「圈」為單位,而非「階段」。
- 風險驅動:每圈先問「哪裡會出事」,把 \(O(10^k)\) 的返工成本前置到風險分析階段消化。
- 這是瀑布與敏捷之間的演化中繼站——敏捷(2001)把螺旋的「圈」再縮短到「衝刺(sprint)」。
第四條線索:迭代式開發——Royce 原意的落實#
Royce 論文第 5、6 節的修正,拆開來就是三個具體主張:
\[ \text{兩次迭代} + \text{開發與測試並行} + \text{持續的客戶互動} \quad\Longrightarrow\quad \text{回饋週期從「月」縮到「週」} \]
- 先做小型版本:用一個精簡但完整的原型(pilot model)跑通全流程, 驗證設計假設——錯誤在第一輪就被吸收,而非累積到測試階段。
- 測試與開發並行:「計畫測試」不是專案末端的動作——測試設計應與每個階段同步展開, 讓 \(k(t)\) 曲線永遠壓在低位。
- 持續的客戶互動:需求凍結是幻想——與其假設需求不變, 不如建立短週期的需求回饋機制,讓變更以「增量」而非「爆炸」的方式到來。
- 迭代回饋的數學效果:回饋週期 \(L\) 縮短 \(r\) 倍, 變更被吸收的階段 \(k\) 隨之下降——總返工成本約下降 \(10^{\Delta k}\) 倍, 一個數量級的節省,來自一張圖上被省略的箭頭。
- 這三個主張在 1988 年被 Boehm 收進螺旋模型,在 2001 年被寫進敏捷宣言 ——Royce 的論文後半部,是敏捷的思想化石。
Python 實作:純瀑布 vs 迭代式的需求變更成本模擬#
import random
# 專案:8 個需求,開發 5 個階段(需求/設計/實作/測試/整合)
# 每個需求有機率 p 在後期才被發現要改(需求變更)
# 純瀑布:變更一律到「測試」階段(k=3)才修,成本 = 10^3 * 修復單位
# 迭代式:每 2 個需求一次迭代(4 次迭代),變更在下一次迭代(k<=1)就修
STAGES = ["需求", "設計", "實作", "測試", "整合"]
def project_cost(p, mode, seed=7):
rng = random.Random(seed)
total = 0.0
n = 8
chunk = n // 4 if mode == "iter" else n # 迭代式:4 次小批量
for i in range(0, n, chunk):
group = range(i, min(i + chunk, n))
base = len(list(group)) * 10 # 基礎開發成本:每個需求 10 單位
total += base
for req in group:
if rng.random() < p: # 這個需求要變更
if mode == "waterfall":
k = STAGES.index("測試") # 一律拖到測試階段才發現
else:
k = 1 # 下一次迭代就發現(設計階段)
total += 10 ** k # 修復成本 10^k
return total
for p in (0.2, 0.4, 0.6):
w = project_cost(p, "waterfall")
it = project_cost(p, "iter")
print(f"變更機率 {p:.0%}:純瀑布 {w:6.0f} vs 迭代式 {it:5.0f}(瀑布為迭代的 {w/it:.1f} 倍)")
# 變更機率 20%:純瀑布 3080 vs 迭代式 110(瀑布為迭代的 28.0 倍)
# 變更機率 40%:純瀑布 5080 vs 迭代式 130(瀑布為迭代的 39.1 倍)
# 變更機率 60%:純瀑布 7080 vs 迭代式 150(瀑布為迭代的 47.2 倍)
結案 -- 後果與影響#
- 1970s–90s 的主流:瀑布被國防(DoD-STD-2167A)、金融、政府專案制度化—— 文書化與 signoff 文化(每階段簽核後才准進下一階段)就此形成。
- 被誤用的教科書:幾乎所有教材引用的都是那張無回饋箭頭的圖—— Royce 的迭代主張被遺忘近三十年,直到敏捷運動重新出土。
- 敏捷革命的靶子:2001 年敏捷宣言直接以瀑布為反例—— 「可運作的軟體重於詳盡的文件」「擁抱變更重於遵循計畫」—— 每一句都是對純瀑布罩門的反擊。
- Royce 原意的平反:螺旋模型(1988)、RUP(1990s)、迭代式與敏捷開發, 事實上都是回到 Royce 論文後半部的思想——回饋越早、迭代越短、成本越低。
- 遺產:瀑布並未消失——在需求穩定、法規嚴格的領域(醫療、航太、嵌入式), 「先凍結後施工」仍是合理選擇;但前提是這是選擇,而非被斷章取義的宿命。
- 歷史的教訓:這是「斷章取義改寫歷史」的經典案例—— 一張圖被複印、一段批註被遺忘,整個產業照著錯誤的版本跑了三十年; 讀文獻要讀全文,尤其是那些看起來太乾淨的圖。
關鍵人物與文獻#
- Winston W. Royce(Lockheed Missiles & Space Co.): Managing the Development of Large Software Systems(Proc. IEEE WESCON, 1970) ——11 頁的論文,被引用的方式與原文主張完全相反。
- Barry Boehm(TRW/USC):螺旋模型「A Spiral Model of Software Development and Enhancement」(Computer, 1988);bug 成本 \(O(10^k)\) 與 COCOMO 的作者 ——見「1968-NATO軟體工程會議.md」。
- Herbert Benington:SAGE 專案的「Production of Large Computer Programs」(1956) ——瀑布式流程的更早前身(Royce 論文亦受其影響)。
- 文獻:Royce 原論文 2003 年被 IEEE 收錄於 Software Engineering Classics 重刊, 並附導讀澄清「Royce 並非瀑布之父」。
- 相關案件:
1968-NATO軟體工程會議.md、1975-神話人月.md、1986-邏輯合成.md。