第 11 / 11 部 待錄

趨勢效能與結語

《A Philosophy of Software Design 軟體設計的哲學》Podcast 準備稿:軟體趨勢、為效能而設計與結語

書名: 軟體設計的哲學 A Philosophy of Software Design 作者: John Ousterhout 系列: 旗艦評書(恩普拉氏) 公開標題建議: 評書|A Philosophy of Software Design.用複雜性檢視所有流行趨勢,並為整季作結 (11/11) 涵蓋範圍: 第19章 軟體趨勢 + 第20章 為效能而設計 + 第21章 結語 + 附錄 設計原則與紅旗清單

背景速覽

這是「旗艦評書.軟體設計的哲學」整季的收官集,把全書最後三章加附錄收在一起。第19章「軟體趨勢」是 Ousterhout 拿全書的「複雜性」這把尺,去逐一檢驗 OOP/繼承、敏捷、單元測試、TDD、設計模式、getter/setter 這些流行做法——這也是他對業界最有火藥味、也最常被引用的一章。第20章「為效能而設計」回答「那要快怎麼辦」,結論卻是「簡單通常也更快」。第21章結語和附錄則把整本書收束成一句話和兩張清單。這集既是本書的收尾,也是整季「評書」的總結——該給聽眾一個誠實的最終評價。

一句話重點

面對任何流行的開發 paradigm,都該用同一把尺去問:「它真的能降低大型系統的複雜性嗎?」——很多看似先進的做法(過度繼承、教條式 TDD、無腦 getter/setter、硬套設計模式)深入看反而增加複雜性;而效能也服從同一個原則——簡單的程式碼通常更快,真要優化時關鍵仍是把效能關鍵路徑做到極簡。

值得討論的重點

1. 用複雜性檢驗流行趨勢——本書最有火藥味的一章

第19章是 Ousterhout 開砲最猛的地方,建議一個一個過:

  • 繼承:介面繼承對抗複雜性(同介面多實作、知識可轉移、實作越多介面越深);但實作繼承要謹慎——它在父子類間建依賴、父類狀態被兩端存取造成階層內資訊洩漏,大量使用的階層往往複雜度極高。建議優先用組合(composition)
  • 敏捷:其增量精神與本書相通,但風險是滑進戰術型——敏捷讓人聚焦「功能」而非「抽象」、鼓勵延後設計。修正:增量的單位應該是抽象,不是功能
  • 單元測試:大力支持——它讓重構變安全,沒測試就不敢大改、複雜性只能累積。
  • TDD:他支持單元測試但不喜歡 TDD——TDD 注意力放在「讓特定功能通過」而非找最佳設計,太戰術、太細粒度、沒有明顯的設計時機。但 TDD 在修 bug 時很適合(先寫一個會因 bug 失敗的測試,修完再跑確認真修對)。
  • 設計模式:是「取代從零設計」的好選項,但別硬套——「設計模式好」不代表「用越多越好」。
  • getter/setter:被「用越多越好」迷思害得最慘的——「萬一要暴露變數時用 getter/setter 合理,但根本上就不該暴露 instance 變數」。它是淺方法,對介面只增雜訊。

2. 為效能而設計:簡單通常也更快

第20章打破「快」和「乾淨」對立的迷思。核心觀點:簡單依然最重要,而且通常也讓系統更快。兩個極端都不好——過度優化每行(拖慢開發、很多優化沒效)和完全忽略(千刀萬剮、回頭時沒有單一改動能救)。折衷:用基本效能知識,挑天生有效率又乾淨的設計,關鍵是知道哪些操作根本上昂貴(網路 round-trip、磁碟 I/O、malloc、cache miss——書裡有張成本表)。怎麼學?跑 micro-benchmark。而很多時候簡單與快並存:hash table vs ordered map,乾淨度相同但 hash table 快 5–10 倍。金句:消除特殊情況的 code 更快、深類別比淺類別更有效率(每次呼叫做更多事、少了層層跨越開銷)。

