讀完這章你要能回答:瀑布、敏捷、看板各適用什麼場景?我的團隊踩過哪些「假敏捷」誤區?

選擇適合團隊的開發流程,是工程效能的基礎。

軟體開發模型#

沒有「最好的」開發模型,只有「最適合的」。選擇模型要考慮團隊情況、專案特點、業務需求。

寶玉在《軟體工程之美》中詳細介紹了各種開發模型。

瀑布模型#

flowchart TD
    A[📋 需求分析] --> B[🏗️ 系統設計]
    B --> C[💻 編碼實現]
    C --> D[🧪 測試驗證]
    D --> E[🚀 部署上線]
    E --> F[🔧 維護運營]

    style A fill:#e3f2fd
    style B fill:#e8eaf6
    style C fill:#fce4ec
    style D fill:#fff8e1
    style E fill:#e8f5e9
    style F fill:#f3e5f5

特點

  • 階段分明,前一階段完成才進入下一階段
  • 文件驅動,每個階段有明確的交付物
  • 變更困難,後期變更成本高

適用場景

  • 需求明確穩定
  • 大型系統、關鍵系統
  • 合規要求嚴格

不適用場景

  • 需求不確定或經常變化
  • 需要快速迭代的產品
  • 小團隊、創業公司

敏捷開發#

敏捷不是一種具體方法,而是一種價值觀和原則。

敏捷宣言的核心

  • 個體和互動 高於 流程和工具
  • 可工作的軟體 高於 詳盡的文件
  • 客戶合作 高於 合同談判
  • 回應變化 高於 遵循計劃

常見的敏捷實踐

實踐說明
Scrum固定週期衝刺,有明確的角色和會議
Kanban可視化工作流,限制在製品數量
XP強調工程實踐(TDD、結對編程等)

敏捷的常見誤區#

很多團隊以為「敏捷就是不寫文件」「敏捷就是隨時改需求」。這是對敏捷的誤解。

寶玉指出的問題:

誤區正確理解
不需要文件需要「剛剛好」的文件
隨時改需求每個迭代內需求穩定
不需要計劃需要持續的計劃和調整
只適合小團隊大團隊也可以用,需要框架支援

選擇開發模型的考量#

考慮因素:
├── 需求穩定性:變化多→敏捷,穩定→瀑布
├── 團隊規模:小團隊→輕量流程,大團隊→需要規範
├── 專案類型:產品迭代→敏捷,交付專案→瀑布
├── 組織文化:需要全組織配合
└── 客戶期望:有些客戶需要詳細計劃和文件

大多數團隊會採用混合方式。例如,用敏捷做迭代開發,但在架構設計階段用更瀑布式的方法。

開發流程實踐#

Sprint / 迭代#

典型的 Sprint 結構

flowchart LR
    subgraph DAY1 [📋 Sprint 計劃 第1天]
        A1[評審待辦事項]
        A2[承諾本迭代要完成的工作]
        A3[分解任務]
    end

    subgraph DEV [💻 開發階段 第2-9天]
        B1[每日站會 15分鐘]
        B2[開發、測試、修復]
        B3[持續整合]
    end

    subgraph END [🎯 Sprint 結束 第10天]
        C1[Sprint 評審:展示完成的工作]
        C2[Sprint 回顧:總結改進點]
        C3[為下個 Sprint 準備]
    end

    DAY1 --> DEV --> END
    END -->|下一個迭代| DAY1

    style DAY1 fill:#e3f2fd
    style DEV fill:#fff3e0
    style END fill:#e8f5e9

每日站會#

站會的目的

  • 同步進展
  • 識別障礙
  • 協調工作

站會的三個問題

  1. 昨天做了什麼?
  2. 今天計劃做什麼?
  3. 有什麼阻礙?

站會不是狀態匯報會。如果變成向領導匯報,而不是團隊互相同步,就失去了意義。

需求拆分#

使用者故事格式

作為 [角色]
我想要 [功能]
以便 [價值]

驗收標準:
- 當 X 時,Y
- 當 A 時,B

好的使用者故事的標準(INVEST)

  • Independent:獨立的
  • Negotiable:可協商的
  • Valuable:有價值的
  • Estimable:可估算的
  • Small:小的
  • Testable:可測試的

持續整合/持續交付#

CI/CD 的價值#

寶玉強調 CI/CD 的重要性:

持續整合和持續交付是現代軟體開發的基礎設施。沒有 CI/CD,很難做到快速、可靠的迭代。

持續整合(CI):
├── 頻繁合併程式碼(至少每天)
├── 自動化構建和測試
├── 快速發現和修復問題
└── 保持程式碼庫健康

持續交付(CD):
├── 程式碼隨時可以部署
├── 自動化部署流程
├── 一鍵發布能力
└── 快速回滾機制

