《Clean Craftsmanship》Podcast 準備稿:重構與簡單設計.把程式碼當黏土
書名: 整潔的軟體工藝 Clean Craftsmanship(Disciplines, Standards, and Ethics) 作者: Robert C. Martin(Uncle Bob) 系列: Reading Uncle Bob(恩普拉氏) 公開標題建議: Reading Uncle Bob|Clean Craftsmanship.Kent Beck 用四行寫完的設計 (5/9) 涵蓋範圍: Part I 第5章 Refactoring + 第6章 Simple Design
背景速覽
前三集打好了測試的地基,這集講「有了測試之後你能做什麼」——重構(在不改行為的前提下改善結構)與它的終極目標:簡單設計。這兩章是雙生的:重構是手段,簡單設計是目的。Uncle Bob 把重構講成「解魔術方塊」,把簡單設計濃縮成 Kent Beck 的四條規則(「Uncle Bob 寫了幾千頁談乾淨程式碼,Kent Beck 用四行就寫完了」)。這集很實用,也是整季「明天就能用」濃度最高的一集。
一句話重點
重構不是「排程裡的一個任務」、不是要老闆批准的特別活動,而是像上完廁所洗手一樣自然、每繞一圈紅綠重構就順手做的持續習慣;而它瞄準的「簡單」只有一個本質——把高階策略和低階細節解開糾纏,讓你能毫不費力地繼續加功能。
值得討論的重點
1. 重構的紀律:小到不需要除錯器、永遠不要請求許可
Uncle Bob 對重構的定義有兩個鐵則:保持行為不變(唯一證明方式是持續通過完整測試)、每一步都很小——小到什麼程度?小到「不需要進除錯器」(Rule 15:避免除錯器;若怕要進除錯器,就把步驟拆更小)。基本工具箱裡最重要的是 Extract Method,他主張「Extract ‘til You Drop」——一直擷取到再也擷取不出函式為止,目標是每個函式只做一件事、讀起來像寫得好的散文。配一條反直覺原則:函式名長度與作用域大小成反比(public 短、private 長)。最後兩句很有力量:「永遠不要為重構道歉」「永遠、永遠不要請求重構的許可」——重構是你工作的一部分,不是額外的恩惠。
2. 魔術方塊的比喻與「為自己留退路」
重構像解魔術方塊:每個「操作」保持大部分不變、只可預測地動幾格;你會的操作越多越熟,就越能隨心所欲地推拉程式碼。但走錯一步,方塊就崩成隨機狀態,得從頭來——而「沒有測試的重構,崩潰幾乎是必然的」。配套的實務智慧是「Leave Yourself an Out」:像飛行員飛進壞天氣前先確認逃生路線一樣,開始一串可能走死胡同的重構前,先標記 commit——「git reset --hard 可以是你的好朋友」。這段對聽眾很受用:大膽重構的前提是隨時能安全撤退。
3. 簡單設計的四條規則:覆蓋、表達、去重、精簡
簡單(Simplicity)的定義是「未糾纏(untangled)」——而最昂貴的糾纏,是高階策略和低階細節纏在一起(SQL 混進 HTML、框架混進核心價值)。Kent Beck 的四條規則(Fowler 整理版)有明確的優先順序:
- 被測試覆蓋(最重要)——可測 = 解耦,寫測試本身就是設計行為。沒有它,後三條全做不到。
- 最大化表達——讓程式碼讀起來像揭示意圖的散文;測試補上「怎麼用」這一半。
- 最小化重複——但小心意外重複(看起來一樣、卻會因不同原因而改變的兩段碼,不該合併;真重複的意圖是收斂的,意外重複是發散的)。
- 最小化大小——在不違反前三條下,把每個函式縮到最小。
還有一個重要的搭配概念:YAGNI(You Aren’t Gonna Need It)。1980-90 年代因為改 code 很貴,大家拼命預埋「未來用得到的掛鉤」;但現在建置秒級、測試便宜,取捨翻轉了——多數掛鉤別放,需求變了再重構,因為「我們很少猜得對客戶要什麼」。
注意事項
⚠️ 「Extract ‘til You Drop」與「函式越小越好」是 Uncle Bob 最受爭議的主張之一,務必平衡。John Ousterhout《A Philosophy of Software Design》直接唱反調:他主張「深模組」(簡單介面、豐富實作),認為過度拆小函式會製造大量淺模組、把邏輯打散成碎片、增加閱讀時的跳轉成本(他稱之為 “classitis” / 過度分解)。這是整季最該並陳的對照組——「小函式」陣營 vs 「深模組」陣營,兩邊都有重量級支持者,聽眾該自己權衡。
⚠️ 「永遠不要請求重構的許可」氣勢很足,但在真實團隊裡要小心分寸。Uncle Bob 的本意是「小步、持續、隨手的重構不需要請示」(這完全對);但「停下功能、花兩週做大型重構/重寫」是另一回事,那需要溝通與共識。別讓聽眾拿這句當「不跟團隊商量就大改架構」的擋箭牌。
⚠️ 「意外重複不該消除」是個微妙但重要的點,很容易被 DRY 教條蓋過去。過度套用 DRY、把兩段「長得像但會分頭演化」的碼硬合併,會造出一個被各種 flag 和特例污染的怪物函式——這種「錯誤的抽象」往往比重複本身更糟(Sandi Metz 名言:「重複遠比錯誤的抽象便宜」)。這條值得特別強調。
專家補充
💡 簡單設計章有個很美的諷刺,值得講:Moore’s Law 的指數成長同時驅動我們造更複雜的系統、又讓我們能大幅簡化設計(因為建置/測試變便宜,不必再過度設計)。也就是說,硬體的進步不只是讓軟體能做更多,更是解放了我們去寫更簡單的軟體——前提是我們願意接受 YAGNI、願意靠重構而非預測來應對變化。
💡 四條規則的排序本身就是一個設計哲學的縮影:測試(可驗證性)排第一,美學(精簡)排最後。這跟很多人的直覺相反——很多人從「把程式碼弄漂亮」開始,但 Uncle Bob 說先確保它「可被安全改動」,漂亮是最後才追求的。這個優先順序在後面的「標準」與「倫理」兩部會再次出現(結構價值 > 行為價值)。
💡 給聽眾的落地心法:重構不必是大工程。最好上手的入口是「改一個爛名字 + 抽一個小函式」——每次打開檔案做這兩件事之一就好。這跟《Clean Code》EP1 的童子軍規則是同一條習慣,Uncle Bob 在這裡只是把它升級成「有測試撐腰、所以敢做得更狠」。
討論問題
🎙️ 開場鉤子:「Kent Beck 說,好設計只需要四條規則。Uncle Bob 寫了幾千頁,Beck 寫了四行。今天我們來看那四行,到底憑什麼。」
🎙️ 自問自答:「為什麼『請給我兩週做重構』這種話注定被拒?」——因為重構本來就不該是獨立任務,它該像洗手一樣內建在每次寫程式裡。
🎙️ 拋給聽眾的對立題:「函式到底該多小?Uncle Bob 說擷取到掉下去為止,Ousterhout 說別把邏輯切成碎片要深模組——你的 codebase 比較需要哪一帖藥?」
🎙️ 帶走的一題:「下次按下重構快捷鍵之前,先 commit 一次。給自己一條隨時能 git reset --hard 的退路,然後放膽改。」
更大範圍關聯
- 重構的正典:Martin Fowler《Refactoring》(第二版 2018) 是這章背後的母體——本章是「重構的紀律與心法」,Fowler 那本是「重構的招式手冊」。兩本搭配是完整套餐。
- 簡單設計的對照組:John Ousterhout《A Philosophy of Software Design》(深模組 vs 小函式) 是這集最該登場的反方;Sandi Metz 對「錯誤抽象」的論述補強了「意外重複別亂合」這點。
- 同系列接點:本章的「可測 = 解耦」「結構價值」直接接到下下一集的 Part II 標準(Quality 章的 Fearless Competence)與 Part III 倫理(Harm 章的結構 > 行為)。重構/簡單設計是整本書「結構優先」這條主軸的技術根基。
- 領域定位:用 [軟體工程領域切分藍圖] 看,這兩章是「設計/重構」核心,也是軟體工匠三經典(Clean Code、Refactoring、Pragmatic Programmer)交會之處。
錄製建議
- 建議時長:約 24-26 分鐘(兩章合併,份量足)。配比:重構紀律與工具箱 7 分、魔術方塊與留退路 3 分、四條規則 8 分、YAGNI 與意外重複 4 分、小函式爭議(Ousterhout)4 分。
- 討論策略:這集是「明天就能用」濃度最高的一集,多給具體招式(Extract Method、留退路、改爛名字)。把「小函式 vs 深模組」的爭議放在後段當思辨高潮——這是整季最值得讓聽眾「自己選邊」的一題,不要替他們下定論。結尾用「四條規則的排序:可驗證性第一、美學最後」收束,順勢預告 Part I 最後一集進入團隊協作。