第 5 / 7 部 待錄

系統羽化平行化

《Clean Code》Podcast 準備稿:系統・羽化・平行化

書名: 無瑕的程式碼 Clean Code(A Handbook of Agile Software Craftsmanship) 作者: Robert C. Martin(Uncle Bob) 系列: Reading Uncle Bob(恩普拉氏) 公開標題建議: Reading Uncle Bob|Clean Code.系統、簡單設計與平行化:架構是長出來的 (5/7) 涵蓋範圍: 第11章 系統 + 第12章 羽化 + 第13章 平行化

背景速覽

這集把視角從「程式碼/類別」拉高到「系統」層次:系統(建造 vs 使用的分離、依賴注入)、羽化(Kent Beck 的簡單設計四原則——好架構是「長出來」的)、平行化(並行程式設計為何這麼難、怎麼防禦)。是全書從「微觀整潔」邁向「宏觀架構」的轉折。

一句話重點

把「建造(組裝物件、串依賴)」和「使用(跑業務邏輯)」分離,系統才好測試、好演進;而好架構不是一開始畫完美藍圖,是靠簡單設計四原則 + 持續重構「長出來」的;至於平行化——它很強大,但寫對它非常難,別輕信「框架幫你搞定」或「並行一定更快」

值得討論的重點

1.(系統)分離「建造」與「使用」

  • 用都市作比喻:城市能運作,是因為有適當的抽象層次與模組化,每個元件管好自己。
  • 把物件的建立與串接(建造)從業務邏輯(使用)抽離:移到 main、用工廠、或最強的——依賴注入(DI)/ 控制反轉(IoC)(物件不自己 new 依賴,由外部餵進來;Spring 是經典例)。
  • 橫切關注點(log、安全、交易)用 AOP 模組化,讓核心業務邏輯(POJO)保持純粹。
  • 心法:架構可以遞增成長,前提是維持關注點分離;不必 Big Design Up Front。

2.(羽化)簡單設計四原則(Kent Beck)

按重要性排序:

  1. 執行所有測試(能被測 → 能被驗證 → 才能部署;為了可測,自然會寫低耦合的 code)
  2. 沒有重複(DRY;消除重複會逼出抽象與職責邊界)
  3. 表達意圖(好命名、短函式、用設計模式的標準名稱、好測試當文件)
  4. 最小化類別與方法數量(這條用來「煞車」,避免為了教條造一堆無意義小類別)

遵循這四條,好設計會自然「羽化(emerge)」——不是設計出來,是長出來的。

3.(平行化)並行很難,先打破三個迷思

  • 迷思:①並行總是更快(錯,只有 I/O 等待或多核計算才有用);②不用改設計(錯,並行演算法結構完全不同);③靠框架就不用懂細節(錯,不懂鎖/信號量,框架也救不了死鎖)。
  • 防禦策略:SRP(並行邏輯與業務邏輯分離)、限制資料視野(縮小臨界區)、用資料副本/不共享(不共享就沒競爭)、用內建的執行緒安全集合(別自己鎖 HashMap)。
  • 測試心態:別把偶發失敗推給「系統不穩」「宇宙射線」——並行 bug 會在負載最高時爆炸。

注意事項

⚠️ 系統章很「Java/企業/Spring」味。 DI 容器、AOP、POJO 都是 2008 年 Java 企業開發的語境。核心思想(分離建造與使用、依賴抽象)跨語言通用,但聽眾若不是 Java 背景,要幫他們把 DI 翻譯成更普遍的話:「別讓物件自己決定它的依賴從哪來。」現代很多語言/框架用更輕量的方式達成(建構子注入、函式參數),不一定需要重型 DI 容器。

⚠️ 「簡單設計四原則」的排序有講究,別搞反。 「最小化類別數」排最後、是煞車條款——它的優先級低於前三條。常見誤用是拿「東西要少」去反對拆分,結果犧牲了可測試與表達意圖。講的時候強調排序。

⚠️ 平行化這章是 2008 年寫的,現代並行模型已大幅演進(async/await、actor 模型、Go 的 goroutine/channel、Rust 的所有權防資料競爭、函數式不可變資料)。Uncle Bob 的原則(少共享、縮臨界區)仍對,但要提醒聽眾:今天有比「手動 synchronized」好得多的工具。

專家補充

💡 「架構是長出來的」(emergent design)是敏捷/XP 的核心信念,但它和「預先架構(up-front architecture)」一直有張力。誠實的補充:簡單設計適合需求會變、有測試護體的場景;但有些決策(資料庫選型、要不要分散式)改起來代價極高,值得預先想清楚。 這也預告下一本《Clean Architecture》談的「哪些決策該延遲、哪些該早定」。

💡 DI/IoC 可以用一句話講清楚給非 Java 聽眾:「好萊塢原則——別打給我們,我們會打給你(Don’t call us, we’ll call you)。」物件不主動去抓依賴,而是被動接收。這個梗好記又精準。

💡 平行化的迷思①(並行≠更快)可連到 Amdahl 定律與「I/O bound vs CPU bound」——這是判斷「該不該上並行」的第一個問題,比任何鎖技巧都更前置、更重要。

討論問題

🎙️ 開場鉤子:「我們常以為好架構是某個資深架構師『一次設計到位』的——但 Uncle Bob(和 Kent Beck)說:好架構是『長出來』的。這對不對?什麼時候對、什麼時候危險?」

🎙️ 自問自答:「為什麼『多開幾個執行緒』常常不會更快、甚至更慢?」——用 I/O bound vs CPU bound 回答,破除「並行=效能」的直覺。

🎙️ 帶走的一題:「看你手上的類別——它有沒有在自己 new 一堆依賴(DB 連線、外部 client)?試著把『建造』搬出去、用參數餵進來,感受一下它變得多好測試。」

更大範圍關聯

  • 通往 Clean Architecture:系統章的「分離建造與使用、依賴抽象」是下一本《Clean Architecture》的縮影;DI/IoC、邊界、依賴方向都會在那裡系統化。
  • 簡單設計 vs 預先架構:接《A Philosophy of Software Design》、Fowler「YAGNI / Is Design Dead?」的辯論。
  • 並行現代化:Go 並行模型、Rust 所有權、actor/CSP——很好的【主題】跨語言題目;書庫《Database Internals》也涉及並行控制。
  • emergent design 的根:Kent Beck《TDD》《Extreme Programming》——系列藍圖大書。

錄製建議

  • 建議時長:約 20 分鐘。系統約 7 分、羽化約 6 分、平行化約 7 分。
  • 討論策略:三章用「從程式碼上升到系統」這條主線串起來。系統章用「好萊塢原則」講 DI 最好記;羽化章把「四原則的排序」講清楚(尤其最後一條是煞車);平行化章重點放在「破三迷思」而非鎖的細節(細節留給附錄 A,下一集)。結尾預告:下一集進三個實戰重構案例。
  • 平行化技術細節多,單人主講時抓「迷思 vs 事實」那張對照表講就夠,不要陷進 synchronized 語法。