CI/CD 流水線#

flowchart LR
    subgraph CI [持續整合 CI]
        A[📤 程式碼提交] --> B[🔍 程式碼檢查]
        B --> C[🔨 構建]
        C --> D[🧪 單元測試]
        D --> E[🔗 整合測試]
    end

    subgraph CD [持續交付 CD]
        E --> F[📦 部署測試環境]
        F --> G[✅ 驗收測試]
        G --> H[🚀 部署生產環境]
    end

    style A fill:#e8f5e9
    style H fill:#c8e6c9

實施 CI/CD 的建議#

階段建議
起步先建立自動化構建和測試
進階增加測試覆蓋率,加入更多檢查
成熟實現一鍵部署,持續改進流水線

CI/CD 不是一步到位的。從最基本的自動化構建開始,逐步完善。關鍵是「持續」改進。

持續交付的紀律#

小批次交付反直覺地「更快、更安全、更便宜」:批次越小,每次變更夾帶的風險越少、出問題時定位越快、回滾代價越低。把一次大發布拆成許多次小發布,整體品質反而更高。

支撐持續交付的幾項核心實務:

  • 發布列車(release train):以固定節奏(如每週)發車,功能趕上就上車、趕不上就搭下一班。它把「什麼時候發布」從每次的談判變成固定排程,反過來逼團隊主動排優先序——因為錯過列車的代價是明確的。
  • Feature Flag:用旗標把「部署」與「發布」解耦。程式碼可以先部署到生產環境但對使用者關閉,之後再透過開關控制曝光,讓上線與啟用各自獨立。
  • Canary(金絲雀):新版本先放給一小部分流量,觀察指標無異常再逐步放大,把爆炸半徑控制到最小。
  • Error Budget(錯誤預算,SRE):把可靠性目標(SLO)轉成「允許出錯的額度」。預算還有剩,就能放心快速推進新功能;預算燒光,就該把精力轉回穩定性。它讓「速度 vs 穩定」的拉鋸有了客觀的裁決依據。

發布列車的取捨:

面向好處代價
節奏可預測、逼出優先序沒趕上就得等下一班
風險批次小、回滾容易需要成熟的自動化與旗標機制
協作各團隊對齊同一節奏跨團隊依賴需提前協調
反例:YouTube 的治理 vs 架構教訓

YouTube 曾試圖用「流程治理」(更多審批、更嚴格的發布規定)來解決發布品質問題,效果有限——治理只是增加摩擦,沒有改變根本。真正解決問題的,是從架構著手:建立自動化測試、feature flag、canary 與快速回滾能力,讓系統本身能安全地承受頻繁變更。

教訓:當交付出問題時,先問「這是架構問題還是流程問題」。多數時候,用流程去補架構的洞,只會拖慢所有人卻治不了本。

程式碼管理#

版本控制策略#

寶玉介紹了常見的分支策略:

Git Flow

gitGraph
    commit id: "init"
    branch develop
    checkout develop
    commit id: "dev-1"
    branch feature/login
    checkout feature/login
    commit id: "feat-1"
    commit id: "feat-2"
    checkout develop
    merge feature/login
    commit id: "dev-2"
    checkout main
    merge develop tag: "v1.0"

GitHub Flow(更簡單):

gitGraph
    commit id: "init"
    branch feature/new-ui
    checkout feature/new-ui
    commit id: "feat-1"
    commit id: "feat-2"
    checkout main
    merge feature/new-ui
    commit id: "deploy" tag: "v1.1"

Trunk-Based Development

gitGraph
    commit id: "init"
    commit id: "small-change-1"
    branch short-lived
    commit id: "quick-fix"
    checkout main
    merge short-lived
    commit id: "small-change-2"
    commit id: "small-change-3"

一個源頭 + 主幹開發#

這三種策略並非等價、可隨意挑選。從工程效能的角度,它們有明確的優劣排序。

長命的 dev / release 分支是一種反模式。分支活得越久,與主幹的分歧越大,合併時的衝突與整合風險就指數上升——「合併地獄」正是源於此。分支不是用來囤積工作的倉庫。

業界大規模實證(DORA)顯示:主幹開發(trunk-based development)與高效能團隊正相關。其核心紀律:

  • 一個源頭(single source of truth):所有人都從同一條主幹拉取、往同一條主幹整合,沒有平行的長命分支。
  • 短命分支:分支只活幾小時到一兩天,小步快速合回主幹。
  • One-Version Rule:每個依賴在整個程式庫只允許一個版本,杜絕「同一套程式碼跑在不同版本依賴」的隱形分歧。

