讀完這章你要能回答:瀑布、敏捷、看板各適用什麼場景?我的團隊踩過哪些「假敏捷」誤區?
選擇適合團隊的開發流程,是工程效能的基礎。
軟體開發模型#
沒有「最好的」開發模型,只有「最適合的」。選擇模型要考慮團隊情況、專案特點、業務需求。
寶玉在《軟體工程之美》中詳細介紹了各種開發模型。
瀑布模型#
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每日站會#
站會的目的:
- 同步進展
- 識別障礙
- 協調工作
站會的三個問題:
- 昨天做了什麼?
- 今天計劃做什麼?
- 有什麼阻礙?
站會不是狀態匯報會。如果變成向領導匯報,而不是團隊互相同步,就失去了意義。
需求拆分#
使用者故事格式:
作為 [角色]
我想要 [功能]
以便 [價值]
驗收標準:
- 當 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 head:
true head是主幹最新的 commit;green head是最新「測試全綠」的 commit。CI/CD 應該對著 green head 部署,而不是盲目追 true head。
分支策略的推薦排序:
| 排序 | 策略 | 適用情境 |
|---|---|---|
| 1 | Trunk-Based Development | 追求高頻交付、CI/CD 成熟的團隊(首選) |
| 2 | GitHub Flow | 中小團隊、單一可部署主線 |
| 3 | Git 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 小時 |
減少不必要會議#
寶玉的建議:
- 能用文件/消息解決的不開會
- 有明確議程再開會
- 只邀請必要的人
- 嚴格控制時間
- 會後有記錄和行動項
技術人員的時間被會議碎片化,無法專注編碼。要保護團隊的專注時間。
本章要點#
- 沒有最好的模型:根據團隊和專案情況選擇
- 敏捷的誤區:不是不寫文件,不是隨意改需求
- 站會三問:昨天做什麼、今天做什麼、有什麼障礙
- CI/CD 是基礎:持續整合、持續交付,逐步完善
- 主幹開發優先:長命分支是反模式,trunk-based 與高效能正相關
- 小批次交付:發布列車 + feature flag + canary + error budget,更快也更安全
- Code Review 三層:正確性 / Code-Owner / 可讀性,第一個 LGTM 貢獻最大價值
- 樣式交給工具:~90% 樣式可自動化,評審別再爭辯風格
- 會議要高效:有議程、有時限、有跟進