開發團隊要成功,必須遵循一系列面向業務的實踐,包括 PlanningSmall ReleasesAcceptance TestsWhole Team。這些實踐的核心目標是彌合業務與開發之間的鴻溝,建立雙方的信任與順暢溝通。

Planning#

估算的本質#

估算(Estimate)本質上就是一種「猜測」——我們希望在不實際建造系統的前提下,對專案所需時間有個概念。因此估算天生就是 不精確的(imprecise),而這種不精確正是為了壓低估算本身的成本。

  • 精確(precise)與準確(accurate)是兩回事:一個估算可以非常準確,但不需要很精確。關鍵在於花最少的時間,找到仍然準確的最小範圍。
  • Trivariate Analysis(三值分析):對大型任務使用三個數字估算——Best Case(5% 信心)、Nominal Case(50% 信心)、Worst Case(95% 信心)。這是 PERT 技術的基礎,適合長期專案層級的估算。

Stories 與 Story Points#

User Story 是從使用者角度出發,對系統功能的簡短描述。它只是未來對話的「佔位符」,不是詳盡的需求文件。

  • Story 通常寫在 索引卡(index card) 上——能拿在手中傳遞、塗寫的實體卡片有巨大價值
  • 刻意不記錄細節:太早寫下的細節會變,而且投入太多心力在卡片上會讓卡片無法被丟棄或修改
  • Story 的建立永遠不會停止——隨時有新 Story 被寫出、修改、合併或丟棄

Story Points 不是時間單位,而是 估算的工作量單位(estimated effort)。它們大致呈線性關係(2 點的故事約需 4 點故事一半的工作量),但本身是模糊的。然而根據 大數法則(Law of Large Numbers),大量模糊數字的加總會趨於穩定。

估算流程:

  1. 選一個中等複雜度的 Story 作為 Golden Story(如 Login = 3 點)
  2. 所有其他 Story 相對於 Golden Story 做比較估算
  3. 使用 Flying FingersPlanning Poker 等共識估算方法

Figure 3.1: The Login story gets assigned three points

INVEST 原則#

Story 的品質可用 INVEST 這個縮寫來檢驗:

原則說明
IndependentStory 之間彼此獨立,可以按任意順序實作
Negotiable細節可以在開發者與業務之間協商,這是控制開發成本的管道
Valuable每個 Story 必須對業務有明確價值。重構、架構清理不是 Story
EstimableStory 必須具體到足以被估算;「系統必須快」這種不算
SmallStory 應小到 1-2 個開發者在單一 Iteration 內可完成
Testable業務能定義出驗證 Story 完成與否的測試

Story 是「薄的垂直切片」——橫切系統所有層(GUI、中間層、資料庫),而非只處理單一層。Refactoring 和 Architecture 永遠不是 Story,它們會透過其他方式處理。

Splitting、Merging 與 Spiking#

技術說明
Merging把多張卡片夾在一起,點數相加
Splitting將大 Story 拆成更小的、仍符合 INVEST 的 Story(例如 Login 可拆為「無密碼登入」、「單次密碼嘗試」、「多次密碼嘗試」、「忘記密碼」)
Spike一種「為了估算某 Story 而寫的 Story」——當團隊無法估算某 Story 時(例如從未用過某 PDF 函式庫),先做一個 Spike 來探索技術可行性

Iteration Planning#

每個 Iteration 開頭舉行 Iteration Planning Meeting (IPM),時長約為 Iteration 長度的 1/20(兩週 Iteration → 約半天)。

流程

  1. Stakeholders 事先按業務價值排序 Story
  2. 團隊根據 Velocity(上次 Iteration 完成的點數)決定容量
  3. Stakeholders 用 四象限遊戲 做 ROI 排序,選出本次 Iteration 要做的 Story

Figure 3.2: The four-quadrant game

四象限邏輯:

高成本低成本
高價值Do LaterDo Now
低價值Never DoDo Much Later

Velocity 是量測值,不是目標。 對 Velocity 施壓只會導致點數通膨——團隊會無意識地膨脹估算來顯示「更快」。控制理論的基本功:不要對你正在量測的東西施壓。

Yesterday’s Weather#