3. 真要優化時:量測,別憑直覺;圍繞關鍵路徑重設計

Ousterhout 給的優化方法論很硬核:程式設計師對效能的直覺極不可靠,憑直覺改只會浪費時間又增加複雜性。要先量測——找出「目前耗時且你有辦法改善」的精確位置、建立基準線,改完重測,沒明顯改善就回退(除非順便讓系統更簡單)。核心金句:沒有顯著加速的複雜性,沒理由保留。 真要圍繞關鍵路徑重設計,先想像「理想程式碼」——「在最常見情況下,完成此任務必須執行的最少 code 是什麼?」——再找最接近理想又乾淨的設計,並把特殊情況的檢查移出關鍵路徑(理想是開頭一個 if 涵蓋所有特例)。書裡 RAMCloud Buffer 的改寫是完美收尾:效能翻倍、設計更簡單、code 還少 20%,三贏。

4. 結語與附錄:全書收束成一句話和兩張清單

第21章把整本書收成一句:本書談的就是一件事——複雜性。它讓系統難建難維護、還常常更慢。所有建議都有短期成本(專案早期增加額外工作),但長期回報是:設計變成引人入勝的解謎、乾淨簡單顯而易見的設計是美的,而且技藝成熟後「好設計幾乎不比快速骯髒設計更費時」。最動人的是那個「雙倍紅利」——好設計者有更大比例時間花在設計(有趣的部分),爛設計者多半在追 bug;提升設計能力,不只交出更高品質的軟體,寫程式本身也更愉快。附錄則是兩張可帶走的清單:15 條設計原則(複雜性逐步累積、能跑還不夠、持續小額投資、模組要深、通用更深、把錯誤設計掉、設計兩次、為易讀而設計、增量單位是抽象……)和 14 條紅旗(淺模組、資訊洩漏、時序分解、過度暴露、穿透型方法、重複、通用/特殊混合、連體方法、註解重複 code、實作汙染介面、模糊名稱、難以命名、難以描述、不顯而易見的 code)——當設計檢查清單和 code review 掃描表用。

注意事項

⚠️ 第19章對 TDD、getter/setter 的批評是 Ousterhout 最具個人色彩、也最受爭議的部分——講的時候要標明這是一家之言。TDD 社群(Kent Beck 一脈)會強烈反駁「TDD 不利設計」,很多人的經驗恰恰相反(TDD 逼出更小、更可測的設計)。getter/setter 在某些框架/序列化場景幾乎是強制的。把這些當「Ousterhout 的觀點、值得辯論」呈現,比當「定論」更誠實,也更符合本書「帶腦讀」的精神。

⚠️ 「簡單通常更快」是趨勢、不是鐵律。Ousterhout 自己留了 RAMCloud 繞過 kernel 直接打 NIC 的例子——有些場景效能關鍵到值得增加複雜度,但前提是前期量測證明了必要性。別讓聽眾把「簡單更快」聽成「永遠不用管效能/不用做底層優化」。

⚠️ 整季收官,要給一個平衡的最終評價,而不是無腦吹捧。本書的局限值得誠實點出:它偏哲學、偏個人經驗(很多論點是「你心裡也這麼覺得」而非實證)、案例幾乎全來自作者自己的學生作業和 RAMCloud(樣本偏學界/系統軟體)、對前端/業務應用/團隊協作著墨少。它的價值在「提供一個統一的世界觀和一套可操作的紅旗」,但它不是放諸四海的食譜——這正好和它自己的態度一致。

專家補充

💡 整季對照線在這集要收口,給一個總評。檢視全季:Ousterhout 和 Uncle Bob 在八成的功夫上是一致的(命名、一致性、可讀性、別讓 code 腐爛、童子軍規則、為人而寫),真正的分歧高度集中在**「模組/函式該多大」——深模組 vs 小函式、稍大稍通用 vs 單一職責切小、「N 行就拆」之爭。而且這個分歧在不同抽象層各自成立**:Uncle Bob 優化「讀單一函式的瞬間」,Ousterhout 優化「用整個模組、改整個系統的長期成本」。所以藍圖 §5「Clean 到底乾不乾淨」的答案不是「Clean Code 錯了」,而是——Clean Code 在函式可讀性那層大致是乾淨的,但把『小』當教條推到模組層,就會製造 Ousterhout 說的淺模組與介面成本。 帶腦讀兩本,你會比只信一本的人更會設計。

