<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Craft on Tarragon</title><link>https://tarrragon.github.io/blog/tags/craft/</link><description>Recent content in Craft on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Wed, 19 Aug 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/craft/index.xml" rel="self" type="application/rss+xml"/><item><title>設計判準與日常實踐</title><link>https://tarrragon.github.io/blog/books/craft/design-and-practice/</link><pubDate>Wed, 19 Aug 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/books/craft/design-and-practice/</guid><description>&lt;p>這個主題處理兩件在日常裡分不開的事：把程式寫成之後改得動的樣子，以及讓那件事持續發生的工作習慣。它們分不開的理由是設計判準要靠習慣才生效——知道模組該小、介面該深，跟每次動手時真的去想這件事，中間隔著一整套日常做法。&lt;/p>
&lt;p>三本書的差別在&lt;strong>密度與主張數&lt;/strong>，不在誰對誰錯：《The Pragmatic Programmer》列幾十條短原則、《A Philosophy of Software Design》用一條主張貫穿全書、《Code Complete》鋪成百科式的對照表。手上的問題越具體，越適合主張集中的《A Philosophy of Software Design》；想建立通盤基礎，才輪得到百科式的《Code Complete》。&lt;/p>
&lt;p>處境相容性這一項三本都查過，都沒有列出限制。它們的判準落在程式碼本身的形狀與個人的動手習慣上，成立與否不取決於組織有沒有職級制度、成員是不是同一個僱主、大家在不在同一個時區，也不受事故追責義務左右。這是全批唯一每一本都查過、而且每一本都沒有依賴的一篇——同一條技藝線上的另外三篇不是這樣，架構、驗證與改既有程式那三篇各自都有書預設了特定的組織條件。&lt;/p>
&lt;h2 id="起點是-the-pragmatic-programmer">起點是 The Pragmatic Programmer&lt;/h2>
&lt;p>Dave Thomas 與 Andy Hunt 的《The Pragmatic Programmer》把技藝拆成幾十條自成一段、互不依賴的實踐——從 DRY、正交性這種設計判準，到版本控制、純文字、自動化這種工具習慣，再到知識組合、除錯紀律這種職業態度——任何一條都可以單獨拿走用。條目多而彼此不相依，是它在本篇管得最寬、因此當起點的原因。&lt;/p>
&lt;p>它最常被引用的是 DRY，而它的原文比多數轉述嚴格：系統裡的每一項知識都必須有單一、明確、權威的表述。這句話管的不只是程式碼——業務規則、設定值、資料定義同樣算，而多數 DRY 的誤用是把它讀成「不要複製貼上」，於是把兩段長得像但會各自變動的程式硬合併，製造出更難改的耦合。&lt;/p>
&lt;p>另一條沒有被廣泛轉述的是曳光彈（tracer bullets）：先打通一條從頭到尾都會動的最細路徑，再逐段加厚。它跟原型的差別在於曳光彈的程式碼會留下來成為骨架，原型是用完就丟——搞混這兩者的團隊會把探索用的臨時程式碼帶進生產。&lt;/p>
&lt;p>20 週年版是大幅改寫過的，不是加註解的重印本，並補進了並行、actor model、property-based testing 與資安基礎。要買就買這一版。時效上，第一版綁的工具與環境（CVS、特定編輯器）在改版時清掉了；DRY、正交性、曳光彈、破窗理論這些主張不依賴任何工具世代。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/books/knowledge-cards/evidence-provenance/" data-link-title="證據來源分類（evidence provenance）" data-link-desc="手上兩本書講同一件事而結論不同、或要拿一本書去支持一個實際決定時，用來判斷它支持得了多大範圍的決定">證據來源&lt;/a>是跨客戶的顧問經驗，形式是格言加短例而非資料——這也決定了它的用法：拿來當檢查表對照自己的習慣，而不是拿去說服別人。&lt;/p>
&lt;p>這本書幾乎不需要前置準備，入行第一年就可以讀；而且每隔幾年重讀會讀出不同的東西，因為同一條原則在不同經驗量下對得上的情境不一樣。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.amazon.com/Pragmatic-Programmer-journey-mastery-Anniversary/dp/0135957052">Amazon（The Pragmatic Programmer, 20th Anniversary Edition）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.books.com.tw/products/0010856354">博客來（The Pragmatic Programmer 20 週年紀念版）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="想把設計問題想清楚時讀-a-philosophy-of-software-design">想把設計問題想清楚時讀 A Philosophy of Software Design&lt;/h2>
&lt;p>John Ousterhout 的這本整本只推一個主張：&lt;strong>軟體設計的根本問題是控制複雜度&lt;/strong>，其餘的判準都從這一條長出來。這種寫法的好處是它給得出一個可以隨身帶的判準，而不是一份要背的清單。&lt;/p>
&lt;p>書中最可操作的是深模組（deep module）這個概念：好的模組是介面小而實作厚，壞的模組是介面跟實作一樣大。這條判準直接推翻了「函式應該盡量短」這種常見指導——把一個模組切成十個各自很淺的函式，介面總量反而變大，複雜度是上升的。另一組是紅旗清單（淺模組、資訊洩漏、時序分解、重複、註解重述程式碼），設計時可以逐條掃。&lt;/p>
&lt;p>它跟 Pragmatic Programmer 的關係是深度換廣度：那本列出有哪些事該做，這本把其中一件（怎麼切模組）挖到底。兩本一起讀不會重複。&lt;/p>
&lt;p>證據來源是單一路徑的個人經驗，而形態特別：素材來自作者多年開設軟體設計課的學生專案觀察，樣本受控但規模小、且偏向課堂專案，這是它跟業界顧問經驗不同的地方。作者是 Tcl 的作者、Stanford 教授。第二版於 2021 年出版，補了更多例子並回應了對第一版的批評。時效上沒有綁定任何工具世代。&lt;/p>
&lt;p>讀這本要先有一段維護經驗當對照：維護過自己或別人寫的東西超過半年，經歷過「當初這樣切好像不對」。沒有這個對照時，深模組會讀成一個偏好而不是判準——可以先讀《The Pragmatic Programmer》，等維護經驗累積起來再回來讀這本。&lt;/p>
&lt;p>繁體中文版查不到，簡體中文版《軟件設計的哲學》第二版由人民郵電出版社出版。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.amazon.com/Philosophy-Software-Design-2nd/dp/173210221X">Amazon（A Philosophy of Software Design, 2nd Edition）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.tenlong.com.tw/products/9787115655615">天瓏（軟件設計的哲學 2/e，簡體中文版）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="要一份百科式的對照時讀-code-complete">要一份百科式的對照時讀 Code Complete&lt;/h2>
&lt;p>Steve McConnell 的《Code Complete》第二版是這個主題涵蓋面最大的一本，把建構期的每個決定都拆開處理：變數命名、迴圈結構、防禦性編程、程式碼佈局、審查方式。它跟前兩本的差別在於它不推銷單一主張，而是把當時能找到的研究與實務歸納整理成對照表。&lt;/p>
&lt;p>它的獨特之處是引用密度。多數技藝書的主張來自作者經驗，這本大量引用了實證研究——哪種審查方式抓到的缺陷比例較高、缺陷在哪個階段被發現的修復成本差幾倍，這類數字它會標出處。要拿數據去支持一個工程實踐的改變時，這本是站上少數能給引用來源的書。&lt;/p>
&lt;p>時效要分層看，而這本的分層特別明顯。&lt;strong>建構期的具體技術&lt;/strong>（那個年代的語言特性、命名慣例、程式碼佈局的爭論）大量過時，讀的時候會一直遇到已經不成立的例子；&lt;strong>它引用的實證研究&lt;/strong>多數停在 2004 年之前，後續二十年的研究沒有納入；而&lt;strong>它整理問題的方式&lt;/strong>——把每個建構決定拆成有哪些選項、各自的取捨是什麼——不依賴那些例子，那才是現在讀它的理由。&lt;/p>
&lt;p>證據來源是理論建構（把當時的實證文獻與實務歸納整理成對照表）加上單一路徑的個人經驗，是這個主題裡唯一有系統引用實證研究的一本。這本不適合通讀，適合遇到具體問題時當工具書查——需要的是查閱的耐心，經驗門檻反而不高。繁體中文版譯名《CODE COMPLETE 2 中文版：軟體開發實務指南》。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670">Amazon（Code Complete, Second Edition）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.books.com.tw/products/0010805887">博客來（CODE COMPLETE 2 中文版：軟體開發實務指南，第二版）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="為什麼只收這幾本">為什麼只收這幾本&lt;/h2>
&lt;p>同樣回答「怎麼寫得更好」，這三本的密度差一個量級：Pragmatic Programmer 廣而每條短，A Philosophy of Software Design 窄而挖到底，Code Complete 大而全。手上的問題越具體越往《A Philosophy of Software Design》走，想建立通盤基礎才輪到《Code Complete》。&lt;/p>
&lt;p>技藝類的書市極擁擠，而多數集中在兩個位置：特定語言的最佳實踐彙編，以及把某一套規則推銷成普適判準的書。前者屬於教學系列而非書單的責任範圍，後者的問題是規則脫離了推導它的取捨——分辨的方法是看它有沒有講清楚什麼情況下這條規則不適用，只給規則不給邊界的表示它把判斷收走了。&lt;/p>
&lt;p>Robert Martin 的《Clean Code》常被列在這個位置，本書單未評估它。它的部分主張（函式應該極短、註解是失敗的象徵）在近年受到相當多的技術批評，而判斷那些批評成不成立需要逐條對照原文與反方論證，這裡沒有做。要讀的話值得同時找反方的討論一起看，不要當成無爭議的標準。&lt;/p>
&lt;p>離收得進來最近的一門課是 MIT 的 6.005 Software Construction。大綱涵蓋規格、測試、抽象資料型別、物件導向設計模式、並行與函數式程式設計，跟本篇三本書重疊得最多，OpenCourseWare 上也放了考題、習題與程式作業——差的只有影音，而成因是那門課刻意不把課堂時間拿來講課（FAQ 自陳），因此沒有可錄的講課。&lt;strong>這不代表設計判準拍不出來&lt;/strong>，理由寫在 &lt;a href="../">工程技藝書單&lt;/a> 的公開課段。&lt;/p>
&lt;h2 id="這個主題接到哪裡">這個主題接到哪裡&lt;/h2>
&lt;p>設計判準要在既有程式碼上生效，靠的是改動的技術：手上有測試時怎麼移動結構、沒有測試時怎麼先弄出測試、以及小改動要不要現在做。那條路徑走 &lt;a href="../changing-existing-code/">改既有的程式&lt;/a>。&lt;/p>
&lt;p>寫得好而團隊切錯時，交付一樣會卡，那條路徑走 &lt;a href="../../software-management/topics/team-design/">組織結構與團隊設計&lt;/a>。想知道自己在職涯位置上該補什麼，走 &lt;a href="../../software-management/roles/">依位置選書&lt;/a>。&lt;/p>
&lt;p>各語言的具體寫法與慣例看 &lt;a href="https://tarrragon.github.io/blog/python/" data-link-title="Python 維護工程師實戰指南" data-link-desc="以 Hook 系統為範例的 Python 開發教學">Python 維護指南&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/go/" data-link-title="Go 入門實戰指南" data-link-desc="理解 Go 語言精神與核心開發能力">Go 維護指南&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/flutter/" data-link-title="Flutter 實戰指南" data-link-desc="Flutter 與 Dart 的實作層教材：型別設計與語言機制、狀態與渲染、測試策略、工具鏈，從實際專案 case 抽出判準。">Flutter 實戰指南&lt;/a>；測試怎麼分層與設計看 &lt;a href="https://tarrragon.github.io/blog/testing/" data-link-title="開發測試實務指南" data-link-desc="測試全過而實機全壞、或程式碼由 agent 產出而無法逐行讀時，用來決定驗證該掛在哪幾層、每一層各自守不住什麼">Testing 測試策略&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>這個主題處理兩件在日常裡分不開的事：把程式寫成之後改得動的樣子，以及讓那件事持續發生的工作習慣。它們分不開的理由是設計判準要靠習慣才生效——知道模組該小、介面該深，跟每次動手時真的去想這件事，中間隔著一整套日常做法。</p>
<p>三本書的差別在<strong>密度與主張數</strong>，不在誰對誰錯：《The Pragmatic Programmer》列幾十條短原則、《A Philosophy of Software Design》用一條主張貫穿全書、《Code Complete》鋪成百科式的對照表。手上的問題越具體，越適合主張集中的《A Philosophy of Software Design》；想建立通盤基礎，才輪得到百科式的《Code Complete》。</p>
<p>處境相容性這一項三本都查過，都沒有列出限制。它們的判準落在程式碼本身的形狀與個人的動手習慣上，成立與否不取決於組織有沒有職級制度、成員是不是同一個僱主、大家在不在同一個時區，也不受事故追責義務左右。這是全批唯一每一本都查過、而且每一本都沒有依賴的一篇——同一條技藝線上的另外三篇不是這樣，架構、驗證與改既有程式那三篇各自都有書預設了特定的組織條件。</p>
<h2 id="起點是-the-pragmatic-programmer">起點是 The Pragmatic Programmer</h2>
<p>Dave Thomas 與 Andy Hunt 的《The Pragmatic Programmer》把技藝拆成幾十條自成一段、互不依賴的實踐——從 DRY、正交性這種設計判準，到版本控制、純文字、自動化這種工具習慣，再到知識組合、除錯紀律這種職業態度——任何一條都可以單獨拿走用。條目多而彼此不相依，是它在本篇管得最寬、因此當起點的原因。</p>
<p>它最常被引用的是 DRY，而它的原文比多數轉述嚴格：系統裡的每一項知識都必須有單一、明確、權威的表述。這句話管的不只是程式碼——業務規則、設定值、資料定義同樣算，而多數 DRY 的誤用是把它讀成「不要複製貼上」，於是把兩段長得像但會各自變動的程式硬合併，製造出更難改的耦合。</p>
<p>另一條沒有被廣泛轉述的是曳光彈（tracer bullets）：先打通一條從頭到尾都會動的最細路徑，再逐段加厚。它跟原型的差別在於曳光彈的程式碼會留下來成為骨架，原型是用完就丟——搞混這兩者的團隊會把探索用的臨時程式碼帶進生產。</p>
<p>20 週年版是大幅改寫過的，不是加註解的重印本，並補進了並行、actor model、property-based testing 與資安基礎。要買就買這一版。時效上，第一版綁的工具與環境（CVS、特定編輯器）在改版時清掉了；DRY、正交性、曳光彈、破窗理論這些主張不依賴任何工具世代。</p>
<p><a href="/blog/books/knowledge-cards/evidence-provenance/" data-link-title="證據來源分類（evidence provenance）" data-link-desc="手上兩本書講同一件事而結論不同、或要拿一本書去支持一個實際決定時，用來判斷它支持得了多大範圍的決定">證據來源</a>是跨客戶的顧問經驗，形式是格言加短例而非資料——這也決定了它的用法：拿來當檢查表對照自己的習慣，而不是拿去說服別人。</p>
<p>這本書幾乎不需要前置準備，入行第一年就可以讀；而且每隔幾年重讀會讀出不同的東西，因為同一條原則在不同經驗量下對得上的情境不一樣。</p>
<ul>
<li><a href="https://www.amazon.com/Pragmatic-Programmer-journey-mastery-Anniversary/dp/0135957052">Amazon（The Pragmatic Programmer, 20th Anniversary Edition）</a></li>
<li><a href="https://www.books.com.tw/products/0010856354">博客來（The Pragmatic Programmer 20 週年紀念版）</a></li>
</ul>
<h2 id="想把設計問題想清楚時讀-a-philosophy-of-software-design">想把設計問題想清楚時讀 A Philosophy of Software Design</h2>
<p>John Ousterhout 的這本整本只推一個主張：<strong>軟體設計的根本問題是控制複雜度</strong>，其餘的判準都從這一條長出來。這種寫法的好處是它給得出一個可以隨身帶的判準，而不是一份要背的清單。</p>
<p>書中最可操作的是深模組（deep module）這個概念：好的模組是介面小而實作厚，壞的模組是介面跟實作一樣大。這條判準直接推翻了「函式應該盡量短」這種常見指導——把一個模組切成十個各自很淺的函式，介面總量反而變大，複雜度是上升的。另一組是紅旗清單（淺模組、資訊洩漏、時序分解、重複、註解重述程式碼），設計時可以逐條掃。</p>
<p>它跟 Pragmatic Programmer 的關係是深度換廣度：那本列出有哪些事該做，這本把其中一件（怎麼切模組）挖到底。兩本一起讀不會重複。</p>
<p>證據來源是單一路徑的個人經驗，而形態特別：素材來自作者多年開設軟體設計課的學生專案觀察，樣本受控但規模小、且偏向課堂專案，這是它跟業界顧問經驗不同的地方。作者是 Tcl 的作者、Stanford 教授。第二版於 2021 年出版，補了更多例子並回應了對第一版的批評。時效上沒有綁定任何工具世代。</p>
<p>讀這本要先有一段維護經驗當對照：維護過自己或別人寫的東西超過半年，經歷過「當初這樣切好像不對」。沒有這個對照時，深模組會讀成一個偏好而不是判準——可以先讀《The Pragmatic Programmer》，等維護經驗累積起來再回來讀這本。</p>
<p>繁體中文版查不到，簡體中文版《軟件設計的哲學》第二版由人民郵電出版社出版。</p>
<ul>
<li><a href="https://www.amazon.com/Philosophy-Software-Design-2nd/dp/173210221X">Amazon（A Philosophy of Software Design, 2nd Edition）</a></li>
<li><a href="https://www.tenlong.com.tw/products/9787115655615">天瓏（軟件設計的哲學 2/e，簡體中文版）</a></li>
</ul>
<h2 id="要一份百科式的對照時讀-code-complete">要一份百科式的對照時讀 Code Complete</h2>
<p>Steve McConnell 的《Code Complete》第二版是這個主題涵蓋面最大的一本，把建構期的每個決定都拆開處理：變數命名、迴圈結構、防禦性編程、程式碼佈局、審查方式。它跟前兩本的差別在於它不推銷單一主張，而是把當時能找到的研究與實務歸納整理成對照表。</p>
<p>它的獨特之處是引用密度。多數技藝書的主張來自作者經驗，這本大量引用了實證研究——哪種審查方式抓到的缺陷比例較高、缺陷在哪個階段被發現的修復成本差幾倍，這類數字它會標出處。要拿數據去支持一個工程實踐的改變時，這本是站上少數能給引用來源的書。</p>
<p>時效要分層看，而這本的分層特別明顯。<strong>建構期的具體技術</strong>（那個年代的語言特性、命名慣例、程式碼佈局的爭論）大量過時，讀的時候會一直遇到已經不成立的例子；<strong>它引用的實證研究</strong>多數停在 2004 年之前，後續二十年的研究沒有納入；而<strong>它整理問題的方式</strong>——把每個建構決定拆成有哪些選項、各自的取捨是什麼——不依賴那些例子，那才是現在讀它的理由。</p>
<p>證據來源是理論建構（把當時的實證文獻與實務歸納整理成對照表）加上單一路徑的個人經驗，是這個主題裡唯一有系統引用實證研究的一本。這本不適合通讀，適合遇到具體問題時當工具書查——需要的是查閱的耐心，經驗門檻反而不高。繁體中文版譯名《CODE COMPLETE 2 中文版：軟體開發實務指南》。</p>
<ul>
<li><a href="https://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670">Amazon（Code Complete, Second Edition）</a></li>
<li><a href="https://www.books.com.tw/products/0010805887">博客來（CODE COMPLETE 2 中文版：軟體開發實務指南，第二版）</a></li>
</ul>
<h2 id="為什麼只收這幾本">為什麼只收這幾本</h2>
<p>同樣回答「怎麼寫得更好」，這三本的密度差一個量級：Pragmatic Programmer 廣而每條短，A Philosophy of Software Design 窄而挖到底，Code Complete 大而全。手上的問題越具體越往《A Philosophy of Software Design》走，想建立通盤基礎才輪到《Code Complete》。</p>
<p>技藝類的書市極擁擠，而多數集中在兩個位置：特定語言的最佳實踐彙編，以及把某一套規則推銷成普適判準的書。前者屬於教學系列而非書單的責任範圍，後者的問題是規則脫離了推導它的取捨——分辨的方法是看它有沒有講清楚什麼情況下這條規則不適用，只給規則不給邊界的表示它把判斷收走了。</p>
<p>Robert Martin 的《Clean Code》常被列在這個位置，本書單未評估它。它的部分主張（函式應該極短、註解是失敗的象徵）在近年受到相當多的技術批評，而判斷那些批評成不成立需要逐條對照原文與反方論證，這裡沒有做。要讀的話值得同時找反方的討論一起看，不要當成無爭議的標準。</p>
<p>離收得進來最近的一門課是 MIT 的 6.005 Software Construction。大綱涵蓋規格、測試、抽象資料型別、物件導向設計模式、並行與函數式程式設計，跟本篇三本書重疊得最多，OpenCourseWare 上也放了考題、習題與程式作業——差的只有影音，而成因是那門課刻意不把課堂時間拿來講課（FAQ 自陳），因此沒有可錄的講課。<strong>這不代表設計判準拍不出來</strong>，理由寫在 <a href="../">工程技藝書單</a> 的公開課段。</p>
<h2 id="這個主題接到哪裡">這個主題接到哪裡</h2>
<p>設計判準要在既有程式碼上生效，靠的是改動的技術：手上有測試時怎麼移動結構、沒有測試時怎麼先弄出測試、以及小改動要不要現在做。那條路徑走 <a href="../changing-existing-code/">改既有的程式</a>。</p>
<p>寫得好而團隊切錯時，交付一樣會卡，那條路徑走 <a href="../../software-management/topics/team-design/">組織結構與團隊設計</a>。想知道自己在職涯位置上該補什麼，走 <a href="../../software-management/roles/">依位置選書</a>。</p>
<p>各語言的具體寫法與慣例看 <a href="/blog/python/" data-link-title="Python 維護工程師實戰指南" data-link-desc="以 Hook 系統為範例的 Python 開發教學">Python 維護指南</a>、<a href="/blog/go/" data-link-title="Go 入門實戰指南" data-link-desc="理解 Go 語言精神與核心開發能力">Go 維護指南</a>、<a href="/blog/flutter/" data-link-title="Flutter 實戰指南" data-link-desc="Flutter 與 Dart 的實作層教材：型別設計與語言機制、狀態與渲染、測試策略、工具鏈，從實際專案 case 抽出判準。">Flutter 實戰指南</a>；測試怎麼分層與設計看 <a href="/blog/testing/" data-link-title="開發測試實務指南" data-link-desc="測試全過而實機全壞、或程式碼由 agent 產出而無法逐行讀時，用來決定驗證該掛在哪幾層、每一層各自守不住什麼">Testing 測試策略</a>。</p>
]]></content:encoded></item><item><title>工程技藝書單</title><link>https://tarrragon.github.io/blog/books/craft/</link><pubDate>Wed, 19 Aug 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/books/craft/</guid><description>&lt;p>這條線處理的是&lt;strong>一個人怎麼把軟體寫好、改好、維持得住&lt;/strong>。它跟 &lt;a href="../software-management/">軟體管理與組織&lt;/a> 的分界在決定的對象：那條線的決定落在人與制度上，這條線的決定落在產物上。分界不落在「有沒有離開編輯器」——系統架構那篇的取捨要跨越團隊、資料與既有承諾，代價有一半落在組織上，但被決定的仍然是系統長什麼形狀。另有一條線 &lt;a href="../finance/">財務與投資&lt;/a> 的決定落在自己的錢上，跟這裡不共用讀者位置。各線為什麼按這個軸分開，說明在 &lt;a href="https://tarrragon.github.io/blog/books/" data-link-title="書單推薦" data-link-desc="站在某個職涯位置、想知道該讀哪本工具書，想往別的位置移動而不知道該預習什麼，或因為閱讀障礙與外語閱讀速度而需要同一份知識換成用聽的時看這裡">書單推薦&lt;/a> 的「書單線」段。&lt;/p>
&lt;p>書的描述沿用同一套維度（&lt;a href="https://tarrragon.github.io/blog/books/knowledge-cards/evidence-provenance/" data-link-title="證據來源分類（evidence provenance）" data-link-desc="手上兩本書講同一件事而結論不同、或要拿一本書去支持一個實際決定時，用來判斷它支持得了多大範圍的決定">證據來源&lt;/a>、時效狀態、&lt;a href="https://tarrragon.github.io/blog/books/knowledge-cards/context-compatibility/" data-link-title="處境相容性（context compatibility）" data-link-desc="一本書或一套做法讀起來都對、換算到自己的組織卻沒有一條動得了時，用來定位缺的是哪一個環境條件">處境相容性&lt;/a>、讀得出價值的前提），定義與這些判定的來源說明在 &lt;a href="https://tarrragon.github.io/blog/books/" data-link-title="書單推薦" data-link-desc="站在某個職涯位置、想知道該讀哪本工具書，想往別的位置移動而不知道該預習什麼，或因為閱讀障礙與外語閱讀速度而需要同一份知識換成用聽的時看這裡">書單推薦&lt;/a>。這四篇的起點書用的也是同一組判準（涵蓋面優先、其次證據來源夠不夠支持那個用途、再其次可操作性），判準寫在 &lt;a href="../software-management/topics/">主題書單&lt;/a> 的「起點書怎麼選出來的」段。驗證那篇是唯一的例外：它的起點取 Beck，理由是後面兩本都在跟它對話，那條「歷史先行性」不在三層判準裡。&lt;/p>
&lt;h2 id="這條線特別要注意時效">這條線特別要注意時效&lt;/h2>
&lt;p>技藝類的書比管理類更容易局部過時，因為它們的例子綁在語言、工具與當時的工程環境上。判斷方式不變——問這一段的論證依賴什麼前提——但套用時要多分一層：&lt;strong>主張本身&lt;/strong>（模組該怎麼切、重複意味著什麼）通常比&lt;strong>示範它的程式碼&lt;/strong>活得久。看到過時的語法不要連著把主張一起丟掉，那是這類書最常見的誤判。&lt;/p>
&lt;p>反過來也成立：一本書的示範用了最新的語言特性，不代表它的主張比較新。&lt;/p>
&lt;h2 id="主題">主題&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>主題&lt;/th>
 &lt;th>承擔的問題&lt;/th>
 &lt;th>起點書&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="design-and-practice/">設計判準與日常實踐&lt;/a>&lt;/td>
 &lt;td>怎麼寫出改得動的程式、日常工作該有哪些習慣&lt;/td>
 &lt;td>The Pragmatic Programmer&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="changing-existing-code/">改既有的程式&lt;/a>&lt;/td>
 &lt;td>要動一段自己沒寫的、或沒有測試保護的程式碼&lt;/td>
 &lt;td>Refactoring&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="system-architecture/">系統架構&lt;/a>&lt;/td>
 &lt;td>整個系統該長什麼形狀、拆分時每個選項的代價&lt;/td>
 &lt;td>Fundamentals of Software Architecture&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="verification/">驗證自己寫對了&lt;/a>&lt;/td>
 &lt;td>該測到什麼程度、這裡到底該不該 mock&lt;/td>
 &lt;td>Test-Driven Development: By Example&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="三個主題其實是同一組概念在三個尺度上運作">三個主題其實是同一組概念在三個尺度上運作&lt;/h2>
