軟體專案為何失敗#

本章是整本書的核心篇章。Brooks 開宗明義地指出:

軟體專案出問題,因排程不當而失敗的比例,遠高於其他所有原因的總和。

為什麼排程如此困難?Brooks 認為有五個根本原因:樂觀主義、人月的謬誤、缺乏勇氣的估算、系統測試的低估、以及在專案落後時錯誤地增加人力。

所有程式設計師都是樂觀主義者#

Brooks 觀察到,程式設計師有一種根深蒂固的樂觀傾向:「這次一定沒問題」、「那個 bug 應該是最後一個了」、「只剩一點點就完成了」。

這種樂觀主義的根源在於程式設計的媒介本身——我們操作的是思想,思想看起來如此簡單而可塑,讓我們忽略了將思想正確實現的困難。每一段程式碼都可能隱藏著錯誤的假設,而我們的樂觀天性使我們系統性地低估了困難度

樂觀主義不是個人缺陷,而是整個行業的系統性偏差。排程時必須有意識地對抗這種傾向。

人月的謬誤#

人月(Man-Month) 作為衡量工作量的單位,是一個危險的神話。它暗示著:如果一個人需要 12 個月完成一項工作,那麼 12 個人可以在 1 個月內完成。人力與時間只有在任務可以完全分割、且參與者之間不需要任何溝通的情況下才能互換——而軟體開發幾乎不可能滿足這個條件。

Brooks 分析了三種不同類型的任務:

可完全分割的任務#

例如收割小麥——人力與時間確實可以互換。增加一倍的人手,就能在一半的時間內完成。

不可分割的任務#

例如懷孕——無論投入多少人力,一個嬰兒都需要九個月。九個女人無法在一個月內生出一個嬰兒。軟體開發中有大量這類具有順序依賴性的工作。

需要溝通的可分割任務#

加入溝通成本後,人力增加的效益會急遽遞減。如果 n 個人需要兩兩溝通,溝通管道數為 n(n-1)/2。除了溝通之外,每位新成員還需要訓練成本(training cost)。

溝通成本隨團隊規模呈二次方成長。一個 50 人的團隊需要 1,225 條溝通管道。這就是為什麼增加人手不一定能加速專案——超過某個臨界點後,增加的溝通負擔會完全吞噬新增的產能。

時程分配經驗法則#

Brooks 提出了一個時程分配的經驗法則

  • 1/3 用於計畫(Planning)
  • 1/6 用於編碼(Coding)
  • 1/4 用於元件測試與早期系統測試
  • 1/4 用於系統測試(所有元件已到位)

這個分配法則有兩個驚人的特點:

  1. 編碼只佔總時間的六分之一,遠低於一般人的預期
  2. 測試佔了總時間的一半——這與大多數排程中分配給測試的時間嚴重不符

系統測試的慢性低估#

系統測試幾乎總是被慢性低估的部分。當整合測試在專案末期發現問題時,所需的修正時間往往難以預測,而延誤又發生在最後階段——此時可見度最高、壓力最大。

缺乏勇氣的估算#

Brooks 觀察到,軟體經理往往缺乏捍衛自己時程估算的勇氣。面對來自客戶或上層的壓力,他們會屈服於不合理的時程要求。這部分源於軟體估算缺乏堅實的理論基礎——但即便估算不精確,它仍然比被迫接受的不切實際承諾要好得多。

Brooks 建議:經理必須學會區分「客戶期望的時程」與「技術上可行的時程」,並有勇氣在兩者衝突時選擇後者。

Brooks’s Law#

這是本書最為人所知的結論:

「為已經落後的軟體專案增加人力,只會使它更加落後。」

Adding manpower to a late software project makes it later.

為什麼增加人力會讓事情更糟?#

  1. 學習曲線:新成員需要時間學習專案的架構、程式碼和慣例。在此期間,他們不僅沒有產出,還會佔用現有成員的時間來教導他們。
  2. 溝通成本激增:溝通管道隨人數呈平方成長,每個新成員都會增加所有人的溝通負擔。
  3. 任務重新分割:原本已經分配好的工作必須重新切割和分配,這本身就需要時間和心力。
  4. 整合成本:更多的人意味著更多的介面、更多的整合問題、更多的協調需求。

再生式時程災難#

最危險的情況是一個自我強化的惡性循環:專案落後 → 增加人力 → 新成員拖慢進度 → 專案更加落後 → 再增加人力……Brooks 稱之為再生式時程災難(Regenerative Schedule Disaster),這正是大型軟體專案常見的死亡螺旋。

本章重點#

  • 人月是危險的神話——人力與時間不可互換,溝通成本隨團隊規模呈平方成長
  • 編碼只佔專案時間的 1/6,測試應佔 1/2,但大多數排程嚴重低估測試時間
  • 所有程式設計師都是樂觀主義者,排程時必須有意識地校正這種偏差
  • 軟體經理需要有勇氣捍衛合理的時程估算,而非屈服於客戶壓力
  • Brooks’s Law:為落後的專案加人,只會更落後——再生式時程災難是最常見的失敗模式