預測本次 Iteration 能完成多少點數的最佳方法就是看上次完成了多少——這就是 Yesterday’s Weather 原則。

  • 第一次 Iteration 的 Velocity 只能猜,但之後每次都用上一次的實際數據
  • Iteration 中間檢查:在 Iteration 中點時,完成的點數應約為目標的一半,否則需調整計畫
  • Iteration 不會失敗:即使沒完成所有 Story,Iteration 仍產生了寶貴的數據供管理者使用

Velocity 的健康指標#

指標意義
Velocity 上升通常不代表團隊真的變快,更可能是 點數通膨(在壓力下無意識調高估算)
Velocity 下降最可能的原因是 程式碼品質下滑——團隊沒有足夠的重構,技術債累積導致速度下降
Golden Story 是通膨的解藥持續拿新 Story 與最初的 Golden Story 比較,就能檢測通膨

專案何時結束#

專案的 Story Deck 像一個 ROI 的蓄水池——每次 Iteration 抽走 ROI,持續探索則注入新的 ROI。當不再有值得實作的 Story 時,專案就結束了。

專案不是在所有 Story 都完成時結束,而是在沒有值得實作的 Story 時結束。 作者曾參與一個為期一年的專案,第一個寫下的 Story(也是專案命名的由來)從未被實作——因為永遠有更緊迫的事要做。

管理 Iteration#

  • 聚焦完成 Story,而非推進任務:完成 80% 的 Story 遠比每個 Story 完成 80% 要好
  • 開發者自行選擇 Story,而非由管理者指派
  • 「完成」的定義:Acceptance Tests 通過
  • 每個 Iteration 結束時對 Stakeholders 做 Demo,最好由 Stakeholders 自己操作系統

Small Releases#

從「一兩個月」到 Continuous Delivery#

Agile 早期(1990 年代末)認為「小型發布」是每一兩個月一次。如今目標是 Continuous Delivery(持續交付)——每次變更後就發布到 Production。不只是交付週期,而是 所有週期都要縮短

版本控制的歷史演進#

理解為何週期縮短如此困難,需要回顧版本控制的歷史——它本質上就是「週期大小」的故事。

1950-60 年代:打孔卡片

程式碼儲存在紙上打的孔洞中,一張卡片 = 一行程式碼(80 字元)。程式是一疊用橡皮筋綁住、放在盒子裡的卡片。要「checkout」就是從抽屜裡拿走那疊卡片。只有拿走卡片的人能修改,週期時間可達數天到數月。

Figure 3.3: A punched card

Figure 3.4: Punched card decks in a box

1970 年代:磁帶

程式碼以卡片映像儲存在磁帶上,用顏色圖釘插在 checkout board 上標記誰鎖定了哪些模組。週期時間仍是數小時到數週。

1980 年代:磁碟與 SCCS

轉移到磁碟後,出現了 SCCS、RCS、CVS 等工具,使用 悲觀鎖(pessimistic lock)。磁碟允許更小的模組,間接縮短了週期時間,但高度耦合的系統仍然拖慢節奏。

Subversion 時代

SVN 引入 樂觀鎖(optimistic lock)——多人可同時 checkout 同一模組,工具自動合併變更。週期時間大幅縮短為「編輯、編譯、測試一小批變更」的時間。

Git 時代

Git 讓 checkout 時間降至零——commit 可隨時發生,衝突在程式設計師想解決時解決。搭配小型解耦模組、高頻 commit、以及全面的快速測試套件,Continuous Delivery 成為可能。

timeline
    title 版本控制的歷史演進
    1950-60s : 打孔卡片
             : 週期:數天到數月
    1970s : 磁帶
          : 週期:數小時到數週
    1980s : SCCS / RCS / CVS
          : 悲觀鎖
    2000s : Subversion
          : 樂觀鎖
    2005+ : Git
          : Continuous Delivery 成為可能

歷史慣性是最大阻力。 數天、數週、數月的週期已深植於許多團隊的文化中,蔓延到 QA、管理層和 Stakeholders 的期望。從這種文化的視角來看,Continuous Delivery 可能顯得荒謬。

Release 與 Deployment 解耦#

組織需要區分 ReleaseDeployment

  • Release:軟體在技術上已準備好被部署
  • Deployment:純粹是業務決策

