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 -.->|"重寫後循環重演"| A

CTO 的期望很明確:開發團隊應持續保持高生產力,可靠地運用紀律來防止軟體結構退化。生產力應該是穩定的,而不是一條向下的曲線。