💡 「程式設計師的效能直覺極不可靠、要先量測」這條,是和 Donald Knuth「過早優化是萬惡之源」一脈相承的工程智慧,也是今天 profiler 文化(perf、flamegraph、APM)的根基。RAMCloud Buffer「效能翻倍、code 少 20%」的案例,是「簡單與快並存」最有說服力的鐵證——值得當本季的一個記憶點收尾。

💡 那 14 條紅旗清單,是整本書最實用的「外帶品」。建議鼓勵聽眾把它印出來貼在螢幕旁、或設成 code review 的 checklist。本書最大的方法論貢獻,就是把抽象的「複雜性」變成一組在 code review 當場喊得出名字的紅旗——這比任何高深理論都更能改變一個團隊的日常。可呼應 EP1 立下的「這套紅旗是整季的詞彙」。

討論問題

🎙️ 開場鉤子:「TDD、設計模式、getter/setter、敏捷——這些你天天在用、被奉為最佳實踐的東西,如果拿一把尺去量它們,會剩下什麼?這位史丹佛教授的尺只有一個刻度:它到底是讓系統更簡單,還是更複雜?」

🎙️ 自問自答:「『要寫得快』和『要寫得乾淨』,真的是兩難嗎?」——用 RAMCloud Buffer 的案例回答:效能翻倍、設計更簡單、code 還少了兩成。簡單的 code,通常本來就比較快。

🎙️ 帶走的一題(整季收尾):「我們花了十一集,看兩位大師對著同一個敵人——複雜性——開出不同的藥方。最後留一題給你自己:下次你又想把一個函式拆小、或又想說『先這樣之後再重構』時,停三秒,問問 Ousterhout 會怎麼看,也問問 Uncle Bob 會怎麼看。能同時聽見兩個聲音、再自己決定的人,才是真的會設計的人。」

更大範圍關聯

  • 對照線總收口:本集為整季作結,回應 [軟體工程領域切分藍圖] §5「Clean 到底乾不乾淨」——結論是兩派八成一致、分歧集中在「模組/函式大小」且在不同抽象層各自成立。建議與 Reading Uncle Bob《Clean Code》全季對照收聽。
  • 軟工三經典的座標:本書與《Clean Code》《Refactoring》《Pragmatic Programmer》同屬旗艦,但它站得更高——談「戰略」而非「戰術」,與 Fred Brooks《人月神話》「本質複雜性 vs 偶然複雜性」遙相呼應,是這條思想線的當代總結。
  • 效能與優化傳統:「先量測、別憑直覺、過早優化是萬惡之源」上承 Knuth,下接今日 profiler/APM 文化;「簡單通常更快」是對「為了快必須犧牲乾淨」這個迷思的有力反駁。

錄製建議

  • 建議時長:約 24–28 分鐘(三章+附錄+整季總結,可放長)。配比:軟體趨勢約 10 分(最有料、最多爭議)、為效能設計約 8 分、結語+附錄+整季總評約 8 分。
  • 討論策略:用「拿一把尺量所有流行做法」開場,把第19章的逐項檢驗演成有節奏的「過堂」(每個趨勢給一句裁決);中段用 RAMCloud Buffer「三贏」案例打破快 vs 乾淨的對立;最後務必留足時間做整季總評——誠實點出本書局限、收束對照線(八成一致、分歧在大小、不同層各自成立)、並把 14 條紅旗當「外帶品」交到聽眾手上。
  • 這是整季最後一集,記得回扣 EP1 立下的定調(「經典要讀但要帶腦讀」「這套紅旗是整季的詞彙」),給聽眾一個有重量、有餘韻的收尾。