Agile 透過不斷縮短發布週期(六個月 → 三個月 → 一個月 → 一週 → …)來打破歷史慣性,漸近地趨向零。

Acceptance Tests#

需求即測試#

Acceptance Tests 的核心理念出奇簡單:需求應該由業務方來定義,而規格本質上就是測試。

例如:「當使用者輸入正確的帳號密碼並點擊登入,系統應顯示歡迎頁面。」這既是規格,也是測試,而且可以自動化。

誰來寫?#

這個實踐之所以令人困惑,是因為存在一個拉鋸:

  • 業務方寫 → 觀點正確但不懂技術格式
  • 開發者寫 → 技術正確但偏離業務觀點

各種工具(FitNesse、JBehave、Cucumber、SpecFlow)試圖分離測試的業務面和技術面,讓業務寫業務側、開發者寫膠水程式碼。但業務方普遍抗拒形式化語言。

Behavior-Driven Development (BDD)Given-When-Then 格式降低技術門檻,讓業務方可以用較正式但非程式語言的方式定義系統行為。

實際運作方式#

儘管上述爭議,實踐本身很簡單:

  1. Business Analysts 撰寫 happy path 測試
  2. QA 撰寫 unhappy path 測試(數量遠多於前者)
  3. 開發者 確保測試自動化並整合到 Continuous Build
  4. 測試在 Iteration 前半段完成;若到中點還沒寫完,部分開發者應轉去協助寫測試

Story 在 Acceptance Test 寫出前不算被定義,在 Acceptance Test 通過前不算完成。 這是「完成」的唯一定義。

QA 角色的轉變#

傳統上 QA 是在專案尾端做測試的「守門員」。在 Agile 中,QA 轉變為在 Iteration 開頭 注入品質的「規格制定者」:

  • QA 不再跑測試(那是開發者的事)
  • QA 負責定義測試,確保系統可部署
  • 這避免了傳統模式中 QA 被上游延遲擠壓、被迫跳過回歸測試的問題

缺陷黑市經濟(The QA Disease):當 QA 在流程尾端時,QA 靠找到缺陷數量證明自己的價值,開發者靠「先交付、不管品質」來趕工期限。雙方都從缺陷中「獲益」,形成一種無需明說的共謀,嚴重侵蝕組織健康。

Whole Team#

從 On-Site Customer 到 Whole Team#

這個實踐最初叫 On-Site Customer——使用者與開發者的距離越短,溝通越好,開發越快越準確。後來改名為 Whole Team,強調開發團隊不只是客戶與程式設計師的二元組合,而是包含管理者、測試人員、技術寫作者等多種角色。

在 Scrum 中,客戶角色被稱為 Product Owner——負責選擇 Story、設定優先序、提供即時回饋。

Co-Location 的價值#

將所有團隊成員放在同一個房間,能最大化團隊效率:

  • 快速溝通:問題在幾秒內就能提出並獲得解答
  • 偶發性協同(Serendipity):客戶可能瞥見螢幕上不對勁的東西;測試人員可能無意中聽到開發者討論而發現對需求的誤解
  • 這是一個 業務實踐,而非團隊實踐——主要受益者是業務方

遠端工作的現實#

  • 離岸外包:1990 年代開始流行,但距離(地理、時區、語言、文化)造成大量溝通失誤、品質低落、返工暴增
  • 遠端在家工作:語言和文化問題較小,但仍損失非語言溝通和偶發對話的機會。團隊中一兩人偶爾在家工作影響不大,但完全遠端的團隊永遠無法達到 Co-Located 團隊的效率
  • 不過作者自己也承認,他曾成功管理過一個完全遠端的團隊——只是「如果能在同一間房間,會更好」

即使遠端工作可以成功,仍然是在透過一個「窺視孔(peephole)」溝通——與 Co-Located 團隊的豐富頻寬相比,總是有所損失。

Conclusion#

Kent Beck 在 2001 年 Snowbird 會議上說過,Agile 的目標之一是 修復業務與開發之間的裂痕。Business Practices 正是實現這個目標的核心:透過 Planning 建立透明度、透過 Small Releases 縮短回饋週期、透過 Acceptance Tests 對齊需求理解、透過 Whole Team 最小化溝通成本。這些實踐讓雙方有了簡單且明確的溝通方式,而溝通孕育信任。