瀑布流程

2019 年 11 月 13 日

在軟體世界中,「瀑布」通常用來描述一種軟體流程風格,與迭代或敏捷風格的理念形成對比。就像軟體中許多著名的術語一樣,它的意義定義不清,起源也模糊不清 - 但我發現它的基本主題是根據活動將大量工作分解成階段。

目前尚不清楚「瀑布」一詞是如何變得如此普遍,但大多數人認為它的起源是 溫斯頓·羅伊斯的一篇論文,特別是這個圖

儘管這篇論文似乎普遍被認為是瀑布概念的來源(基於任務向下層疊的形狀),但「瀑布」一詞從未出現在論文中。目前尚不清楚名稱是如何在後續出現的。

羅伊斯的論文描述了他對當時(60 年代後期)軟體開發流程的觀察,以及如何改進通常的實作步驟。 [1] 但「瀑布」已經走得更遠,被用作軟體開發風格的一般描述。對於像我這樣在軟體研討會上發言的人來說,它幾乎總是只以貶義的方式出現 - 我不記得聽過任何研討會講者在多年來對瀑布說過任何好話。然而,在與企業從業人員交談時,我確實聽說它被視為一種可行的,甚至是首選的開發風格。當然,現在不如 90 年代那麼普遍,但比聽取流程專家的意見所假設的要更頻繁。

但「瀑布」究竟是什麼?這不是一個容易回答的問題,因為就像軟體中的許多事物一樣,沒有明確的定義。在我看來,有一個共同的特徵主導著人們對瀑布的任何定義,那就是根據活動將工作分解成階段的想法。

讓我解釋一下這個詞組。假設我有一些軟體要建置,而且我認為建置它大約需要一年的時間。很少有人會高興地說「離開一年,然後告訴我何時完成」。相反,大多數人會希望將那一年的時間分解成更小的區塊,以便他們可以監控進度並確信事情正在按部就班地進行。接下來的問題是如何執行這種分解?

瀑布風格,正如羅伊斯的草圖所建議的,是根據我們正在執行的活動來進行的。因此,我們的 1 年專案可能會分解成 2 個月的分析、4 個月的設計、3 個月的編碼和 3 個月的測試。這裡的對比在於迭代風格,我們會採用一些高階需求(建立一個圖書館管理系統),並將它們分為子集(搜尋目錄、預約書籍、借閱和歸還、評估罰款)。然後,我們會採用其中一個子集並花幾個月的時間來建置工作軟體以實作該功能,將其傳送到暫存環境或最好是傳送到現場製作環境。對一個子集執行此操作後,我們將繼續處理其他子集。

在這種思考方式中,瀑布表示「一次對所有功能執行一項活動」,而迭代表示「一次對一個功能執行所有活動」。

如果「瀑布」一詞的起源很模糊,那麼這種基於階段的細分是如何起源的這個概念也是如此。我的猜測是,將一項大型任務分解成不同的活動是很自然的,特別是如果你以建築施工等活動為靈感。每項活動都需要不同的技能,因此在引入所有編碼人員之前讓所有分析師完成分析在直覺上是有道理的。在人們開始編碼之前,對需求的誤解似乎更容易修正,特別是考慮到 60 年代末電腦的狀態。最後,相同的基於活動的細分可以用作許多專案的標準,而基於功能的細分則較難教授。[2]

儘管不難找到人解釋為什麼這種瀑布式思考不適合軟體開發,但我應該在此總結我對瀑布式的主要反對意見。瀑布式通常將測試和整合作為週期中的最後兩個階段,但這些是開發專案中最難預測的元素。這些階段的問題會導致重複執行早期階段的許多步驟,並導致專案大幅延遲。只宣告除了最後階段之外的所有階段都「完成」很容易,但缺少許多工作,因此很難判斷專案是否進行順利。在所有功能完成之前,沒有機會進行早期發布。所有這些都為開發工作帶來了很大的風險。

此外,瀑布式方法迫使我們採用預測式的規劃風格,它假設一旦你完成一個階段,例如需求分析,產生的可交付成果將成為後續階段工作的穩定平台。[3]在實務上,絕大多數軟體專案發現他們需要在幾個月內大幅變更其需求,因為每個人都更了解領域、軟體環境的特徵以及商業環境的變化。事實上,我們發現交付功能子集比任何事情都更能幫助釐清接下來需要做什麼,因此,迭代方法讓我們能夠轉換到適應性規劃方法,在我們了解軟體的實際需求時更新我們的計畫。[4]