&lt;p>這條線有四個主題，其中三個排在同一道刻度上。耦合與內聚這兩個概念貫穿它們，只是作用的範圍不同。Kent Beck 用它們算「這幾行現在要不要整理」，Ousterhout 用它們判斷「這個模組的介面該多深」，Richards 與 Ford 在元件層用同一組概念談切分與粒度。三個主題不是三種學問，是同一把尺在三個刻度上讀。這道刻度上的三本跟各篇的起點書只有一本重疊：架構那一層兩者都是 Richards 與 Ford，另外兩層不同——照起點書走的讀者在最小尺度落到的是 Fowler 而不是 Beck，在模組尺度落到的是 Pragmatic Programmer 而不是 Ousterhout。那兩本各自是所屬主題涵蓋面最廣的入口，而不是這把尺的刻度。要看這把尺，最小與模組兩層直接取 Beck 與 Ousterhout。&lt;/p>
&lt;p>知道這件事有一個實用後果：&lt;strong>換尺度是一種可以主動做的判斷&lt;/strong>。同一類問題反覆出現而每次都在原尺度處理，通常代表問題不在那一層——整理這段程式碼整理了五次而它還是難改，該往上看模組邊界；模組怎麼切都不對，該往上看系統的責任分配；而系統怎麼切都有人抱怨，那可能已經不是技術問題，走 &lt;a href="../software-management/topics/team-design/">組織結構與團隊設計&lt;/a>。&lt;/p>
&lt;p>反過來也成立。架構圖畫得再乾淨，落到每次修改仍然要有人決定先整理還是後整理，而那個決定沒有架構層的答案。&lt;/p>
&lt;p>&lt;a href="verification/">驗證自己寫對了&lt;/a> 不在這道刻度上，它是橫跨三個尺度的另一軸——每個尺度都要回答「我怎麼知道自己沒弄壞」，而那個問題在一次修改、模組邊界與系統拆分上會得到不同的答案。&lt;/p>
&lt;h2 id="這條線不做角色分眾">這條線不做角色分眾&lt;/h2>
&lt;p>管理那條線按讀者對什麼負責分成五個位置，這條線刻意不做同樣的事，理由是技藝問題跟職涯位置的相關性遠低於管理問題。&lt;/p>
&lt;p>資深工程師與剛入行的人在重構同一段程式碼時，需要的是同一本書；差別在讀得出多少，而那個差別已經寫在每本書的「讀得出價值的前提」裡，不需要再開一層路由承接。更根本的是這條線的主題本身就是分眾機制——讀者依當下在做什麼自己選尺度（我正在改這幾行、我在切模組、我在決定系統形狀），而那個選擇比職稱準確得多：同一個人在同一週可能三個尺度都碰到。&lt;/p>
&lt;p>因此這條線的入口是主題表，不是位置表。要按職涯位置選書的讀者，那條路在 &lt;a href="../software-management/roles/">依位置選書&lt;/a>，而那五篇也會在需要技藝內容時指過來。&lt;/p>
&lt;h2 id="四個主題裡只有系統架構接得住公開課">四個主題裡只有系統架構接得住公開課&lt;/h2>
&lt;p>讀不動長篇文字時，同一份知識的影音路徑由公開課承接，收錄門檻寫在 &lt;a href="https://tarrragon.github.io/blog/books/" data-link-title="書單推薦" data-link-desc="站在某個職涯位置、想知道該讀哪本工具書，想往別的位置移動而不知道該預習什麼，或因為閱讀障礙與外語閱讀速度而需要同一份知識換成用聽的時看這裡">書單推薦&lt;/a> 的「公開課怎麼收」段。這條線套用那兩條之後，接得住的只有 &lt;a href="system-architecture/">系統架構&lt;/a>，另外三個主題都沒查到，而它們空著的理由各自不同，寫在各篇的「為什麼只收這幾本」段內。這條線與 &lt;a href="../finance/">財務與投資&lt;/a> 的差別在沒查到的主題數：那條線四篇都有課，所以它不需要這樣一段線層說明，各篇自己交代就夠。&lt;/p>
&lt;p>那三個主題的共同點只到觀察為止：跟它們最相關的學院課都只有文字材料。這裡不往下推論知識類型，因為最順的那個推論站不住。順的推論是「判準沒有可以對答案的形式，所以進不了以作業與考試為骨架的課程」，而 MIT 的 6.005 Software Construction 直接否證它——大綱涵蓋規格、測試、抽象資料型別、物件導向設計模式、並行與函數式程式設計，跟這條線的設計判準重疊得最多，而它在 OpenCourseWare 上放的資源是考題、考題解答、習題與程式作業，判準出得了題也評得了分。它缺的只有影片，成因與知識類型無關：課程的 FAQ 自陳刻意不把課堂時間花在講課上，改成課前讀、課堂做練習，於是沒有可錄的講課。&lt;/p>
&lt;p>更廣的反例在同一所學校：Sloan 的 15.401 Finance Theory I（2008）與 15.S50 Poker Theory and Analytics（2015）都有完整的 lecture videos，可見同院同期的判斷型題材拍得出來。所以能說的只有結果——對讀不動文字的人，這三個主題目前沒有影音路徑——而成因逐篇不同，寫在各篇自己的收錄段。管理線那邊把同一件事分成三類成因（見 &lt;a href="../software-management/topics/">主題書單&lt;/a> 的公開課段），這條線對得上其中兩類：設計判準是「學院有課、只是沒有影片」，驗證是「市場供給充足而形態不對」；改既有的程式對不上任何一類，那正是這裡不往下推論的部分。&lt;/p>
&lt;p>市場那一側的供給充足而問的問題不同。以軟體測試或軟體工程為題的公開課數量不少，2026 年 8 月這一輪查到的多半是職涯訓練與面試準備，它們交付的是怎麼當一個測試工程師；驗證那一篇要交付的是三本書彼此不同意在哪。驗證那個主題因此不是被本質恆定那一條擋下來的——它是搜到的那些課與該主題不在同一層，逐篇的說明在各篇自己的收錄段。&lt;/p>
&lt;p>中文側的落差落在更前面一段。台大開放式課程的 &lt;a href="https://ocw.aca.ntu.edu.tw/courses/111S107">程式設計&lt;/a>（孔令傑，資訊管理學系，15 講，C++）教的是寫得出程式，課程頁自陳不預設任何程式背景，目標是讓學生之後能自學任何一種語言；這條線的四本起點書都預設讀者已經寫過一陣子程式，所以它落在這條線的入口之前而不在線上。程式經驗還沒建立起來的讀者從那裡開始，&lt;a href="https://www.youtube.com/playlist?list=PLCX-BLZ1hDpBuSFO8-TtF_q5QlBfeb6Q0">YouTube 播放清單&lt;/a> 有全部 15 講。&lt;/p>
&lt;h2 id="跟教學系列的邊界">跟教學系列的邊界&lt;/h2>
&lt;p>書單給選讀判斷，實作在教學系列：各語言的寫法與慣例看 &lt;a href="https://tarrragon.github.io/blog/python/" data-link-title="Python 維護工程師實戰指南" data-link-desc="以 Hook 系統為範例的 Python 開發教學">Python&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/go/" data-link-title="Go 入門實戰指南" data-link-desc="理解 Go 語言精神與核心開發能力">Go&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/flutter/" data-link-title="Flutter 實戰指南" data-link-desc="Flutter 與 Dart 的實作層教材：型別設計與語言機制、狀態與渲染、測試策略、工具鏈，從實際專案 case 抽出判準。">Flutter&lt;/a>，測試分層與 mock 判斷看 &lt;a href="https://tarrragon.github.io/blog/testing/" data-link-title="開發測試實務指南" data-link-desc="測試全過而實機全壞、或程式碼由 agent 產出而無法逐行讀時，用來決定驗證該掛在哪幾層、每一層各自守不住什麼">Testing 測試策略&lt;/a>，領域模型的切法看 &lt;a href="https://tarrragon.github.io/blog/ddd/" data-link-title="DDD 領域驅動設計指南" data-link-desc="領域模型的理論與判準層：一袋欄位還是領域模型、什麼時候值得建 entity、不變式該落在哪一層強制、狀態轉換怎麼留下稽核軌跡、建構路徑怎麼設計。語言無關，實作限制路由到各語言模組。">DDD 領域驅動設計指南&lt;/a>。&lt;/p>
&lt;h2 id="backlog">Backlog&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>項目&lt;/th>
 &lt;th>類型&lt;/th>
 &lt;th>前置條件&lt;/th>
 &lt;th>規模&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Open Yale Courses 四十門逐門判定&lt;/td>
 &lt;td>案例&lt;/td>
 &lt;td>該站規模可窮盡，這一輪只按主題名取用；逐門過完才能把「沒查到」升級成「枚舉後沒有」&lt;/td>
 &lt;td>1 次&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>沒查到課的三個主題重掃一次&lt;/td>
 &lt;td>案例&lt;/td>
 &lt;td>2027 年 8 月之後重跑，判準是本質恆定加實際有影音&lt;/td>
 &lt;td>1 次&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>設計判準這個主題改判&lt;/td>
 &lt;td>主章&lt;/td>
 &lt;td>MIT 6.005 補上影音，或找到另一門教設計判準而有影音的課；沒有人會主動去看，實際觸發點是 2027 年那次重掃&lt;/td>
 &lt;td>1 段&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table></description><content:encoded><![CDATA[<p>這條線處理的是<strong>一個人怎麼把軟體寫好、改好、維持得住</strong>。它跟 <a href="../software-management/">軟體管理與組織</a> 的分界在決定的對象：那條線的決定落在人與制度上，這條線的決定落在產物上。分界不落在「有沒有離開編輯器」——系統架構那篇的取捨要跨越團隊、資料與既有承諾，代價有一半落在組織上，但被決定的仍然是系統長什麼形狀。另有一條線 <a href="../finance/">財務與投資</a> 的決定落在自己的錢上，跟這裡不共用讀者位置。各線為什麼按這個軸分開，說明在 <a href="/blog/books/" data-link-title="書單推薦" data-link-desc="站在某個職涯位置、想知道該讀哪本工具書，想往別的位置移動而不知道該預習什麼，或因為閱讀障礙與外語閱讀速度而需要同一份知識換成用聽的時看這裡">書單推薦</a> 的「書單線」段。</p>
<p>書的描述沿用同一套維度（<a href="/blog/books/knowledge-cards/evidence-provenance/" data-link-title="證據來源分類（evidence provenance）" data-link-desc="手上兩本書講同一件事而結論不同、或要拿一本書去支持一個實際決定時，用來判斷它支持得了多大範圍的決定">證據來源</a>、時效狀態、<a href="/blog/books/knowledge-cards/context-compatibility/" data-link-title="處境相容性（context compatibility）" data-link-desc="一本書或一套做法讀起來都對、換算到自己的組織卻沒有一條動得了時，用來定位缺的是哪一個環境條件">處境相容性</a>、讀得出價值的前提），定義與這些判定的來源說明在 <a href="/blog/books/" data-link-title="書單推薦" data-link-desc="站在某個職涯位置、想知道該讀哪本工具書，想往別的位置移動而不知道該預習什麼，或因為閱讀障礙與外語閱讀速度而需要同一份知識換成用聽的時看這裡">書單推薦</a>。這四篇的起點書用的也是同一組判準（涵蓋面優先、其次證據來源夠不夠支持那個用途、再其次可操作性），判準寫在 <a href="../software-management/topics/">主題書單</a> 的「起點書怎麼選出來的」段。驗證那篇是唯一的例外：它的起點取 Beck，理由是後面兩本都在跟它對話，那條「歷史先行性」不在三層判準裡。</p>
<h2 id="這條線特別要注意時效">這條線特別要注意時效</h2>
<p>技藝類的書比管理類更容易局部過時，因為它們的例子綁在語言、工具與當時的工程環境上。判斷方式不變——問這一段的論證依賴什麼前提——但套用時要多分一層：<strong>主張本身</strong>（模組該怎麼切、重複意味著什麼）通常比<strong>示範它的程式碼</strong>活得久。看到過時的語法不要連著把主張一起丟掉，那是這類書最常見的誤判。</p>
<p>反過來也成立：一本書的示範用了最新的語言特性，不代表它的主張比較新。</p>
<h2 id="主題">主題</h2>
<table>
  <thead>
      <tr>
          <th>主題</th>
          <th>承擔的問題</th>
          <th>起點書</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="design-and-practice/">設計判準與日常實踐</a></td>
          <td>怎麼寫出改得動的程式、日常工作該有哪些習慣</td>
          <td>The Pragmatic Programmer</td>
      </tr>
      <tr>
          <td><a href="changing-existing-code/">改既有的程式</a></td>
          <td>要動一段自己沒寫的、或沒有測試保護的程式碼</td>
          <td>Refactoring</td>
      </tr>
      <tr>
          <td><a href="system-architecture/">系統架構</a></td>
          <td>整個系統該長什麼形狀、拆分時每個選項的代價</td>
          <td>Fundamentals of Software Architecture</td>
      </tr>
      <tr>
          <td><a href="verification/">驗證自己寫對了</a></td>
          <td>該測到什麼程度、這裡到底該不該 mock</td>
          <td>Test-Driven Development: By Example</td>
      </tr>
  </tbody>
</table>
<h2 id="三個主題其實是同一組概念在三個尺度上運作">三個主題其實是同一組概念在三個尺度上運作</h2>
<p>這條線有四個主題，其中三個排在同一道刻度上。耦合與內聚這兩個概念貫穿它們，只是作用的範圍不同。Kent Beck 用它們算「這幾行現在要不要整理」，Ousterhout 用它們判斷「這個模組的介面該多深」，Richards 與 Ford 在元件層用同一組概念談切分與粒度。三個主題不是三種學問，是同一把尺在三個刻度上讀。這道刻度上的三本跟各篇的起點書只有一本重疊：架構那一層兩者都是 Richards 與 Ford，另外兩層不同——照起點書走的讀者在最小尺度落到的是 Fowler 而不是 Beck，在模組尺度落到的是 Pragmatic Programmer 而不是 Ousterhout。那兩本各自是所屬主題涵蓋面最廣的入口，而不是這把尺的刻度。要看這把尺，最小與模組兩層直接取 Beck 與 Ousterhout。</p>
<p>知道這件事有一個實用後果：<strong>換尺度是一種可以主動做的判斷</strong>。同一類問題反覆出現而每次都在原尺度處理，通常代表問題不在那一層——整理這段程式碼整理了五次而它還是難改，該往上看模組邊界；模組怎麼切都不對，該往上看系統的責任分配；而系統怎麼切都有人抱怨，那可能已經不是技術問題，走 <a href="../software-management/topics/team-design/">組織結構與團隊設計</a>。</p>
<p>反過來也成立。架構圖畫得再乾淨，落到每次修改仍然要有人決定先整理還是後整理，而那個決定沒有架構層的答案。</p>
<p><a href="verification/">驗證自己寫對了</a> 不在這道刻度上，它是橫跨三個尺度的另一軸——每個尺度都要回答「我怎麼知道自己沒弄壞」，而那個問題在一次修改、模組邊界與系統拆分上會得到不同的答案。</p>
<h2 id="這條線不做角色分眾">這條線不做角色分眾</h2>
<p>管理那條線按讀者對什麼負責分成五個位置，這條線刻意不做同樣的事，理由是技藝問題跟職涯位置的相關性遠低於管理問題。</p>
<p>資深工程師與剛入行的人在重構同一段程式碼時，需要的是同一本書；差別在讀得出多少，而那個差別已經寫在每本書的「讀得出價值的前提」裡，不需要再開一層路由承接。更根本的是這條線的主題本身就是分眾機制——讀者依當下在做什麼自己選尺度（我正在改這幾行、我在切模組、我在決定系統形狀），而那個選擇比職稱準確得多：同一個人在同一週可能三個尺度都碰到。</p>
<p>因此這條線的入口是主題表，不是位置表。要按職涯位置選書的讀者，那條路在 <a href="../software-management/roles/">依位置選書</a>，而那五篇也會在需要技藝內容時指過來。</p>
<h2 id="四個主題裡只有系統架構接得住公開課">四個主題裡只有系統架構接得住公開課</h2>
<p>讀不動長篇文字時，同一份知識的影音路徑由公開課承接，收錄門檻寫在 <a href="/blog/books/" data-link-title="書單推薦" data-link-desc="站在某個職涯位置、想知道該讀哪本工具書，想往別的位置移動而不知道該預習什麼，或因為閱讀障礙與外語閱讀速度而需要同一份知識換成用聽的時看這裡">書單推薦</a> 的「公開課怎麼收」段。這條線套用那兩條之後，接得住的只有 <a href="system-architecture/">系統架構</a>，另外三個主題都沒查到，而它們空著的理由各自不同，寫在各篇的「為什麼只收這幾本」段內。這條線與 <a href="../finance/">財務與投資</a> 的差別在沒查到的主題數：那條線四篇都有課，所以它不需要這樣一段線層說明，各篇自己交代就夠。</p>
<p>那三個主題的共同點只到觀察為止：跟它們最相關的學院課都只有文字材料。這裡不往下推論知識類型，因為最順的那個推論站不住。順的推論是「判準沒有可以對答案的形式，所以進不了以作業與考試為骨架的課程」，而 MIT 的 6.005 Software Construction 直接否證它——大綱涵蓋規格、測試、抽象資料型別、物件導向設計模式、並行與函數式程式設計，跟這條線的設計判準重疊得最多，而它在 OpenCourseWare 上放的資源是考題、考題解答、習題與程式作業，判準出得了題也評得了分。它缺的只有影片，成因與知識類型無關：課程的 FAQ 自陳刻意不把課堂時間花在講課上，改成課前讀、課堂做練習，於是沒有可錄的講課。</p>
<p>更廣的反例在同一所學校：Sloan 的 15.401 Finance Theory I（2008）與 15.S50 Poker Theory and Analytics（2015）都有完整的 lecture videos，可見同院同期的判斷型題材拍得出來。所以能說的只有結果——對讀不動文字的人，這三個主題目前沒有影音路徑——而成因逐篇不同，寫在各篇自己的收錄段。管理線那邊把同一件事分成三類成因（見 <a href="../software-management/topics/">主題書單</a> 的公開課段），這條線對得上其中兩類：設計判準是「學院有課、只是沒有影片」，驗證是「市場供給充足而形態不對」；改既有的程式對不上任何一類，那正是這裡不往下推論的部分。</p>
<p>市場那一側的供給充足而問的問題不同。以軟體測試或軟體工程為題的公開課數量不少，2026 年 8 月這一輪查到的多半是職涯訓練與面試準備，它們交付的是怎麼當一個測試工程師；驗證那一篇要交付的是三本書彼此不同意在哪。驗證那個主題因此不是被本質恆定那一條擋下來的——它是搜到的那些課與該主題不在同一層，逐篇的說明在各篇自己的收錄段。</p>
<p>中文側的落差落在更前面一段。台大開放式課程的 <a href="https://ocw.aca.ntu.edu.tw/courses/111S107">程式設計</a>（孔令傑，資訊管理學系，15 講，C++）教的是寫得出程式，課程頁自陳不預設任何程式背景，目標是讓學生之後能自學任何一種語言；這條線的四本起點書都預設讀者已經寫過一陣子程式，所以它落在這條線的入口之前而不在線上。程式經驗還沒建立起來的讀者從那裡開始，<a href="https://www.youtube.com/playlist?list=PLCX-BLZ1hDpBuSFO8-TtF_q5QlBfeb6Q0">YouTube 播放清單</a> 有全部 15 講。</p>
<h2 id="跟教學系列的邊界">跟教學系列的邊界</h2>
<p>書單給選讀判斷，實作在教學系列：各語言的寫法與慣例看 <a href="/blog/python/" data-link-title="Python 維護工程師實戰指南" data-link-desc="以 Hook 系統為範例的 Python 開發教學">Python</a>、<a href="/blog/go/" data-link-title="Go 入門實戰指南" data-link-desc="理解 Go 語言精神與核心開發能力">Go</a>、<a href="/blog/flutter/" data-link-title="Flutter 實戰指南" data-link-desc="Flutter 與 Dart 的實作層教材：型別設計與語言機制、狀態與渲染、測試策略、工具鏈，從實際專案 case 抽出判準。">Flutter</a>，測試分層與 mock 判斷看 <a href="/blog/testing/" data-link-title="開發測試實務指南" data-link-desc="測試全過而實機全壞、或程式碼由 agent 產出而無法逐行讀時，用來決定驗證該掛在哪幾層、每一層各自守不住什麼">Testing 測試策略</a>，領域模型的切法看 <a href="/blog/ddd/" data-link-title="DDD 領域驅動設計指南" data-link-desc="領域模型的理論與判準層：一袋欄位還是領域模型、什麼時候值得建 entity、不變式該落在哪一層強制、狀態轉換怎麼留下稽核軌跡、建構路徑怎麼設計。語言無關，實作限制路由到各語言模組。">DDD 領域驅動設計指南</a>。</p>
<h2 id="backlog">Backlog</h2>
<table>
  <thead>
      <tr>
          <th>項目</th>
          <th>類型</th>
          <th>前置條件</th>
          <th>規模</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Open Yale Courses 四十門逐門判定</td>
          <td>案例</td>
          <td>該站規模可窮盡，這一輪只按主題名取用；逐門過完才能把「沒查到」升級成「枚舉後沒有」</td>
          <td>1 次</td>
      </tr>
      <tr>
          <td>沒查到課的三個主題重掃一次</td>
          <td>案例</td>
          <td>2027 年 8 月之後重跑，判準是本質恆定加實際有影音</td>
          <td>1 次</td>
      </tr>
      <tr>
          <td>設計判準這個主題改判</td>
          <td>主章</td>
          <td>MIT 6.005 補上影音，或找到另一門教設計判準而有影音的課；沒有人會主動去看，實際觸發點是 2027 年那次重掃</td>
          <td>1 段</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>改既有的程式</title><link>https://tarrragon.github.io/blog/books/craft/changing-existing-code/</link><pubDate>Wed, 19 Aug 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/books/craft/changing-existing-code/</guid><description>&lt;p>改既有的程式跟寫新的程式是兩種活。寫新的時候形狀由動手的人決定；改既有的時候形狀已經定了，動它的前提是不弄壞任何人依賴的行為。這件事的難度不由程式碼的複雜度決定，由&lt;strong>有沒有辦法知道自己弄壞了什麼&lt;/strong>決定——同一段程式，有測試時的改法跟沒測試時的改法完全不同。&lt;/p>
&lt;p>三本書按這條線分：有測試時怎麼做（Fowler 的《Refactoring》）、沒測試時怎麼先弄出測試（Feathers 的《Working Effectively with Legacy Code》）、以及改動小到不值得開專案時怎麼決定要不要現在做（Beck 的《Tidy First?》）。&lt;/p>
&lt;h2 id="起點是-refactoring">起點是 Refactoring&lt;/h2>
&lt;p>Martin Fowler 的《Refactoring》把這個主題編成一份目錄，第二版收了六十幾項具名重構，每一項都有動機、機制與範例——編成目錄這件事本身就是它涵蓋面最完整的原因，因為漏掉的手法在目錄裡是看得出來的。它同時定義了這個詞：重構是改變程式碼的內部結構而不改變其外部行為——這個定義比日常用法嚴格得多，而多數把「重構」用在大改寫上的溝通混亂都來自忽略後半句。&lt;/p>
&lt;p>&lt;strong>IDE 自動化之後這本書的價值在哪，是讀它之前最該想清楚的事。&lt;/strong> 目錄裡多數手法現在是一個快捷鍵：Extract Function、Rename、Move Method 都由工具代勞，而書裡那些「先做這步、再做這步、每步跑測試」的手動安全程序，實務上不會有人照著做。看到這裡就把整本書跳過是常見的誤判。&lt;/p>
&lt;p>被自動化的是機械步驟，沒有被自動化的是判斷：這段程式碼該不該提取、提取到哪一層、什麼訊號代表現在該動它。目錄的用途因此從「怎麼安全地手動做」轉成&lt;strong>一套共同詞彙&lt;/strong>——說得出「這裡要做的是 Replace Conditional with Polymorphism」的時候，審查討論的單位就從「我覺得這樣比較好」變成一個有明確前後狀態的動作。書中的程式碼異味清單（Code Smell）是這套詞彙的另一半，它命名的是動手的理由。&lt;/p>
&lt;p>版本要選：第二版（2018）把範例從 Java 換成 JavaScript，並補了不用 class 的函式式範例。這對讀者是真的取捨——寫 Java 的人第一版的範例反而貼近，而第二版的目錄本身有更新。時效上，被工具取代的是機械步驟而不是判斷——目錄裡多數手法現在是 IDE 的一個快捷鍵，那一層已經過時；命名這些動作的詞彙、以及判斷「現在該不該動它」的異味清單不依賴任何工具世代。&lt;a href="https://tarrragon.github.io/blog/books/knowledge-cards/evidence-provenance/" data-link-title="證據來源分類（evidence provenance）" data-link-desc="手上兩本書講同一件事而結論不同、或要拿一本書去支持一個實際決定時，用來判斷它支持得了多大範圍的決定">證據來源&lt;/a>是跨客戶的顧問經驗（作者與貢獻者群的實務歸納），形式是目錄而非論證。&lt;/p>
&lt;p>這本要有一段程式碼在手上才讀得動——自己想改、但不確定怎麼下手的那種。沒有那段程式碼在手上，翻目錄的動作會停在「原來這叫 Extract Function」，而目錄真正的用法是反過來——手上有一個改不動的地方，去查它叫什麼。&lt;/p>
&lt;p>繁體中文版《重構（第二版）：改善既有程式的設計》，碁峰出版、賴屹民譯。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Signature/dp/0134757599">Amazon（Refactoring, 2nd Edition）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.books.com.tw/products/0010825896">博客來（重構（第二版）：改善既有程式的設計）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="手上沒有測試時讀-working-effectively-with-legacy-code">手上沒有測試時讀 Working Effectively with Legacy Code&lt;/h2>
&lt;p>Michael Feathers 這本補的是前一本假設已經存在、而現實中經常沒有的東西。它對遺留程式碼的定義是：&lt;strong>沒有測試的程式碼就是遺留程式碼&lt;/strong>，不論它上週才寫好。這個定義把問題從「這段程式碼有多老」換成「我改它的時候拿什麼確認自己沒弄壞」，而後者才是可以動手處理的。&lt;/p>
&lt;p>於是全書的主軸變成一個先有雞還是先有蛋的問題：要安全地改，得先有測試；要寫測試，得先把依賴切開；而切開依賴本身就是在改程式碼。Feathers 的解法是接縫（seam）——程式裡那些可以在不編輯該處的前提下改變行為的位置，找到它就有了掛測試的著力點。書末的二十四項解依賴技術是這套方法的目錄。&lt;/p>
&lt;p>它跟 Fowler 那本的關係是入場與正式作業：Feathers 負責把程式碼推到「已經進了測試控制」這個門檻，門檻之後 Fowler 的目錄才用得上。兩本沒有重疊。&lt;/p>
&lt;p>時效上，書中的範例語言（C++、Java、C）與那個年代的工具鏈已經隔了一段距離，測試框架的部分也是；接縫這個概念與二十四項技術處理的是靜態依賴怎麼被切開，那件事不依賴語言世代。證據來源是跨客戶的顧問經驗，來自作者在多個遺留系統上的現場工作。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/books/knowledge-cards/context-compatibility/" data-link-title="處境相容性（context compatibility）" data-link-desc="一本書或一套做法讀起來都對、換算到自己的組織卻沒有一條動得了時，用來定位缺的是哪一個環境條件">處境相容性&lt;/a>上，二十四項技術預設那份程式碼是動得了的——編譯、執行、加測試、改建置設定都做得到。系統只能透過廠商窗口改、或本機建不起來時，其中一半用不上，那種處境要先取得建置環境才談得上入場技術。&lt;/p>
&lt;p>這本要接手過一個沒有測試、而又被要求改動的系統才讀得出東西——沒有那個處境時，接縫會讀成一個過度講究的技巧。可以先知道它存在，接手那樣的系統時再拿出來。&lt;/p>
&lt;p>繁體中文版《Working Effectively with Legacy Code 中文版：管理、修改、重構遺留程式碼的藝術》，博碩出版。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052">Amazon（Working Effectively with Legacy Code）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.books.com.tw/products/0010829482">博客來（Working Effectively with Legacy Code 中文版）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="要決定現在整理還是之後再說時讀-tidy-first">要決定「現在整理還是之後再說」時讀 Tidy First?&lt;/h2>
&lt;p>Kent Beck 的《Tidy First?》（2023）處理的是另外兩本沒有處理的那個決定：手上要改一個功能，而周圍的程式碼有點亂——先整理再改、改完再整理、還是不整理？這本書整本只回答這一個問題，很快就能讀完。它也是本篇門檻最低的一本，跟起點書不是同一本：起點取 Fowler 是因為涵蓋面，而 Fowler 那本要手上正有一段想改的程式碼才讀得出東西。要挑給一群程度不一的人共讀時取這本。&lt;/p>
&lt;p>它的做法是把整理當成一筆投資來算。整理現在要付成本、之後改動變便宜，而「之後」有多遠、會不會真的再改到這裡，決定了這筆投資划不划算。Beck 用耦合與內聚解釋成本從哪來，再用選擇權的概念解釋為什麼在不確定性高的時候保留彈性本身有價值。這是這個主題裡唯一把「要不要現在做」寫成可以推導的決定、而不是憑手感的一本。&lt;/p>
&lt;p>它跟另外兩本的分工是規模：Fowler 與 Feathers 處理的是動作本身怎麼做，這本處理的是動作要不要現在做、做多少。書中的整理項目刻意都很小（一次幾分鐘到一小時），因為它主張的正是小步——大改動需要批准、需要協調、會跟別人的工作衝突，而小到不需要開專案的改動可以隨時做。&lt;/p>
&lt;p>證據來源是單一路徑的個人經驗，加上他自己標明的經驗主義立場——書名的問號與副標的 personal exercise 都在說這是他的實踐而非通則，這個自我標定在技藝書裡少見。&lt;/p>
&lt;p>處境上，先整理再改這個取捨預設 commit 的節奏由動手的人自己控制。每個 commit 要對應一張工單、或整理型改動需要單獨送審的流程裡，整理的成本項要重算——書中算的是認知與風險成本，那些流程另外加上一筆固定的行政成本。時效上是這個主題最新的一本，尚無過時的部分。這本書幾乎不需要前置準備，但它預設讀者已經知道重構是什麼——完全沒有那個概念時，先讀 Fowler 的前幾章再回來。繁體中文版《先整理一下？｜個人層面的軟體設計考量》，歐萊禮出版。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.amazon.com/Tidy-First-Personal-Exercise-Empirical/dp/1098151240">Amazon（Tidy First?: A Personal Exercise in Empirical Software Design）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.books.com.tw/products/0011008590">博客來（先整理一下？｜個人層面的軟體設計考量）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="為什麼只收這幾本">為什麼只收這幾本&lt;/h2>
&lt;p>手上有沒有測試，決定了哪一類技術用得上，所以這個主題的入口不只一個：有測試的走 Fowler 的目錄，沒有測試的走 Feathers 的入場技術，改動小到不值得開專案的走 Beck 的取捨算法。三本之間沒有重疊。&lt;/p>
&lt;p>重構主題的書市有一大類是特定語言的重構手冊，它們把 Fowler 的目錄翻譯成某個語言的慣用寫法。那類屬於教學系列而非書單的責任範圍，而且它們的時效跟語言版本綁在一起。看目錄裡的手法名稱就分得出來——手法名稱本身是某個語言的語法特徵時，那本書會隨那個語法的演進失效。&lt;/p>
&lt;p>Joshua Kerievsky 的《Refactoring to Patterns》把重構手法接到設計模式上，本書單未評估它。它的前提是讀者已經熟悉 GoF 設計模式，而那套模式在近年的適用性本身有討論——判斷這本書現在的價值要先處理那個前提，這裡沒有做。&lt;/p>
&lt;p>讀不動長篇文字的讀者在別的主題可以改走公開課，這個主題走不了。課堂教材要可控、可評分、每屆重複得了，而本篇三本書處理的&lt;strong>已經存在而且沒人想動的程式碼&lt;/strong>正好是這三項的反面——它的價值來自真實系統累積出來的歷史，那種材料課程取不到。所以這裡查不到課，而這是對缺席最合理的解釋、不是查證結果。整條線的供給狀況寫在 &lt;a href="../">工程技藝書單&lt;/a> 的公開課段。&lt;/p>
&lt;h2 id="這個主題接到哪裡">這個主題接到哪裡&lt;/h2>
&lt;p>改動的技術要用在對的地方，靠的是設計判準——什麼樣的結構值得改成、什麼樣的複雜度是根本問題。那條路徑走 &lt;a href="../design-and-practice/">設計判準與日常實踐&lt;/a>。&lt;/p>
&lt;p>要動的程式碼沒有測試而需要先補，測試該怎麼分層與設計看 &lt;a href="https://tarrragon.github.io/blog/testing/" data-link-title="開發測試實務指南" data-link-desc="測試全過而實機全壞、或程式碼由 agent 產出而無法逐行讀時，用來決定驗證該掛在哪幾層、每一層各自守不住什麼">Testing 測試策略&lt;/a>；大規模重構怎麼分階段推進、途中的常見失誤與作用域回歸風險，看 &lt;a href="https://tarrragon.github.io/blog/python/07-refactoring/" data-link-title="模組七：重構實戰" data-link-desc="基於 v0.28.0-v0.31.0 重構經驗的程式碼品質改善指南">Python 維護指南的重構章&lt;/a>，那裡有一個跨版本重構的完整實作案例。&lt;/p>
&lt;p>如果重構一直被排不進時程，那不是技藝問題——走 &lt;a href="../../software-management/topics/estimation-decision/">估算、承諾與決策偏誤&lt;/a> 與 &lt;a href="../../software-management/topics/team-design/">組織結構與團隊設計&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>改既有的程式跟寫新的程式是兩種活。寫新的時候形狀由動手的人決定；改既有的時候形狀已經定了，動它的前提是不弄壞任何人依賴的行為。這件事的難度不由程式碼的複雜度決定，由<strong>有沒有辦法知道自己弄壞了什麼</strong>決定——同一段程式，有測試時的改法跟沒測試時的改法完全不同。</p>
<p>三本書按這條線分：有測試時怎麼做（Fowler 的《Refactoring》）、沒測試時怎麼先弄出測試（Feathers 的《Working Effectively with Legacy Code》）、以及改動小到不值得開專案時怎麼決定要不要現在做（Beck 的《Tidy First?》）。</p>
<h2 id="起點是-refactoring">起點是 Refactoring</h2>
<p>Martin Fowler 的《Refactoring》把這個主題編成一份目錄，第二版收了六十幾項具名重構，每一項都有動機、機制與範例——編成目錄這件事本身就是它涵蓋面最完整的原因，因為漏掉的手法在目錄裡是看得出來的。它同時定義了這個詞：重構是改變程式碼的內部結構而不改變其外部行為——這個定義比日常用法嚴格得多，而多數把「重構」用在大改寫上的溝通混亂都來自忽略後半句。</p>
<p><strong>IDE 自動化之後這本書的價值在哪，是讀它之前最該想清楚的事。</strong> 目錄裡多數手法現在是一個快捷鍵：Extract Function、Rename、Move Method 都由工具代勞，而書裡那些「先做這步、再做這步、每步跑測試」的手動安全程序，實務上不會有人照著做。看到這裡就把整本書跳過是常見的誤判。</p>
<p>被自動化的是機械步驟，沒有被自動化的是判斷：這段程式碼該不該提取、提取到哪一層、什麼訊號代表現在該動它。目錄的用途因此從「怎麼安全地手動做」轉成<strong>一套共同詞彙</strong>——說得出「這裡要做的是 Replace Conditional with Polymorphism」的時候，審查討論的單位就從「我覺得這樣比較好」變成一個有明確前後狀態的動作。書中的程式碼異味清單（Code Smell）是這套詞彙的另一半，它命名的是動手的理由。</p>
<p>版本要選：第二版（2018）把範例從 Java 換成 JavaScript，並補了不用 class 的函式式範例。這對讀者是真的取捨——寫 Java 的人第一版的範例反而貼近，而第二版的目錄本身有更新。時效上，被工具取代的是機械步驟而不是判斷——目錄裡多數手法現在是 IDE 的一個快捷鍵，那一層已經過時；命名這些動作的詞彙、以及判斷「現在該不該動它」的異味清單不依賴任何工具世代。<a href="/blog/books/knowledge-cards/evidence-provenance/" data-link-title="證據來源分類（evidence provenance）" data-link-desc="手上兩本書講同一件事而結論不同、或要拿一本書去支持一個實際決定時，用來判斷它支持得了多大範圍的決定">證據來源</a>是跨客戶的顧問經驗（作者與貢獻者群的實務歸納），形式是目錄而非論證。</p>
<p>這本要有一段程式碼在手上才讀得動——自己想改、但不確定怎麼下手的那種。沒有那段程式碼在手上，翻目錄的動作會停在「原來這叫 Extract Function」，而目錄真正的用法是反過來——手上有一個改不動的地方，去查它叫什麼。</p>
<p>繁體中文版《重構（第二版）：改善既有程式的設計》，碁峰出版、賴屹民譯。</p>
<ul>
<li><a href="https://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Signature/dp/0134757599">Amazon（Refactoring, 2nd Edition）</a></li>
<li><a href="https://www.books.com.tw/products/0010825896">博客來（重構（第二版）：改善既有程式的設計）</a></li>
</ul>
<h2 id="手上沒有測試時讀-working-effectively-with-legacy-code">手上沒有測試時讀 Working Effectively with Legacy Code</h2>
<p>Michael Feathers 這本補的是前一本假設已經存在、而現實中經常沒有的東西。它對遺留程式碼的定義是：<strong>沒有測試的程式碼就是遺留程式碼</strong>，不論它上週才寫好。這個定義把問題從「這段程式碼有多老」換成「我改它的時候拿什麼確認自己沒弄壞」，而後者才是可以動手處理的。</p>
<p>於是全書的主軸變成一個先有雞還是先有蛋的問題：要安全地改，得先有測試；要寫測試，得先把依賴切開；而切開依賴本身就是在改程式碼。Feathers 的解法是接縫（seam）——程式裡那些可以在不編輯該處的前提下改變行為的位置，找到它就有了掛測試的著力點。書末的二十四項解依賴技術是這套方法的目錄。</p>
<p>它跟 Fowler 那本的關係是入場與正式作業：Feathers 負責把程式碼推到「已經進了測試控制」這個門檻，門檻之後 Fowler 的目錄才用得上。兩本沒有重疊。</p>
<p>時效上，書中的範例語言（C++、Java、C）與那個年代的工具鏈已經隔了一段距離，測試框架的部分也是；接縫這個概念與二十四項技術處理的是靜態依賴怎麼被切開，那件事不依賴語言世代。證據來源是跨客戶的顧問經驗，來自作者在多個遺留系統上的現場工作。</p>
<p><a href="/blog/books/knowledge-cards/context-compatibility/" data-link-title="處境相容性（context compatibility）" data-link-desc="一本書或一套做法讀起來都對、換算到自己的組織卻沒有一條動得了時，用來定位缺的是哪一個環境條件">處境相容性</a>上，二十四項技術預設那份程式碼是動得了的——編譯、執行、加測試、改建置設定都做得到。系統只能透過廠商窗口改、或本機建不起來時，其中一半用不上，那種處境要先取得建置環境才談得上入場技術。</p>
<p>這本要接手過一個沒有測試、而又被要求改動的系統才讀得出東西——沒有那個處境時，接縫會讀成一個過度講究的技巧。可以先知道它存在，接手那樣的系統時再拿出來。</p>
<p>繁體中文版《Working Effectively with Legacy Code 中文版：管理、修改、重構遺留程式碼的藝術》，博碩出版。</p>
<ul>
<li><a href="https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052">Amazon（Working Effectively with Legacy Code）</a></li>
<li><a href="https://www.books.com.tw/products/0010829482">博客來（Working Effectively with Legacy Code 中文版）</a></li>
</ul>
<h2 id="要決定現在整理還是之後再說時讀-tidy-first">要決定「現在整理還是之後再說」時讀 Tidy First?</h2>
<p>Kent Beck 的《Tidy First?》（2023）處理的是另外兩本沒有處理的那個決定：手上要改一個功能，而周圍的程式碼有點亂——先整理再改、改完再整理、還是不整理？這本書整本只回答這一個問題，很快就能讀完。它也是本篇門檻最低的一本，跟起點書不是同一本：起點取 Fowler 是因為涵蓋面，而 Fowler 那本要手上正有一段想改的程式碼才讀得出東西。要挑給一群程度不一的人共讀時取這本。</p>
<p>它的做法是把整理當成一筆投資來算。整理現在要付成本、之後改動變便宜，而「之後」有多遠、會不會真的再改到這裡，決定了這筆投資划不划算。Beck 用耦合與內聚解釋成本從哪來，再用選擇權的概念解釋為什麼在不確定性高的時候保留彈性本身有價值。這是這個主題裡唯一把「要不要現在做」寫成可以推導的決定、而不是憑手感的一本。</p>
<p>它跟另外兩本的分工是規模：Fowler 與 Feathers 處理的是動作本身怎麼做，這本處理的是動作要不要現在做、做多少。書中的整理項目刻意都很小（一次幾分鐘到一小時），因為它主張的正是小步——大改動需要批准、需要協調、會跟別人的工作衝突，而小到不需要開專案的改動可以隨時做。</p>
<p>證據來源是單一路徑的個人經驗，加上他自己標明的經驗主義立場——書名的問號與副標的 personal exercise 都在說這是他的實踐而非通則，這個自我標定在技藝書裡少見。</p>
<p>處境上，先整理再改這個取捨預設 commit 的節奏由動手的人自己控制。每個 commit 要對應一張工單、或整理型改動需要單獨送審的流程裡，整理的成本項要重算——書中算的是認知與風險成本，那些流程另外加上一筆固定的行政成本。時效上是這個主題最新的一本，尚無過時的部分。這本書幾乎不需要前置準備，但它預設讀者已經知道重構是什麼——完全沒有那個概念時，先讀 Fowler 的前幾章再回來。繁體中文版《先整理一下？｜個人層面的軟體設計考量》，歐萊禮出版。</p>
<ul>
<li><a href="https://www.amazon.com/Tidy-First-Personal-Exercise-Empirical/dp/1098151240">Amazon（Tidy First?: A Personal Exercise in Empirical Software Design）</a></li>
<li><a href="https://www.books.com.tw/products/0011008590">博客來（先整理一下？｜個人層面的軟體設計考量）</a></li>
</ul>
<h2 id="為什麼只收這幾本">為什麼只收這幾本</h2>
<p>手上有沒有測試，決定了哪一類技術用得上，所以這個主題的入口不只一個：有測試的走 Fowler 的目錄，沒有測試的走 Feathers 的入場技術，改動小到不值得開專案的走 Beck 的取捨算法。三本之間沒有重疊。</p>
<p>重構主題的書市有一大類是特定語言的重構手冊，它們把 Fowler 的目錄翻譯成某個語言的慣用寫法。那類屬於教學系列而非書單的責任範圍，而且它們的時效跟語言版本綁在一起。看目錄裡的手法名稱就分得出來——手法名稱本身是某個語言的語法特徵時，那本書會隨那個語法的演進失效。</p>
<p>Joshua Kerievsky 的《Refactoring to Patterns》把重構手法接到設計模式上，本書單未評估它。它的前提是讀者已經熟悉 GoF 設計模式，而那套模式在近年的適用性本身有討論——判斷這本書現在的價值要先處理那個前提，這裡沒有做。</p>
<p>讀不動長篇文字的讀者在別的主題可以改走公開課，這個主題走不了。課堂教材要可控、可評分、每屆重複得了，而本篇三本書處理的<strong>已經存在而且沒人想動的程式碼</strong>正好是這三項的反面——它的價值來自真實系統累積出來的歷史，那種材料課程取不到。所以這裡查不到課，而這是對缺席最合理的解釋、不是查證結果。整條線的供給狀況寫在 <a href="../">工程技藝書單</a> 的公開課段。</p>
<h2 id="這個主題接到哪裡">這個主題接到哪裡</h2>
<p>改動的技術要用在對的地方，靠的是設計判準——什麼樣的結構值得改成、什麼樣的複雜度是根本問題。那條路徑走 <a href="../design-and-practice/">設計判準與日常實踐</a>。</p>
<p>要動的程式碼沒有測試而需要先補，測試該怎麼分層與設計看 <a href="/blog/testing/" data-link-title="開發測試實務指南" data-link-desc="測試全過而實機全壞、或程式碼由 agent 產出而無法逐行讀時，用來決定驗證該掛在哪幾層、每一層各自守不住什麼">Testing 測試策略</a>；大規模重構怎麼分階段推進、途中的常見失誤與作用域回歸風險，看 <a href="/blog/python/07-refactoring/" data-link-title="模組七：重構實戰" data-link-desc="基於 v0.28.0-v0.31.0 重構經驗的程式碼品質改善指南">Python 維護指南的重構章</a>，那裡有一個跨版本重構的完整實作案例。</p>
<p>如果重構一直被排不進時程，那不是技藝問題——走 <a href="../../software-management/topics/estimation-decision/">估算、承諾與決策偏誤</a> 與 <a href="../../software-management/topics/team-design/">組織結構與團隊設計</a>。</p>
]]></content:encoded></item><item><title>系統架構</title><link>https://tarrragon.github.io/blog/books/craft/system-architecture/</link><pubDate>Wed, 19 Aug 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/books/craft/system-architecture/</guid><description>&lt;p>架構決定跟 &lt;a href="../design-and-practice/">設計判準與日常實踐&lt;/a> 與 &lt;a href="../changing-existing-code/">改既有的程式&lt;/a> 的差別在&lt;strong>改錯的代價&lt;/strong>。程式碼寫得不好可以重構，模組切得不好可以搬；架構選錯之後，改動要跨越團隊、資料、部署與既有承諾，通常大到只能繞過而不能修正。這使得架構的核心能力是&lt;strong>在資訊不足的時候把取捨講清楚&lt;/strong>——包括講清楚自己選的那個爛在哪——而不是知道有哪些做法。&lt;/p>
&lt;p>這個主題只有兩本，按有沒有詞彙分：《Fundamentals of Software Architecture》先建立一整套可以用來討論的概念，《Software Architecture: The Hard Parts》再處理那些用了概念仍然沒有標準答案的決定。&lt;/p>
&lt;p>讀不動長篇文字時，本篇文末另標出承接這個主題機制層的公開課，收錄門檻與已知限制見 &lt;a href="https://tarrragon.github.io/blog/books/" data-link-title="書單推薦" data-link-desc="站在某個職涯位置、想知道該讀哪本工具書，想往別的位置移動而不知道該預習什麼，或因為閱讀障礙與外語閱讀速度而需要同一份知識換成用聽的時看這裡">書單推薦&lt;/a> 的「公開課怎麼收」段。&lt;/p>
&lt;h2 id="起點是-fundamentals-of-software-architecture">起點是 Fundamentals of Software Architecture&lt;/h2>
&lt;p>Mark Richards 與 Neal Ford 這本的主要貢獻是一整套詞彙，而詞彙要鋪滿才有用——這也是它成為本篇涵蓋面最完整一本的原因。沒有那套詞彙的架構討論會停在「我覺得微服務比較好」，有了之後才問得出「我們要優化的是哪幾個架構特性、代價付在哪裡」。&lt;/p>
&lt;p>核心是架構特性（architecture characteristics）這個概念：可擴展性、彈性、可測試性、可部署性這些「性」不是越多越好，它們互相衝突，而架構的工作是選出這個系統真正需要的少數幾個、明確放棄其餘的。書中另一半是架構風格的目錄——分層、微核心、事件驅動、微服務、第二版新增的模組化單體——每個風格附上它在各項特性上的評分，於是「選哪個」變成一個有維度的比較而不是流行度投票。&lt;/p>
&lt;p>第二版（繁中版 2026 年出）跟第一版的差距大到需要挑版本：新增模組化單體、架構模式、圖示法、治理、資料架構與生成式 AI 幾章，並改寫了架構法則的部分。第一版繁中譯名是《軟體架構原理｜工程方法》，第二版是《軟體架構原理 第二版｜現代工程方法》，買新的。&lt;/p>
&lt;p>時效上，架構風格的清單與各風格的特性評分隨生態變動——第二版新增的模組化單體與生成式 AI 兩章就是這一層的更新；架構特性互相衝突、必須明確放棄一些，這條主軸不依賴任何一代的風格清單。&lt;a href="https://tarrragon.github.io/blog/books/knowledge-cards/evidence-provenance/" data-link-title="證據來源分類（evidence provenance）" data-link-desc="手上兩本書講同一件事而結論不同、或要拿一本書去支持一個實際決定時，用來判斷它支持得了多大範圍的決定">證據來源&lt;/a>是跨客戶的顧問經驗與教學經驗，加上跨組織案例的整理，形式接近教科書——它整理已知的做法而非提出新主張，這也決定了它的用法：當參照系用，不是當論證用。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/books/knowledge-cards/context-compatibility/" data-link-title="處境相容性（context compatibility）" data-link-desc="一本書或一套做法讀起來都對、換算到自己的組織卻沒有一條動得了時，用來定位缺的是哪一個環境條件">處境相容性&lt;/a>上，架構特性的取捨預設有人為不同特性負責、而且那些人講得上話。決定由外部給定時——客戶指定、母公司統一、法規要求——這本書給的是理解那個決定的語言，不是做那個決定的方法。&lt;/p>
&lt;p>讀這本要參與過一個需要跨團隊協調的系統，架構特性的衝突才體會得到——衝突要在有人為不同特性負責時才顯現，只在單一服務裡工作時看不見它。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.amazon.com/Fundamentals-Software-Architecture-Engineering-Approach/dp/1098175514">Amazon（Fundamentals of Software Architecture: A Modern Engineering Approach, 2nd Edition）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.books.com.tw/products/0011045361">博客來（軟體架構原理 第二版｜現代工程方法）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="已經在拆分而每個選項都有代價時讀-software-architecture-the-hard-parts">已經在拆分而每個選項都有代價時讀 Software Architecture: The Hard Parts&lt;/h2>
&lt;p>同一組作者加上 Pramod Sadalage 與 Zhamak Dehghani 的這本，處理的是前一本建立詞彙之後才浮出來的問題：服務該切多細、工作流程要編排還是編舞、契約要嚴格還是寬鬆、分散式交易怎麼辦、資料該怎麼跟著服務拆。&lt;/p>
&lt;p>它的書名說明了立場——這些是&lt;strong>沒有最佳實踐的問題&lt;/strong>。書的結構因此給的是取捨分析的做法而非答案：把每個決定的可能選項列出來、標出各自在哪些架構特性上得分、明確寫出放棄了什麼。它反覆示範同一個動作，那個動作本身才是要學的東西。&lt;/p>
&lt;p>其中資料那部分特別值得注意，因為它是拆分服務時最常被低估的一段。服務可以切開，資料的一致性需求切不開；書中對於哪些資料該複製、哪些該共用、交易邊界該畫在哪，給的是可以逐項走的判斷，而不是「盡量避免分散式交易」這種沒有出口的建議。&lt;/p>
&lt;p>它跟前一本的關係是入場與深水：前一本讓人說得出這個系統要什麼，這本接手說得出之後仍然沒有標準答案的那些決定。順序不要顛倒——沒有架構特性的詞彙時，這本的取捨分析會讀成一堆並列的技術選項。&lt;/p>
&lt;p>證據來源同樣是跨客戶的顧問經驗加跨組織案例，而它比前一本更依賴一個貫穿全書的虛構案例。時效上，書出版於 2021 年，微服務相關的工具生態已有變化；取捨分析的做法與資料拆分的判斷不依賴那些工具。&lt;/p>
&lt;p>這本要有正在拆、或已經拆了一個系統的處境才讀得出東西——沒有那個處境時，八種粒度崩解訊號每一種都同樣有道理，而它們的用途是在其中認出正在發生的那一種。可以先知道它存在，開始拆的時候再拿出來。繁體中文版《軟體架構：困難部分》。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.amazon.com/Software-Architecture-Trade-Off-Distributed-Architectures/dp/1492086894">Amazon（Software Architecture: The Hard Parts）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.books.com.tw/products/0010927173">博客來（軟體架構：困難部分）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="為什麼只收這兩本">為什麼只收這兩本&lt;/h2>
&lt;p>兩本按「有沒有詞彙」分：建立整套概念與參照系（Fundamentals），以及用了概念之後仍然沒有標準答案的決定（The Hard Parts）。同一組作者，刻意寫成前後接續，中間沒有空隙也沒有重疊。&lt;/p>
&lt;p>架構的書市有一大類是特定架構風格的推廣書（微服務怎麼做、事件驅動怎麼做）。那類的問題是它們預設風格已經選定，而選擇本身才是架構工作最難的部分——分辨方式是看它有沒有寫「什麼情況下不要用這個風格」，而架構風格的邊界通常落在規模與團隊數上——同一個風格在三個團隊與三十個團隊下的代價差一個量級，不交代這一項的多半是在推銷而不是在分析。&lt;/p>
&lt;p>Robert Martin 的《Clean Architecture》常被列在這個位置，本書單未評估它，理由與 &lt;a href="../design-and-practice/">設計判準與日常實踐&lt;/a> 對《Clean Code》的處理相同。SEI 的《Software Architecture in Practice》是學術系統化的另一條路線（品質屬性、ATAM 評估法），繁中版也在，但它的讀者定位偏向需要正式架構評估流程的組織，本書單未評估那個情境。&lt;/p>
&lt;p>資料密集系統的設計（複製、分片、一致性模型）不在這個主題，那屬於 &lt;a href="https://tarrragon.github.io/blog/backend/" data-link-title="Backend 服務實務指南" data-link-desc="用跨語言教學路線整理資料庫、快取、訊息佇列、觀測、部署、可靠性、資安、事故與容量等後端服務能力">Backend 服務實務指南&lt;/a> 的責任範圍。&lt;/p>
&lt;h2 id="機制那一半有兩門完整的課取捨判斷那一半沒有">機制那一半有兩門完整的課，取捨判斷那一半沒有&lt;/h2>
&lt;p>這是技藝線唯一接得住公開課的主題，而它接住的只有一半。架構決定要用到機制知識與取捨判斷兩者：機制知識是複製怎麼做、一致性有幾種、共識協定在解什麼、分割之後交易怎麼辦；取捨判斷是在資訊不足時把每個選項的代價講清楚。機制教得了，判斷教不了——這跟本篇兩本書的分工同向，起點書先給詞彙、第二本才處理用了詞彙仍然沒有標準答案的決定。&lt;/p>
&lt;p>&lt;strong>MIT 6.824 Distributed Systems（Spring 2020）&lt;/strong> 由 Robert Morris 主講、20 講、每講約 80 分鐘，走的是讀論文加講解的形式。講次依序走過 GFS、主備複製、Raft（連三講）、ZooKeeper、CRAQ 的鏈式複製、Aurora、Frangipani 與 Memcached 的快取一致性、分散式交易、Spanner、樂觀並行控制、Spark、COPS 的因果一致性，最後兩講是 Bitcoin 與 Blockstack。它給的是本篇兩本書在談元件切分與資料所有權時預設讀者知道、而兩本書都不從頭建立的那些機制。這門課要寫 Go 的實驗作業（MapReduce 與 Raft 各一份），只看講課不做實驗仍然走得完，代價是共識協定那幾講會停在聽得懂而不是做得出來。&lt;/p>
&lt;p>&lt;strong>Martin Kleppmann 的 Distributed Systems lecture series&lt;/strong> 是劍橋的課，8 講切成 23 段影片、每段 10 到 20 分鐘，全長約七小時。同一位作者的《Designing Data-Intensive Applications》不在這一篇——資料密集系統的設計屬於 &lt;a href="https://tarrragon.github.io/blog/backend/" data-link-title="Backend 服務實務指南" data-link-desc="用跨語言教學路線整理資料庫、快取、訊息佇列、觀測、部署、可靠性、資安、事故與容量等後端服務能力">Backend 服務實務指南&lt;/a> 的範圍，這裡收的只有這門課。它跟前一門的差別在密度與門檻：Morris 那門一講一篇論文、每講約 80 分鐘、假設聽眾是研究生；Kleppmann 這門從電腦網路與時鐘開始建立，單段短、可以零碎聽完。兩門的「講」不是同一個單位——比長度要用總時數，6.824 二十講約二十六小時。想先建立整體地圖的從這一門開始，想追某個機制怎麼被證明的走前一門。&lt;/p>
&lt;p>兩門課的材料是已經發表的論文與已經定案的協定，時效因此不隨版本更新而動；會改變的是它們順帶提到的雲端服務與工具介面。兩門都是英語授課，而它們不像 Open Yale 的課附官方逐字稿——字幕狀態以 YouTube 當下提供的為準，本頁沒有確認過是人工還是自動。這個主題沒查到中文的對應課。&lt;/p>
&lt;p>取捨判斷那一半沒查到課，而缺口的成因就是這個主題的核心能力本身——在資訊不足的時候把取捨講清楚，包括講清楚自己選的那個爛在哪。這種能力的教材是別人做過的決定與它後來的代價，而那些代價要好幾年才顯現，一學期的課承載不了。整條線的供給狀況寫在 &lt;a href="../">工程技藝書單&lt;/a> 的公開課段。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.youtube.com/playlist?list=PLrw6a1wE39_tb2fErI4-WkMbsvGQk9_UB">YouTube 播放清單（MIT 6.824 Distributed Systems，Robert Morris，Spring 2020，20 講）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.youtube.com/playlist?list=PLeKd45zvjcDFUEv_ohr_HdUFe97RItdiB">YouTube 播放清單（Distributed Systems lecture series，Martin Kleppmann，8 講、23 段影片）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="這個主題接到哪裡">這個主題接到哪裡&lt;/h2>
&lt;p>架構決定的代價一半落在組織上——介面畫在哪裡，決定了哪兩個團隊要天天開會。那條路徑走 &lt;a href="../../software-management/topics/team-design/">組織結構與團隊設計&lt;/a>，Team Topologies 與這裡的架構風格處理的是同一件事的兩端。&lt;/p>
&lt;p>往下一個尺度走，模組與介面該怎麼切看 &lt;a href="../design-and-practice/">設計判準與日常實踐&lt;/a>；架構定了之後既有程式碼怎麼搬過去看 &lt;a href="../changing-existing-code/">改既有的程式&lt;/a>。&lt;/p>
&lt;p>具體的資料庫、快取、佇列與可觀測性選型看 &lt;a href="https://tarrragon.github.io/blog/backend/" data-link-title="Backend 服務實務指南" data-link-desc="用跨語言教學路線整理資料庫、快取、訊息佇列、觀測、部署、可靠性、資安、事故與容量等後端服務能力">Backend 服務實務指南&lt;/a>，部署與環境看 &lt;a href="https://tarrragon.github.io/blog/infra/" data-link-title="Infra 基礎設施建置指南" data-link-desc="從零循序漸進把雲端基礎設施做起來 — IaC、身分憑證、網路地基、環境分離、核心服務、可觀測性、自動化 review 與治理習慣，含怎麼在組織內推動">Infra 基礎設施建置指南&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>架構決定跟 <a href="../design-and-practice/">設計判準與日常實踐</a> 與 <a href="../changing-existing-code/">改既有的程式</a> 的差別在<strong>改錯的代價</strong>。程式碼寫得不好可以重構，模組切得不好可以搬；架構選錯之後，改動要跨越團隊、資料、部署與既有承諾，通常大到只能繞過而不能修正。這使得架構的核心能力是<strong>在資訊不足的時候把取捨講清楚</strong>——包括講清楚自己選的那個爛在哪——而不是知道有哪些做法。</p>
<p>這個主題只有兩本，按有沒有詞彙分：《Fundamentals of Software Architecture》先建立一整套可以用來討論的概念，《Software Architecture: The Hard Parts》再處理那些用了概念仍然沒有標準答案的決定。</p>
<p>讀不動長篇文字時，本篇文末另標出承接這個主題機制層的公開課，收錄門檻與已知限制見 <a href="/blog/books/" data-link-title="書單推薦" data-link-desc="站在某個職涯位置、想知道該讀哪本工具書，想往別的位置移動而不知道該預習什麼，或因為閱讀障礙與外語閱讀速度而需要同一份知識換成用聽的時看這裡">書單推薦</a> 的「公開課怎麼收」段。</p>
<h2 id="起點是-fundamentals-of-software-architecture">起點是 Fundamentals of Software Architecture</h2>
<p>Mark Richards 與 Neal Ford 這本的主要貢獻是一整套詞彙，而詞彙要鋪滿才有用——這也是它成為本篇涵蓋面最完整一本的原因。沒有那套詞彙的架構討論會停在「我覺得微服務比較好」，有了之後才問得出「我們要優化的是哪幾個架構特性、代價付在哪裡」。</p>
<p>核心是架構特性（architecture characteristics）這個概念：可擴展性、彈性、可測試性、可部署性這些「性」不是越多越好，它們互相衝突，而架構的工作是選出這個系統真正需要的少數幾個、明確放棄其餘的。書中另一半是架構風格的目錄——分層、微核心、事件驅動、微服務、第二版新增的模組化單體——每個風格附上它在各項特性上的評分，於是「選哪個」變成一個有維度的比較而不是流行度投票。</p>
<p>第二版（繁中版 2026 年出）跟第一版的差距大到需要挑版本：新增模組化單體、架構模式、圖示法、治理、資料架構與生成式 AI 幾章，並改寫了架構法則的部分。第一版繁中譯名是《軟體架構原理｜工程方法》，第二版是《軟體架構原理 第二版｜現代工程方法》，買新的。</p>
<p>時效上，架構風格的清單與各風格的特性評分隨生態變動——第二版新增的模組化單體與生成式 AI 兩章就是這一層的更新；架構特性互相衝突、必須明確放棄一些，這條主軸不依賴任何一代的風格清單。<a href="/blog/books/knowledge-cards/evidence-provenance/" data-link-title="證據來源分類（evidence provenance）" data-link-desc="手上兩本書講同一件事而結論不同、或要拿一本書去支持一個實際決定時，用來判斷它支持得了多大範圍的決定">證據來源</a>是跨客戶的顧問經驗與教學經驗，加上跨組織案例的整理，形式接近教科書——它整理已知的做法而非提出新主張，這也決定了它的用法：當參照系用，不是當論證用。</p>
<p><a href="/blog/books/knowledge-cards/context-compatibility/" data-link-title="處境相容性（context compatibility）" data-link-desc="一本書或一套做法讀起來都對、換算到自己的組織卻沒有一條動得了時，用來定位缺的是哪一個環境條件">處境相容性</a>上，架構特性的取捨預設有人為不同特性負責、而且那些人講得上話。決定由外部給定時——客戶指定、母公司統一、法規要求——這本書給的是理解那個決定的語言，不是做那個決定的方法。</p>
<p>讀這本要參與過一個需要跨團隊協調的系統，架構特性的衝突才體會得到——衝突要在有人為不同特性負責時才顯現，只在單一服務裡工作時看不見它。</p>
<ul>
<li><a href="https://www.amazon.com/Fundamentals-Software-Architecture-Engineering-Approach/dp/1098175514">Amazon（Fundamentals of Software Architecture: A Modern Engineering Approach, 2nd Edition）</a></li>
<li><a href="https://www.books.com.tw/products/0011045361">博客來（軟體架構原理 第二版｜現代工程方法）</a></li>
</ul>
<h2 id="已經在拆分而每個選項都有代價時讀-software-architecture-the-hard-parts">已經在拆分而每個選項都有代價時讀 Software Architecture: The Hard Parts</h2>
<p>同一組作者加上 Pramod Sadalage 與 Zhamak Dehghani 的這本，處理的是前一本建立詞彙之後才浮出來的問題：服務該切多細、工作流程要編排還是編舞、契約要嚴格還是寬鬆、分散式交易怎麼辦、資料該怎麼跟著服務拆。</p>
<p>它的書名說明了立場——這些是<strong>沒有最佳實踐的問題</strong>。書的結構因此給的是取捨分析的做法而非答案：把每個決定的可能選項列出來、標出各自在哪些架構特性上得分、明確寫出放棄了什麼。它反覆示範同一個動作，那個動作本身才是要學的東西。</p>
<p>其中資料那部分特別值得注意，因為它是拆分服務時最常被低估的一段。服務可以切開，資料的一致性需求切不開；書中對於哪些資料該複製、哪些該共用、交易邊界該畫在哪，給的是可以逐項走的判斷，而不是「盡量避免分散式交易」這種沒有出口的建議。</p>
<p>它跟前一本的關係是入場與深水：前一本讓人說得出這個系統要什麼，這本接手說得出之後仍然沒有標準答案的那些決定。順序不要顛倒——沒有架構特性的詞彙時，這本的取捨分析會讀成一堆並列的技術選項。</p>
<p>證據來源同樣是跨客戶的顧問經驗加跨組織案例，而它比前一本更依賴一個貫穿全書的虛構案例。時效上，書出版於 2021 年，微服務相關的工具生態已有變化；取捨分析的做法與資料拆分的判斷不依賴那些工具。</p>
<p>這本要有正在拆、或已經拆了一個系統的處境才讀得出東西——沒有那個處境時，八種粒度崩解訊號每一種都同樣有道理，而它們的用途是在其中認出正在發生的那一種。可以先知道它存在，開始拆的時候再拿出來。繁體中文版《軟體架構：困難部分》。</p>
<ul>
<li><a href="https://www.amazon.com/Software-Architecture-Trade-Off-Distributed-Architectures/dp/1492086894">Amazon（Software Architecture: The Hard Parts）</a></li>
<li><a href="https://www.books.com.tw/products/0010927173">博客來（軟體架構：困難部分）</a></li>
</ul>
<h2 id="為什麼只收這兩本">為什麼只收這兩本</h2>
<p>兩本按「有沒有詞彙」分：建立整套概念與參照系（Fundamentals），以及用了概念之後仍然沒有標準答案的決定（The Hard Parts）。同一組作者，刻意寫成前後接續，中間沒有空隙也沒有重疊。</p>
<p>架構的書市有一大類是特定架構風格的推廣書（微服務怎麼做、事件驅動怎麼做）。那類的問題是它們預設風格已經選定，而選擇本身才是架構工作最難的部分——分辨方式是看它有沒有寫「什麼情況下不要用這個風格」，而架構風格的邊界通常落在規模與團隊數上——同一個風格在三個團隊與三十個團隊下的代價差一個量級，不交代這一項的多半是在推銷而不是在分析。</p>
<p>Robert Martin 的《Clean Architecture》常被列在這個位置，本書單未評估它，理由與 <a href="../design-and-practice/">設計判準與日常實踐</a> 對《Clean Code》的處理相同。SEI 的《Software Architecture in Practice》是學術系統化的另一條路線（品質屬性、ATAM 評估法），繁中版也在，但它的讀者定位偏向需要正式架構評估流程的組織，本書單未評估那個情境。</p>
<p>資料密集系統的設計（複製、分片、一致性模型）不在這個主題，那屬於 <a href="/blog/backend/" data-link-title="Backend 服務實務指南" data-link-desc="用跨語言教學路線整理資料庫、快取、訊息佇列、觀測、部署、可靠性、資安、事故與容量等後端服務能力">Backend 服務實務指南</a> 的責任範圍。</p>
<h2 id="機制那一半有兩門完整的課取捨判斷那一半沒有">機制那一半有兩門完整的課，取捨判斷那一半沒有</h2>
<p>這是技藝線唯一接得住公開課的主題，而它接住的只有一半。架構決定要用到機制知識與取捨判斷兩者：機制知識是複製怎麼做、一致性有幾種、共識協定在解什麼、分割之後交易怎麼辦；取捨判斷是在資訊不足時把每個選項的代價講清楚。機制教得了，判斷教不了——這跟本篇兩本書的分工同向，起點書先給詞彙、第二本才處理用了詞彙仍然沒有標準答案的決定。</p>
<p><strong>MIT 6.824 Distributed Systems（Spring 2020）</strong> 由 Robert Morris 主講、20 講、每講約 80 分鐘，走的是讀論文加講解的形式。講次依序走過 GFS、主備複製、Raft（連三講）、ZooKeeper、CRAQ 的鏈式複製、Aurora、Frangipani 與 Memcached 的快取一致性、分散式交易、Spanner、樂觀並行控制、Spark、COPS 的因果一致性，最後兩講是 Bitcoin 與 Blockstack。它給的是本篇兩本書在談元件切分與資料所有權時預設讀者知道、而兩本書都不從頭建立的那些機制。這門課要寫 Go 的實驗作業（MapReduce 與 Raft 各一份），只看講課不做實驗仍然走得完，代價是共識協定那幾講會停在聽得懂而不是做得出來。</p>
<p><strong>Martin Kleppmann 的 Distributed Systems lecture series</strong> 是劍橋的課，8 講切成 23 段影片、每段 10 到 20 分鐘，全長約七小時。同一位作者的《Designing Data-Intensive Applications》不在這一篇——資料密集系統的設計屬於 <a href="/blog/backend/" data-link-title="Backend 服務實務指南" data-link-desc="用跨語言教學路線整理資料庫、快取、訊息佇列、觀測、部署、可靠性、資安、事故與容量等後端服務能力">Backend 服務實務指南</a> 的範圍，這裡收的只有這門課。它跟前一門的差別在密度與門檻：Morris 那門一講一篇論文、每講約 80 分鐘、假設聽眾是研究生；Kleppmann 這門從電腦網路與時鐘開始建立，單段短、可以零碎聽完。兩門的「講」不是同一個單位——比長度要用總時數，6.824 二十講約二十六小時。想先建立整體地圖的從這一門開始，想追某個機制怎麼被證明的走前一門。</p>
<p>兩門課的材料是已經發表的論文與已經定案的協定，時效因此不隨版本更新而動；會改變的是它們順帶提到的雲端服務與工具介面。兩門都是英語授課，而它們不像 Open Yale 的課附官方逐字稿——字幕狀態以 YouTube 當下提供的為準，本頁沒有確認過是人工還是自動。這個主題沒查到中文的對應課。</p>
<p>取捨判斷那一半沒查到課，而缺口的成因就是這個主題的核心能力本身——在資訊不足的時候把取捨講清楚，包括講清楚自己選的那個爛在哪。這種能力的教材是別人做過的決定與它後來的代價，而那些代價要好幾年才顯現，一學期的課承載不了。整條線的供給狀況寫在 <a href="../">工程技藝書單</a> 的公開課段。</p>
<ul>
<li><a href="https://www.youtube.com/playlist?list=PLrw6a1wE39_tb2fErI4-WkMbsvGQk9_UB">YouTube 播放清單（MIT 6.824 Distributed Systems，Robert Morris，Spring 2020，20 講）</a></li>
<li><a href="https://www.youtube.com/playlist?list=PLeKd45zvjcDFUEv_ohr_HdUFe97RItdiB">YouTube 播放清單（Distributed Systems lecture series，Martin Kleppmann，8 講、23 段影片）</a></li>
</ul>
<h2 id="這個主題接到哪裡">這個主題接到哪裡</h2>
<p>架構決定的代價一半落在組織上——介面畫在哪裡，決定了哪兩個團隊要天天開會。那條路徑走 <a href="../../software-management/topics/team-design/">組織結構與團隊設計</a>，Team Topologies 與這裡的架構風格處理的是同一件事的兩端。</p>
<p>往下一個尺度走，模組與介面該怎麼切看 <a href="../design-and-practice/">設計判準與日常實踐</a>；架構定了之後既有程式碼怎麼搬過去看 <a href="../changing-existing-code/">改既有的程式</a>。</p>
<p>具體的資料庫、快取、佇列與可觀測性選型看 <a href="/blog/backend/" data-link-title="Backend 服務實務指南" data-link-desc="用跨語言教學路線整理資料庫、快取、訊息佇列、觀測、部署、可靠性、資安、事故與容量等後端服務能力">Backend 服務實務指南</a>，部署與環境看 <a href="/blog/infra/" data-link-title="Infra 基礎設施建置指南" data-link-desc="從零循序漸進把雲端基礎設施做起來 — IaC、身分憑證、網路地基、環境分離、核心服務、可觀測性、自動化 review 與治理習慣，含怎麼在組織內推動">Infra 基礎設施建置指南</a>。</p>
]]></content:encoded></item><item><title>驗證自己寫對了</title><link>https://tarrragon.github.io/blog/books/craft/verification/</link><pubDate>Wed, 19 Aug 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/books/craft/verification/</guid><description>&lt;p>這個主題有一個技藝線其他三篇——設計判準、系統架構、改既有的程式——都沒有的特徵：&lt;strong>收錄的書彼此不同意&lt;/strong>。測試該寫到什麼粒度、協作對象該不該用 mock 替換、測試該綁在行為上還是結構上——這些問題有兩個互相對立的傳統，而多數讀者是在讀到第二本、發現它跟第一本說法相反的時候，才知道自己一直在照著其中一派做而不知道有另一派。&lt;/p>
&lt;p>所以這篇的選讀判斷跟那三篇不同：不是「先讀哪本再讀哪本」，是&lt;strong>先知道分歧在哪，再決定要站哪邊&lt;/strong>。&lt;/p>
&lt;p>收的書分成兩組。第一組四本各自站在一個位置上：Kent Beck 的《Test-Driven Development: By Example》給出原始定義，Freeman 與 Pryce 的《Growing Object-Oriented Software, Guided by Tests》把其中一派的主張寫到最完整，Khorikov 的《Unit Testing Principles, Practices, and Patterns》是後來對那一派的系統性批評——&lt;strong>這三本不同意的是同一個問題的答案&lt;/strong>，那個問題是「測試的單元是什麼」。Bach 與 Bolton 的《Taking Testing Seriously》站在第四個位置上，&lt;strong>它不同意的是問題本身&lt;/strong>：它主張要先分開的是兩種活動——「執行事先寫好的判準」與「設計判準、發現沒人想到要問的問題」——而不是單元的大小。&lt;/p>
&lt;p>第二組一本，Aniche 的《Effective Software Testing》，處理的是立場確定之後仍然要回答的操作問題——這些測試案例是怎麼推出來的。前四本沒有一本給這個程序。&lt;/p>
&lt;p>站內對這個分歧的立場與推導在 &lt;a href="https://tarrragon.github.io/blog/record/behavior-first-tdd-methodology/" data-link-title="行為優先的 TDD：測試耦合行為、不耦合結構" data-link-desc="重構時測試大量壞掉、或在「該不該 mock 這個協作者」上需要一個可執行的立場時，本站對兩派 TDD 分歧的選擇與推導">行為優先的 TDD 方法論&lt;/a>，那篇處理的是「所以我們怎麼做」；這裡處理的是「該讀哪本、每本代表什麼位置」。&lt;/p>
&lt;h2 id="起點是-kent-beck-的-test-driven-development-by-example">起點是 Kent Beck 的 Test-Driven Development: By Example&lt;/h2>
&lt;p>這本是 TDD 的原始定義，2003 年出版，做的事情很單純：從頭到尾走完兩個小專案，把紅燈、綠燈、重構這個循環示範幾十次。讀它的價值不在學到技巧，在於看清楚那個循環的節奏究竟有多小——書中的步伐比多數人想像的細，細到會讓第一次讀的人覺得沒必要。&lt;/p>
&lt;p>它是起點的理由是 Freeman 與 Pryce 那本、Khorikov 那本都在跟它對話。分歧從一個定義開始：&lt;strong>測試的單元是什麼&lt;/strong>。Beck 的用法把單元當成一組協同工作的類別，測試對外的行為；後來的另一派——書市慣稱倫敦學派——把單元縮到單一類別，把所有協作者換成 mock。兩派的所有差異都從這個定義分岔出去。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/books/knowledge-cards/evidence-provenance/" data-link-title="證據來源分類（evidence provenance）" data-link-desc="手上兩本書講同一件事而結論不同、或要拿一本書去支持一個實際決定時，用來判斷它支持得了多大範圍的決定">證據來源&lt;/a>是單一路徑的個人經驗，形式是作者逐步演練自己的實踐而非論證。時效上，範例是 Java 與 Python 的舊版本，測試框架也隔了兩個世代；紅綠重構的節奏與「讓測試驅動設計」這個主張不依賴那些。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/books/knowledge-cards/context-compatibility/" data-link-title="處境相容性（context compatibility）" data-link-desc="一本書或一套做法讀起來都對、換算到自己的組織卻沒有一條動得了時，用來定位缺的是哪一個環境條件">處境相容性&lt;/a>上，這套節奏預設提交的粒度由寫的人自己決定。流程若要求每個提交對應一張工單、或測試必須跟功能在同一個 PR 送審，書中那個細到讓人覺得沒必要的步伐就落不了地，要先改流程、或改用較粗的循環。&lt;/p>
&lt;p>這本書幾乎不需要前置作業，但它預設讀者寫過測試——完全沒寫過的人會看不出那些步驟在避免什麼；先在自己的專案寫過幾個測試再來讀，那些步驟的用意才看得出來。繁體中文版《Kent Beck 的測試驅動開發：案例導向的逐步解決之道》，博碩出版、陳仕傑譯。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530">Amazon（Test Driven Development: By Example）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.books.com.tw/products/0010883019">博客來（Kent Beck 的測試驅動開發：案例導向的逐步解決之道）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="想看-mock-那一派的完整主張時讀-growing-object-oriented-software-guided-by-tests">想看 mock 那一派的完整主張時讀 Growing Object-Oriented Software, Guided by Tests&lt;/h2>
&lt;p>Steve Freeman 與 Nat Pryce 這本是倫敦學派的代表作，也是它最完整的一次陳述。主張是由外而內開發：從最外層的驗收測試開始，往內每遇到一個還不存在的協作對象就先用 mock 頂替，於是 mock 不只是測試工具，而是&lt;strong>用來發現物件之間該有什麼關係的設計手段&lt;/strong>。&lt;/p>
&lt;p>這個定位常被誤解。多數人把 mock 當成「真實依賴太慢所以換掉」，而這本書的主張是相反的——mock 是在那個依賴還不知道長什麼樣的時候，用寫測試的方式把它的介面逼出來。書中貫穿全書的那個範例完整走過一次這個流程，是它跟只講技巧的測試書的差別。&lt;/p>
&lt;p>它也是這個主題裡爭議最集中的一本。批評集中在同一點：這種寫法讓測試綁在物件的協作結構上，於是重構內部結構時測試會大量壞掉，而重構本來不該破壞測試。這個批評成不成立，取決於單元怎麼定義——那正是 Khorikov 那本要處理的問題。&lt;/p>
&lt;p>證據來源是單一路徑的個人經驗（兩位作者十年的系統開發），形式是主張加上一個長篇範例。時效上，範例是 Java 與 JMock，那部分已經很遠；由外而內的流程與 mock 當設計手段這個主張不依賴語言。&lt;/p>
&lt;p>讀這本要先有一次自己造成的後果：寫過一套後來覺得難維護的測試。還沒有那個經驗時，這本的主張跟批評它的主張聽起來都有道理，讀的人沒有判斷的依據——它因此適合排在自己的測試開始出現維護負擔之後，而不是照出版順序讀。查不到中譯本（2026 年 8 月查）。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.amazon.com/Growing-Object-Oriented-Software-Guided-Tests/dp/0321503627">Amazon（Growing Object-Oriented Software, Guided by Tests）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="要一組可以拿來評分的判準時讀-unit-testing-principles-practices-and-patterns">要一組可以拿來評分的判準時讀 Unit Testing Principles, Practices, and Patterns&lt;/h2>
&lt;p>Vladimir Khorikov 這本（2020）是單元定義這條線上最後出版的一本，也是唯一給出&lt;strong>一套可以拿來評測試的通用判準&lt;/strong>的一本。四支柱是防止回歸、抵抗重構、快速回饋、易於維護，而書中的核心論證是前三者互相衝突、不可能同時最大化，所以測試設計是取捨而非最佳實踐。這套判準有一類測試評不了：為了替沒有測試的程式碼建立行為快照而寫、用完就丟的那種（&lt;a href="../changing-existing-code/">改既有的程式&lt;/a> 收的 Feathers 那本教的手法），它在抵抗重構與易於維護上必然低分，而那正是它該有的樣子。四支柱預設被評的測試要長期留著。&lt;/p>
&lt;p>它對倫敦學派的批評就建立在這組判準上：把所有協作者 mock 掉會讓測試耦合到實作結構，因而在「抵抗重構」這一項上得分很低——而那一項是四支柱裡唯一不能用其他項補償的，因為一個會誤報的測試套件最終會被團隊忽略。作者主張的是古典學派：單元是行為而非類別，只有跨越應用邊界的協作對象（資料庫、外部服務）才該替換。&lt;/p>
&lt;p>這本的用法跟前兩本不同：它不是拿來讀完的，是拿來當量尺的。手上有一套自己覺得不對勁的測試時，逐項打分數比讀任何主張都快看出問題在哪。&lt;/p>
&lt;p>證據來源是單一路徑的個人經驗加上理論建構，形式是原則加判準——這是本篇收錄的書裡唯一嘗試把測試設計寫成可推導體系的。範例是 C#，但判準本身與語言無關。時效上沒有明顯過時的部分——四支柱的取捨與工具世代無關。&lt;/p>
&lt;p>這本要有量測的對象：手上一套實際在跑、而且開始造成負擔的測試。沒有那套測試，四支柱之間的取捨不會浮現——它們互相衝突，而衝突要有一套實際的測試當標的才看得見。還沒有這樣一套測試的話，可以先知道這本存在，等負擔出現再拿出來用。查不到繁體中文版，簡體中文版《單元測試：原則、實踐與模式》（2026 年 8 月查）。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.amazon.com/Unit-Testing-Principles-Practices-Patterns/dp/1617296279">Amazon（Unit Testing Principles, Practices, and Patterns）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.tenlong.com.tw/products/9781617296277">天瓏（Unit Testing Principles, Practices, and Patterns，原文版）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="想知道機器接手判準之後人還做什麼時讀-taking-testing-seriously">想知道機器接手判準之後人還做什麼時讀 Taking Testing Seriously&lt;/h2>
&lt;p>James Bach 與 Michael Bolton 這本（Wiley，2025 年 11 月）是 Rapid Software Testing 這一派的完整陳述。它跟前三本不在同一個座標系裡：前三本爭的是單元的邊界該畫在哪，這本主張要先分開的是兩種活動——&lt;strong>checking&lt;/strong>（對一個已經被決定的事實做二元評估，判準事先寫下、原則上可以交給機器）與 &lt;strong>testing&lt;/strong>（設計判準本身、發現沒有人想到要問的問題、判斷觀察到的現象算不算問題）。作者的立場是自動化能接手的只有前者，而前者的品質完全取決於當初設計它的那次後者。&lt;/p>
&lt;p>這個分界是這一派的起點，理由是自動化的邊界由判準寫不寫得下來決定，與工具能力無關。作者同期公開談論過 AI 與這個分界的關係；書的目次未能取得，這裡不指涉它在書中的位置與篇幅。&lt;/p>
&lt;p>證據來源是兩位作者長期的教學與顧問實踐加上一套自建的術語體系，形式是主張與啟發式的目錄而不是逐步演練——它不像 Freeman 與 Pryce 那本有一個貫穿全書的範例可以跟著做。時效上是本篇最新的一本，術語體系本身不依賴任何工具世代。&lt;/p>
&lt;p>處境相容性上要先知道一件事：這一派的語彙（checking、oracle、heuristic、探索式測試的活動記錄）與多數團隊日常使用的詞彙不重疊，讀的時候要一邊做術語對照。它也預設讀者有機會親自操作產品——判準要在觀察當下才成形是這套主張的核心，而完全只寫單元測試、不碰成品的人拿不到那個觀察位置。查不到中譯本（2026 年 8 月查）。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.wiley.com/en-us/Taking&amp;#43;Testing&amp;#43;Seriously:&amp;#43;The&amp;#43;Rapid&amp;#43;Software&amp;#43;Testing&amp;#43;Approach-p-00416398">Wiley（Taking Testing Seriously: The Rapid Software Testing Approach）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.tenlong.com.tw/products/9781394253197">天瓏（Taking Testing Seriously，原文版）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="要一套推出測試案例的程序時讀-effective-software-testing">要一套推出測試案例的程序時讀 Effective Software Testing&lt;/h2>
&lt;p>Maurício Aniche 這本（Manning，2022）處理的是前四本都沒有給的一項：&lt;strong>這些測試案例是怎麼被推出來的&lt;/strong>。Khorikov 給的是評分用的量尺，Beck 給的是循環的節奏，這本給的是從需求推導案例的步驟——先從規格切出等價類與邊界，再用覆蓋準則檢查有沒有漏掉分支，接著設計方法與類別的契約（前置條件、後置條件、不變量），最後回頭問這段程式碼的可測試性是不是設計本身的問題。&lt;/p></description><content:encoded><![CDATA[<p>這個主題有一個技藝線其他三篇——設計判準、系統架構、改既有的程式——都沒有的特徵：<strong>收錄的書彼此不同意</strong>。測試該寫到什麼粒度、協作對象該不該用 mock 替換、測試該綁在行為上還是結構上——這些問題有兩個互相對立的傳統，而多數讀者是在讀到第二本、發現它跟第一本說法相反的時候，才知道自己一直在照著其中一派做而不知道有另一派。</p>
<p>所以這篇的選讀判斷跟那三篇不同：不是「先讀哪本再讀哪本」，是<strong>先知道分歧在哪，再決定要站哪邊</strong>。</p>
<p>收的書分成兩組。第一組四本各自站在一個位置上：Kent Beck 的《Test-Driven Development: By Example》給出原始定義，Freeman 與 Pryce 的《Growing Object-Oriented Software, Guided by Tests》把其中一派的主張寫到最完整，Khorikov 的《Unit Testing Principles, Practices, and Patterns》是後來對那一派的系統性批評——<strong>這三本不同意的是同一個問題的答案</strong>，那個問題是「測試的單元是什麼」。Bach 與 Bolton 的《Taking Testing Seriously》站在第四個位置上，<strong>它不同意的是問題本身</strong>：它主張要先分開的是兩種活動——「執行事先寫好的判準」與「設計判準、發現沒人想到要問的問題」——而不是單元的大小。</p>
<p>第二組一本，Aniche 的《Effective Software Testing》，處理的是立場確定之後仍然要回答的操作問題——這些測試案例是怎麼推出來的。前四本沒有一本給這個程序。</p>
<p>站內對這個分歧的立場與推導在 <a href="/blog/record/behavior-first-tdd-methodology/" data-link-title="行為優先的 TDD：測試耦合行為、不耦合結構" data-link-desc="重構時測試大量壞掉、或在「該不該 mock 這個協作者」上需要一個可執行的立場時，本站對兩派 TDD 分歧的選擇與推導">行為優先的 TDD 方法論</a>，那篇處理的是「所以我們怎麼做」；這裡處理的是「該讀哪本、每本代表什麼位置」。</p>
<h2 id="起點是-kent-beck-的-test-driven-development-by-example">起點是 Kent Beck 的 Test-Driven Development: By Example</h2>
<p>這本是 TDD 的原始定義，2003 年出版，做的事情很單純：從頭到尾走完兩個小專案，把紅燈、綠燈、重構這個循環示範幾十次。讀它的價值不在學到技巧，在於看清楚那個循環的節奏究竟有多小——書中的步伐比多數人想像的細，細到會讓第一次讀的人覺得沒必要。</p>
<p>它是起點的理由是 Freeman 與 Pryce 那本、Khorikov 那本都在跟它對話。分歧從一個定義開始：<strong>測試的單元是什麼</strong>。Beck 的用法把單元當成一組協同工作的類別，測試對外的行為；後來的另一派——書市慣稱倫敦學派——把單元縮到單一類別，把所有協作者換成 mock。兩派的所有差異都從這個定義分岔出去。</p>
<p><a href="/blog/books/knowledge-cards/evidence-provenance/" data-link-title="證據來源分類（evidence provenance）" data-link-desc="手上兩本書講同一件事而結論不同、或要拿一本書去支持一個實際決定時，用來判斷它支持得了多大範圍的決定">證據來源</a>是單一路徑的個人經驗，形式是作者逐步演練自己的實踐而非論證。時效上，範例是 Java 與 Python 的舊版本，測試框架也隔了兩個世代；紅綠重構的節奏與「讓測試驅動設計」這個主張不依賴那些。</p>
<p><a href="/blog/books/knowledge-cards/context-compatibility/" data-link-title="處境相容性（context compatibility）" data-link-desc="一本書或一套做法讀起來都對、換算到自己的組織卻沒有一條動得了時，用來定位缺的是哪一個環境條件">處境相容性</a>上，這套節奏預設提交的粒度由寫的人自己決定。流程若要求每個提交對應一張工單、或測試必須跟功能在同一個 PR 送審，書中那個細到讓人覺得沒必要的步伐就落不了地，要先改流程、或改用較粗的循環。</p>
<p>這本書幾乎不需要前置作業，但它預設讀者寫過測試——完全沒寫過的人會看不出那些步驟在避免什麼；先在自己的專案寫過幾個測試再來讀，那些步驟的用意才看得出來。繁體中文版《Kent Beck 的測試驅動開發：案例導向的逐步解決之道》，博碩出版、陳仕傑譯。</p>
<ul>
<li><a href="https://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530">Amazon（Test Driven Development: By Example）</a></li>
<li><a href="https://www.books.com.tw/products/0010883019">博客來（Kent Beck 的測試驅動開發：案例導向的逐步解決之道）</a></li>
</ul>
<h2 id="想看-mock-那一派的完整主張時讀-growing-object-oriented-software-guided-by-tests">想看 mock 那一派的完整主張時讀 Growing Object-Oriented Software, Guided by Tests</h2>
<p>Steve Freeman 與 Nat Pryce 這本是倫敦學派的代表作，也是它最完整的一次陳述。主張是由外而內開發：從最外層的驗收測試開始，往內每遇到一個還不存在的協作對象就先用 mock 頂替，於是 mock 不只是測試工具，而是<strong>用來發現物件之間該有什麼關係的設計手段</strong>。</p>
<p>這個定位常被誤解。多數人把 mock 當成「真實依賴太慢所以換掉」，而這本書的主張是相反的——mock 是在那個依賴還不知道長什麼樣的時候，用寫測試的方式把它的介面逼出來。書中貫穿全書的那個範例完整走過一次這個流程，是它跟只講技巧的測試書的差別。</p>
<p>它也是這個主題裡爭議最集中的一本。批評集中在同一點：這種寫法讓測試綁在物件的協作結構上，於是重構內部結構時測試會大量壞掉，而重構本來不該破壞測試。這個批評成不成立，取決於單元怎麼定義——那正是 Khorikov 那本要處理的問題。</p>
<p>證據來源是單一路徑的個人經驗（兩位作者十年的系統開發），形式是主張加上一個長篇範例。時效上，範例是 Java 與 JMock，那部分已經很遠；由外而內的流程與 mock 當設計手段這個主張不依賴語言。</p>
<p>讀這本要先有一次自己造成的後果：寫過一套後來覺得難維護的測試。還沒有那個經驗時，這本的主張跟批評它的主張聽起來都有道理，讀的人沒有判斷的依據——它因此適合排在自己的測試開始出現維護負擔之後，而不是照出版順序讀。查不到中譯本（2026 年 8 月查）。</p>
<ul>
<li><a href="https://www.amazon.com/Growing-Object-Oriented-Software-Guided-Tests/dp/0321503627">Amazon（Growing Object-Oriented Software, Guided by Tests）</a></li>
</ul>
<h2 id="要一組可以拿來評分的判準時讀-unit-testing-principles-practices-and-patterns">要一組可以拿來評分的判準時讀 Unit Testing Principles, Practices, and Patterns</h2>
<p>Vladimir Khorikov 這本（2020）是單元定義這條線上最後出版的一本，也是唯一給出<strong>一套可以拿來評測試的通用判準</strong>的一本。四支柱是防止回歸、抵抗重構、快速回饋、易於維護，而書中的核心論證是前三者互相衝突、不可能同時最大化，所以測試設計是取捨而非最佳實踐。這套判準有一類測試評不了：為了替沒有測試的程式碼建立行為快照而寫、用完就丟的那種（<a href="../changing-existing-code/">改既有的程式</a> 收的 Feathers 那本教的手法），它在抵抗重構與易於維護上必然低分，而那正是它該有的樣子。四支柱預設被評的測試要長期留著。</p>
<p>它對倫敦學派的批評就建立在這組判準上：把所有協作者 mock 掉會讓測試耦合到實作結構，因而在「抵抗重構」這一項上得分很低——而那一項是四支柱裡唯一不能用其他項補償的，因為一個會誤報的測試套件最終會被團隊忽略。作者主張的是古典學派：單元是行為而非類別，只有跨越應用邊界的協作對象（資料庫、外部服務）才該替換。</p>
<p>這本的用法跟前兩本不同：它不是拿來讀完的，是拿來當量尺的。手上有一套自己覺得不對勁的測試時，逐項打分數比讀任何主張都快看出問題在哪。</p>
<p>證據來源是單一路徑的個人經驗加上理論建構，形式是原則加判準——這是本篇收錄的書裡唯一嘗試把測試設計寫成可推導體系的。範例是 C#，但判準本身與語言無關。時效上沒有明顯過時的部分——四支柱的取捨與工具世代無關。</p>
<p>這本要有量測的對象：手上一套實際在跑、而且開始造成負擔的測試。沒有那套測試，四支柱之間的取捨不會浮現——它們互相衝突，而衝突要有一套實際的測試當標的才看得見。還沒有這樣一套測試的話，可以先知道這本存在，等負擔出現再拿出來用。查不到繁體中文版，簡體中文版《單元測試：原則、實踐與模式》（2026 年 8 月查）。</p>
<ul>
<li><a href="https://www.amazon.com/Unit-Testing-Principles-Practices-Patterns/dp/1617296279">Amazon（Unit Testing Principles, Practices, and Patterns）</a></li>
<li><a href="https://www.tenlong.com.tw/products/9781617296277">天瓏（Unit Testing Principles, Practices, and Patterns，原文版）</a></li>
</ul>
<h2 id="想知道機器接手判準之後人還做什麼時讀-taking-testing-seriously">想知道機器接手判準之後人還做什麼時讀 Taking Testing Seriously</h2>
<p>James Bach 與 Michael Bolton 這本（Wiley，2025 年 11 月）是 Rapid Software Testing 這一派的完整陳述。它跟前三本不在同一個座標系裡：前三本爭的是單元的邊界該畫在哪，這本主張要先分開的是兩種活動——<strong>checking</strong>（對一個已經被決定的事實做二元評估，判準事先寫下、原則上可以交給機器）與 <strong>testing</strong>（設計判準本身、發現沒有人想到要問的問題、判斷觀察到的現象算不算問題）。作者的立場是自動化能接手的只有前者，而前者的品質完全取決於當初設計它的那次後者。</p>
<p>這個分界是這一派的起點，理由是自動化的邊界由判準寫不寫得下來決定，與工具能力無關。作者同期公開談論過 AI 與這個分界的關係；書的目次未能取得，這裡不指涉它在書中的位置與篇幅。</p>
<p>證據來源是兩位作者長期的教學與顧問實踐加上一套自建的術語體系，形式是主張與啟發式的目錄而不是逐步演練——它不像 Freeman 與 Pryce 那本有一個貫穿全書的範例可以跟著做。時效上是本篇最新的一本，術語體系本身不依賴任何工具世代。</p>
<p>處境相容性上要先知道一件事：這一派的語彙（checking、oracle、heuristic、探索式測試的活動記錄）與多數團隊日常使用的詞彙不重疊，讀的時候要一邊做術語對照。它也預設讀者有機會親自操作產品——判準要在觀察當下才成形是這套主張的核心，而完全只寫單元測試、不碰成品的人拿不到那個觀察位置。查不到中譯本（2026 年 8 月查）。</p>
<ul>
<li><a href="https://www.wiley.com/en-us/Taking&#43;Testing&#43;Seriously:&#43;The&#43;Rapid&#43;Software&#43;Testing&#43;Approach-p-00416398">Wiley（Taking Testing Seriously: The Rapid Software Testing Approach）</a></li>
<li><a href="https://www.tenlong.com.tw/products/9781394253197">天瓏（Taking Testing Seriously，原文版）</a></li>
</ul>
<h2 id="要一套推出測試案例的程序時讀-effective-software-testing">要一套推出測試案例的程序時讀 Effective Software Testing</h2>
<p>Maurício Aniche 這本（Manning，2022）處理的是前四本都沒有給的一項：<strong>這些測試案例是怎麼被推出來的</strong>。Khorikov 給的是評分用的量尺，Beck 給的是循環的節奏，這本給的是從需求推導案例的步驟——先從規格切出等價類與邊界，再用覆蓋準則檢查有沒有漏掉分支，接著設計方法與類別的契約（前置條件、後置條件、不變量），最後回頭問這段程式碼的可測試性是不是設計本身的問題。</p>
<p>它跟量尺型的書搭配起來沒有重疊：量尺回答「手上這套測試好不好」，這本回答「還缺哪幾個案例」。手上一套測試被評為分數低而不知道要補什麼時，缺的通常是這本教的推導程序。</p>
<p>證據來源是學術訓練加業界實踐（作者當時同時任教於 Delft 理工大學並在業界帶技術培訓），形式是步驟加練習，每章有可自己動手的題目。範例是 Java 與 JUnit，推導程序本身與語言無關。時效上沒有明顯過時的部分。</p>
<p>前置經驗要求比前四本低——它不預設讀者已經寫過一套難維護的測試，也不預設讀者對兩派分歧有立場。缺點的另一面是它不處理立場問題：讀完之後仍然要自己決定單元畫在哪，那要回到前面四本。作者另有一套與本書同主題的免費線上課（見下方公開課段），內容重疊但形式互補。查不到繁體中文版，另有簡體中文譯本（2026 年 8 月查）。</p>
<ul>
<li><a href="https://www.manning.com/books/effective-software-testing">Manning（Effective Software Testing: A Developer&rsquo;s Guide）</a></li>
<li><a href="https://www.tenlong.com.tw/products/9781633439931">天瓏（Effective Software Testing: A Developer&rsquo;s Guide，原文版）</a></li>
</ul>
<h2 id="為什麼只收這幾本">為什麼只收這幾本</h2>
<p>立場那四本彼此不同意，而它們的分歧點正是這個主題最難自己判斷的那一個。讀完會發現自己原本以為的「測試最佳實踐」是某一派的立場，而那個發現比任何單一技巧有用。Aniche 那本收在旁邊，因為立場選定之後「案例怎麼推出來」仍然沒有答案。</p>
<p>測試的書市有兩大類不在這裡。一類是特定框架的操作手冊，那類的時效跟框架版本綁死，且屬於教學系列的範圍。另一類是把測試金字塔或某個覆蓋率目標推銷成普適規則的書——它們的問題是規則脫離了推導它的取捨，而本篇收的書恰好證明那些取捨還在爭論中。</p>
<p>Mark Winteringham 的《Software Testing with Generative AI》（Manning，2024）是 2026 年 8 月這一輪查到唯一整本處理「用生成式工具做測試」的書，本書單評估後不收。內容是工具操作層——用編碼助理引導 TDD、向對話模型取回饋、呼叫 API 生測試資料——落在上一段第一類的排除範圍裡，時效跟工具版本綁死。這個判定只針對本篇的收錄軸（立場分歧），要找那類操作內容的人它是現成的入口。</p>
<p>Roy Osherove 的《單元測試的藝術》繁中版流通度高，本書單未評估它。它的定位偏向操作手冊而非立場陳述，跟本篇要回答的問題（分歧在哪）不同軸；要判斷它現在的價值需要對照第三版的改寫幅度，這裡沒有做。</p>
<p>Gerard Meszaros 的《xUnit Test Patterns》是測試異味與模式的完整目錄，本書單未評估——它的體量與參考書性質接近 Code Complete，而這個主題目前沒有那個生態位的需求。</p>
<h2 id="影音路徑在別的關鍵字底下">影音路徑在別的關鍵字底下</h2>
<p>以「軟體測試」為關鍵字找到的公開課，2026 年 8 月這一輪查到的集中在怎麼當一個測試工程師——測試種類的名詞、工具操作、面試會問什麼，那類內容預設有標準答案可以教。本篇要交付的是幾本書彼此不同意在哪，是一組還在爭論中的立場，兩者不在同一層。</p>
<p>但這不表示這個主題沒有影音路徑，<strong>它出現在別的關鍵字底下</strong>。問「分歧在哪」的影音內容出現在 TDD、software engineering、craftsmanship 這幾個關鍵字下，而不在 software testing 下——後者的檢索結果被測試工程師的職涯內容佔滿。讀不動長篇文字的讀者要換的是關鍵字，不是放棄。</p>
<p>供給的形態依製作者的商業模式分成三種，判斷免費內容拿得到多少要先看這個：</p>
<table>
  <thead>
      <tr>
          <th>形態</th>
          <th>免費內容的位置</th>
          <th>這個主題拿得到什麼</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>內容型（付費課程靠免費內容引流）</td>
          <td>影音平台頻道，量大且完整</td>
          <td>Dave Farley 的 Continuous Delivery 與 Modern Software Engineering 頻道、Emily Bache 的頻道（approval testing 與重構的逐步演練）、Khorikov 的 Enterprise Craftsmanship 部落格</td>
      </tr>
      <tr>
          <td>顧問型（課程面向企業、不靠影音引流）</td>
          <td>長篇文字，不是影音</td>
          <td>Bach 與 Bolton 的 developsense.com 與 satisfice.com；想走影音繞過長文的人在這一派上沒有路徑</td>
      </tr>
      <tr>
          <td>平台型（全免費、靠上游產品變現）</td>
          <td>課程平台本身</td>
          <td>工具操作為主（Selenium、Cypress、Playwright、Appium），填不了立場分歧那個缺口</td>
      </tr>
  </tbody>
</table>
<p>學術機構開的免費課是這一輪查到最貼近本篇主題的影音資源：Delft 理工大學在 edX 上的 Automated Software Testing 系列由 Aniche 與 Arie van Deursen 開設，內容是單元測試、覆蓋準則與可測試性設計，與上面收錄的《Effective Software Testing》同源而形式互補。</p>
<p>整條線的供給狀況寫在 <a href="../">工程技藝書單</a> 的公開課段。</p>
<p>本篇的「最新」「唯一」「查不到中譯」這幾類宣稱都是相對於查證時點的。下次新增或替換任何一本書時，整篇重掃一次這三類句子——它們不會自己跟著新書更新。</p>
<h2 id="這個主題接到哪裡">這個主題接到哪裡</h2>
<p>測試寫不出來常常是設計的訊號而非測試技巧的問題——難測的程式碼通常是耦合太緊。那條路徑走 <a href="../design-and-practice/">設計判準與日常實踐</a>。既有程式碼沒有測試而必須先補，那是 <a href="../changing-existing-code/">改既有的程式</a> 裡 Feathers 那本處理的問題。</p>
<p>站內自己的測試分層策略、協議整合驗證與實機教訓看 <a href="/blog/testing/" data-link-title="開發測試實務指南" data-link-desc="測試全過而實機全壞、或程式碼由 agent 產出而無法逐行讀時，用來決定驗證該掛在哪幾層、每一層各自守不住什麼">Testing 測試策略</a>；本站在 mock 學派分歧上採取的立場與推導在 <a href="/blog/record/behavior-first-tdd-methodology/" data-link-title="行為優先的 TDD：測試耦合行為、不耦合結構" data-link-desc="重構時測試大量壞掉、或在「該不該 mock 這個協作者」上需要一個可執行的立場時，本站對兩派 TDD 分歧的選擇與推導">行為優先的 TDD 方法論</a>。</p>
<p>程式碼由 agent 產出、而人不打算逐行讀時，判準該落在哪走 <a href="/blog/testing/06-agent-authored-code/" data-link-title="模組六：Agent 產出程式碼的驗證" data-link-desc="程式碼由 agent 寫、人不再逐行讀時，用來決定驗證該落在哪些位置，以及每個位置的射程到哪裡">模組六：Agent 產出程式碼的驗證</a>——那裡處理的是本篇四本立場書共同預設而在那個情境下失效的前提：測試由懂需求的人寫，而那個人會讀自己的程式碼。Bach 與 Bolton 那本的 checking 與 testing 分界是這條路線的上游概念。</p>
]]></content:encoded></item></channel></rss>