幾個有用的心智模型:

  • VCS 是 4D 檔案系統:版本控制不只管「現在的檔案」(3D),還管「跨時間的每個版本」(第 4 維)。理解這點,才會善用歷史而非只把它當備份。
  • green head vs true headtrue head 是主幹最新的 commit;green head 是最新「測試全綠」的 commit。CI/CD 應該對著 green head 部署,而不是盲目追 true head。

分支策略的推薦排序:

排序策略適用情境
1Trunk-Based Development追求高頻交付、CI/CD 成熟的團隊(首選)
2GitHub Flow中小團隊、單一可部署主線
3Git Flow有明確版本發布節奏、需並行維護多版本

越往下,分支越長命、整合成本越高。除非有明確理由(如需長期維護多個發布版本),否則優先往上選。

程式碼評審#

為什麼要做 Code Review

  • 發現 Bug 和設計問題
  • 知識共享和技術交流
  • 保持程式碼一致性
  • 提升程式碼品質文化

Code Review 的最佳實踐

審查者:
├── 及時回應(24小時內)
├── 關注重點(架構、邏輯、可讀性)
├── 提供建設性回饋
└── 不要雞蛋裡挑骨頭

提交者:
├── 保持 PR 小(200-400行)
├── 寫清楚描述和背景
├── 先自我審查
└── 對回饋保持開放

「200-400 行」是軟性啟發,不是硬規則。真正的原則是原子性:一個 PR 只做一件事、能被獨立理解與回滾。一個邏輯完整的 600 行重構,可能比硬切成三個互相依賴的 PR 更好評審。

三層核可:正確性、所有權、可讀性#

成熟的評審流程把「核可」拆成三種彼此獨立的把關,理解它們才能避免評審變成形式:

核可類型把關的問題由誰負責
LGTM(正確性)這段程式碼正確、合理嗎?任何夠格的同儕
Code-Owner這塊程式碼的主人同意這項變更嗎?該模組的 OWNERS
Readability風格與語言慣例達標嗎?有該語言 readability 認證的人

這三層常常由同一個人一次滿足,不必然要三個人。第一個 LGTM 往往就貢獻了約 80% 的評審價值——多數情況下一位評審就足夠。別把「多人評審」當成品質保證,那只會拖慢節奏卻邊際遞減。

  • OWNERS 檔:在目錄裡放 OWNERS 檔,宣告誰對這塊程式碼有核可權。它讓「Code-Owner 核可」變成可自動執行的規則,而非靠人記憶。
  • presubmit 自動檢查:在 PR 合併前自動跑建置、測試、靜態檢查與格式化,把機器能判斷的事交給機器。
  • 回應與回饋紀律:24 小時內回應評審請求;回饋要批次給(一次給完所有意見),避免擠牙膏式來回拖垮提交者。

樣式規範交給工具#

評審時為了縮排、命名風格爭論,是對所有人時間的浪費。樣式規範的設計有五個原則:

原則說明
規則要有價值每條規則都該有明確理由,不為規則而規則
為讀者最佳化程式碼被讀的次數遠多於被寫,優先利於閱讀
保持一致性一致性本身就有價值,降低認知負擔
避免意外構造不用容易誤導或出錯的語言特性
向實務妥協必要時為現實(效能、相容性)讓步

大約 90% 的樣式問題可以被自動檢查。把 formatter 與 linter 放進 presubmit,讓機器強制執行樣式,code review 就不該再為樣式爭辯——人類的注意力應該留給邏輯與設計。

會議效率#

技術團隊常見會議#

會議目的頻率時長
站會同步進展每天15 分鐘
計劃會規劃迭代每迭代1-2 小時
評審會展示成果每迭代1 小時
回顧會總結改進每迭代1 小時
技術評審評審方案按需1 小時

減少不必要會議#

寶玉的建議:

  • 能用文件/消息解決的不開會
  • 有明確議程再開會
  • 只邀請必要的人
  • 嚴格控制時間
  • 會後有記錄和行動項

技術人員的時間被會議碎片化,無法專注編碼。要保護團隊的專注時間。

本章要點#

  1. 沒有最好的模型:根據團隊和專案情況選擇
  2. 敏捷的誤區:不是不寫文件,不是隨意改需求
  3. 站會三問:昨天做什麼、今天做什麼、有什麼障礙
  4. CI/CD 是基礎:持續整合、持續交付,逐步完善
  5. 主幹開發優先:長命分支是反模式,trunk-based 與高效能正相關
  6. 小批次交付:發布列車 + feature flag + canary + error budget,更快也更安全
  7. Code Review 三層:正確性 / Code-Owner / 可讀性,第一個 LGTM 貢獻最大價值
  8. 樣式交給工具:~90% 樣式可自動化,評審別再爭辯風格
  9. 會議要高效:有議程、有時限、有跟進