Bob Martin 以 CTO 的口吻,對生產力提出四項期望。這些期望不是管理上的願望清單,而是專業開發者應該內化的最低標準。
We Will Never Ship S**T(我們絕不交付垃圾)#
每個開發者大概都有過交付垃圾的經驗——為了趕 deadline、為了不好意思說估算錯了、為了管理層的壓力、甚至只是粗心大意。但不管理由是什麼,這些理由都不成立。
什麼是垃圾?
- 每一個你交付出去的 bug
- 每一個未經測試的功能
- 每一個寫得很爛的函式
- 每一個對細節的依賴(dependency on detail)
- 每一個不必要的耦合
- GUI 裡面出現 SQL
- Business rules 裡面出現 database schema
前面章節所有紀律(TDD、Refactoring、Simple Design 等)的每一次違反,都有可能產生垃圾。
工程師的權衡#
這不代表每一條紀律都必須在所有時刻被遵守。工程師會做權衡(trade-off),但工程上的權衡不是粗心或草率。如果你必須打破某條紀律,你需要:
- 一個好的理由
- 一個好的緩解計畫(mitigation plan)
以 CSS 為例:事先為 CSS 撰寫自動化測試通常不切實際,你要看到畫面才知道對不對。那緩解計畫是什麼?
- 用眼睛手動測試
- 在所有客戶可能使用的瀏覽器上測試
- 制定一份標準的畫面規格描述,定義可接受的變化範圍
- 設計出技術方案讓 CSS 容易手動測試
- 這些測試由開發者自己做,不是丟給 QA
換句話說就是:把工作做好。 所有人——管理者、使用者、所有接觸到軟體的人——都期待我們把工作做好。
Inexpensive Adaptability(低成本的可適應性)#
Software 是一個複合詞,意思是「有彈性的產品」(flexible product)。軟體存在的全部理由,就是讓我們能快速且輕鬆地改變機器的行為。當我們把軟體寫到難以修改,就違反了軟體存在的根本意義。
為什麼軟體會變僵硬?#
因為團隊未能執行測試和重構的紀律。有些團隊只依賴初始設計和架構,有些則追逐流行但不可持續的做法。
無論你建了多少 microservices,無論初始設計和架構願景多完美,缺少測試和重構紀律,程式碼都會快速退化,系統會變得越來越難維護。
CTO 的期望#
- 當客戶要求變更時,開發團隊應提出一個成本與變更範圍成正比的策略
- 客戶或許不懂系統內部,但他們對變更的範圍有直覺——他們期望成本與範圍匹配
- 太多系統隨時間變得僵化,導致變更成本高到客戶和管理者覺得不合理
- 更糟的是,有些開發者會以「這違反系統架構」為由抵制變更
一個抵制客戶合理變更需求的架構,就是一個違背軟體意義的架構。這樣的架構必須被改變以適應客戶的需求。而讓這種改變變容易的,就是良好的重構和你信任的測試套件。
We Will Always Be Ready(我們隨時準備好)#
快速的部署節奏#
軟體部署的節奏經歷了一段歷史演變:
| 時代 | 部署節奏 |
|---|---|
| 早期 | 每週甚至每天部署 |
| 1970 年代 Waterfall 時代 | 節奏拉長到數月甚至數年 |
| Agile 時代 | Scrum 建議 30 天 sprint,XP 建議 3 週 iteration,後來都加快到雙週 |
| 現代 | 許多團隊每天部署多次,開發週期趨近於零 |
Technically Ready to Release#
CTO 期望最長一到兩週的 sprint,每次 sprint 結束時軟體在技術上已可發布。
所謂「技術上可發布」的意思是:
| 項目 | 說明 |
|---|---|
| 不代表 | 商業上一定要發布——可能功能集不完整 |
| 代表 | 如果商業部門決定發布,開發團隊(包括 QA)沒有異議 |
| 代表 | 軟體能用、已測試、已文件化、已準備好部署 |
| 不需要 | 漫長的 burn-in 期或所謂的「穩定化 sprint」 |
| 不應該 | Alpha 和 beta 測試可用來驗證功能與使用者的相容性,但不應該用來抓 coding defects |
Bob 講了一個故事:某個製作法律文書處理器的團隊,學了 XP 之後,每週燒一張新的 CD 放在實驗室的堆疊頂端。業務員要去客戶面前 demo 時,直接走進實驗室拿最上面那張就走。這就是「隨時準備好」的程度。
需要什麼來維持這種就緒狀態?#
| 面向 | 說明 |
|---|---|
| 規劃 | Stakeholders 和開發者頻繁地估算並選擇最高價值的 story |
| 測試 | QA 深度參與,提供定義「完成」的自動化驗收測試 |
| 協作 | 開發者緊密合作,維持密集的測試、審查和重構紀律 |
| 態度 | 隨時準備好不只是遵循 Agile 的教條和儀式,而是一種持續交付增量價值的承諾和生活方式 |
Stable Productivity(穩定的生產力)#
生產力下降的惡性循環#
軟體專案經常隨時間經歷生產力下降,這是嚴重功能失調的症狀,根因是忽略了測試和重構紀律。惡性循環如下:
- 程式碼變得糾結、脆弱、僵硬 → 越來越難保持乾淨
- 脆弱度上升 → 對改動的恐懼增加
- 開發者越來越不敢清理髒亂的程式碼 → 怕越清越多 bug
- 數個月內,生產力加速下滑,漸近於零
加人解決不了問題#
管理者常試圖加人來對抗生產力下降,但新人一樣會被恐懼感染——他們很快學會模仿現有成員的行為,問題只會被延續。
重寫的誘惑#
- 當開發者被追問生產力為何下降,他們會抱怨程式碼品質太差
- 他們開始要求從頭重新設計系統
- 論點是:「我們知道過去犯了什麼錯,不會再犯了」
- 管理者不信任這個論點,但因為絕望而讓步
- Bob 不期望這種情況發生
flowchart TD
A["程式碼糾結/脆弱"] --> B["恐懼增加"]
B --> C["不敢清理"]
C --> D["生產力下降"]
D --> E["管理者加人"]
E --> F["新人感染恐懼"]
F --> G["生產力更差"]
G --> H["要求重寫"]
H -.->|"重寫後循環重演"| ACTO 的期望很明確:開發團隊應持續保持高生產力,可靠地運用紀律來防止軟體結構退化。生產力應該是穩定的,而不是一條向下的曲線。