這些是我輕率地說「你應該只在希望成功的專案中使用反覆開發」的主要原因。

瀑布式和反覆式可能會相互嵌套。一個六年專案可能包含兩個三年專案,其中兩個專案都以瀑布式風格架構,但第二個專案會新增其他功能。你可以將這視為頂層的兩次反覆專案,每次反覆都是瀑布式。由於規模龐大且反覆次數少,我會將其視為主要為瀑布式專案。相反,你可能會看到一個專案有 16 次反覆,每次反覆為一個月,其中每次反覆都以瀑布式風格規劃。我會將其視為主要為反覆式。雖然理論上可能會有難以分類的中間地帶專案,但實際上通常很容易看出哪一種風格佔主導地位。

瀑布式和反覆式可以混合,其中早期階段(需求分析、高階設計)以瀑布式風格進行,而後續階段(詳細設計、程式碼、測試)則以反覆方式進行。這會降低後續測試和整合階段固有的風險,但無法啟用適應性規劃。

瀑布式通常被視為敏捷軟體開發的替代方案,但我並不認為這是絕對正確的。敏捷流程確實需要反覆方法,且無法以瀑布式風格運作。但很容易遵循反覆方法(即非瀑布式),但並非敏捷。[5]我可能會透過在未來一年內將 100 個功能分成十次反覆來執行此操作,然後預期每次反覆都能按時完成其規劃的功能集。如果我這樣做,我的初始計畫就是預測性計畫,如果一切順利,我應該預期工作會緊密遵循計畫。但適應性規劃是敏捷思維的要素。我預期功能會在反覆之間移動,會出現新功能,且會捨棄許多不再有價值的功能。

我的經驗法則就是,任何說「我們成功是因為我們準時且符合預算」的人,即使他們遵循反覆流程,也是在預測性規劃的思維下思考,因此並非以敏捷思維思考。在敏捷世界中,成功完全取決於業務價值,無論幾個月前計畫中寫了什麼。計畫會制定,但會定期更新。它們會引導有關下一步該做什麼的決策,但不會用作成功指標。

進一步閱讀

Laurent Bossavit 在其優秀著作《軟體工程的妖精》中,對「瀑布式」一詞興起的起源進行了調查:https://leanpub.com/leprechauns

備註

1: 有很多人試圖詮釋 Royce 論文。有些人認為他的論文反對瀑布式,並指出論文討論了圖 2 中建議的流程類型中的缺陷,我已在此引述。他確實討論了缺陷,但他也表示,所說明的方法「在根本上是健全的」。這種基於活動的專案分解,肯定成為隨後幾十年中公認的模型。

2: 這會導致另一個與「瀑布」一詞相符的常見特徵 - 嚴格的流程,詳細說明每個人應該做什麼。90 年代的軟體流程人員當然熱衷於提出規範性方法,但這種規範性思維也影響了許多提倡迭代技術的人。儘管敏捷方法明確否認這種泰勒主義思維,但我經常聽說偽敏捷計畫遵循此路線。

3: 在開始下一個階段之前應該完成一個階段的概念是一種方便的虛構。即使是最熱切的瀑布支持者也會同意,在實際上對先前階段進行一些返工是必要的,儘管我認為大多數人會說,如果執行得完美,每個活動都不需要返工。Royce 的論文明確討論了預期在相鄰步驟(例如,他圖中的分析和程式設計)之間進行迭代。然而,Royce 認為較長的回溯(例如,程式設計和測試之間)是一個嚴重的問題。

4: 這確實提出了瀑布式風格實際上是否比迭代式更好的問題。理論上,瀑布式在對需求和所用技術有深入了解的情況下可能會更好,而且在產品生命週期內這兩者都不會發生重大變化。我說「理論上」,因為我沒有遇到過這種情況,所以我無法判斷瀑布式在實務上是否合適。即使在那時,我仍不願意遵循瀑布式風格進行後續階段(程式碼測試整合),因為我在持續整合時發現將測試與編碼交織在一起非常有價值。

5: 在 90 年代,物件導向世界普遍接受瀑布式是一個壞主意,應該用迭代式風格取代。然而,我不認為有敏捷社群出現的程度來接受變更需求。

致謝

感謝 Ben Noble、Clare Sudbury、David Johnston、Karl Brown、Kyle Hodgson、Pramod Sadalage、Prasanna Pendse、Rebecca Parsons、Sriram Narayan、Sriram Narayanan、Tiago Griffo、Unmesh Joshi 和 Vidhyalakshmi Narayanaswamy,他們在我們的內部郵寄清單上討論了這篇文章的草稿。