「重構之前,最根本的問題是:什麼是設計壞味道?為什麼必須重構以消除它們?」 — 本書開場提問
從設計壞味道談起#
軟體本身具有複雜性、易變性與不可見性,這些「本質性困難」決定了軟體設計絕非易事。要面對這份困難,重要實踐之一就是辨識並處理設計中的壞味道(design smells)。
設計壞味道是設計中違反基礎設計原則、進而傷害設計品質的某些結構。
醫學診斷是個好的類比:
- 病人的症狀,相當於設計中的壞味道。
- 症狀背後的疾病,相當於設計中真正的問題。
- 醫師分析症狀、判斷疾病、開立治療方案;設計者則分析壞味道、推斷底層問題、執行重構。
要回答「為什麼必須重構消除壞味道」這個問題,就必須認識技術債(technical debt)。
1.1 什麼是技術債?#
技術債一詞由 Ward Cunningham 於 1992 年的報告中提出,用以類比金融債務:
- 借錢本身不可怕——只要按期還款。
- 不還款會孳生利息,而且利息會以複利形式滾動。
- 拖得越久,債務越大;最終可能達到無法償還的地步——這時就要宣告破產。
軟體開發完全相同:
- 當開發者選擇便宜行事的快速修補而非妥善設計時,就借入了技術債。
- 若能即時償還,影響不大。
- 若選擇拖延或忘記,每次新變更都會與「帶債」的設計交織,使債務越滾越大。
- 極端情況下,技術債積壓到無法清償時,整個專案只能放棄——稱為技術破產(technical bankruptcy)。
1.2 技術債由哪些東西構成?#
技術債並非只有單一面向,常見的維度包含:
- 程式碼債(code debt):靜態分析工具違規、不一致的編碼風格。
- 設計債(design debt):設計壞味道、違反設計規則。
- 測試債(test debt):缺乏測試、覆蓋率不足、測試設計不良。
- 文件債(documentation debt):欠缺重要面向的文件、文件品質低、文件過時。

Figure 1.1: 技術債的多重維度
本書聚焦於設計債。後文若無特別說明,「技術債」一詞即指設計債。
設計債如何累積#
以一家中型軟體組織為例:
- 為了搶占市場,要求開發者更快推出功能。
- 開發者沒有時間妥善評估設計決策的影響。
- 一個個局部、零散的設計妥協累積,逐漸侵蝕整體結構品質。
- 軟體進入長期維護階段後,這些累積的問題會大幅增加理解與維護的成本——這份未來的補救成本,就是設計債。
缺陷算不算技術債?#
書中明確採取以下立場:
缺陷(defect)與技術債分屬不同問題,不應混為一談。
理由:
- 缺陷直接影響外部品質屬性,使用者立即可見,組織必然會優先處理。
- 技術債影響內部品質,使用者察覺不到,往往被擱置或忽略。
- 若把缺陷納入技術債,組織會在修完缺陷後誤以為技術債也已處理,反而忽略真正的內部結構問題。
1.3 技術債的影響#
技術債由兩部分組成:
- 本金(principal):當初為求快速採取的捷徑或妥協。
- 利息(interest):本金未還時隨時間累積的成本,而且是複利成長。
利息為何呈複利?因為:
- 新變更必然會與帶債的舊設計交織,使整體結構更加扭曲。
- 既有的捷徑會「鼓勵」甚至強迫後續開發者繼續採用捷徑,債務便不斷擴大。
對變更成本的衝擊#
Jim Highsmith 描述「變更成本(Cost of Change,CoC)」與技術債的關係:
- 良好維護的系統,實際 CoC 接近理論最佳 CoC。
- 技術債一旦增加,實際 CoC 同步攀升。
- 極端時 CoC 高到無以為繼,即落入技術破產。
對團隊士氣的衝擊#
技術債不只是技術問題,更是組織與心理問題。當變更越來越困難,團隊會感到挫敗無力;而「一次還清」幾乎不可能,這會進一步消磨士氣。
書中也舉了金融業的真實案例——美國造市商 Knight Capital 因電腦交易程式錯誤導致重大虧損,BBC 報導指出技術債正是背後主因。
案例:被忽視的 12 年產品#
書中有一個延伸案例值得記住:
- 一個運行 12 年的產品需要升級換代,外聘架構師團隊介入。
- 架構師發現巨大的技術債:客戶端與伺服器邏輯使用同一份程式碼透過參數切換,毫無關注點分離。
- 架構師主張先重構再加功能,但管理層擔心延誤、開發團隊根本沒聽過技術債概念,內部產生抗拒。
- 最後決定「分階段重構」,僅針對單一關鍵模組。
- 然而緊耦合、缺少介面、責任不清等問題比預期嚴重,每次重構都很痛苦。
- 結果產品延遲半年發布,且新功能大幅縮水。
- 不過這次部分清債為後續版本鋪好了路——避免了技術破產的結局。
案例的最大教訓:讓所有利害關係人意識到技術債的存在,是任何重構計畫能否成功的前提。
1.4 技術債的成因#
技術債最終源於管理者、架構師、開發者所做的決策。除了「對技術債缺乏認知」外,常見成因包含:
- 進度壓力:在期限壓力下開發者採取倉促捷徑,例如濫用「複製貼上式程式設計(copy-paste programming)」。短期看似可行,長期累積卻使設計變得脆弱、難以理解。
- 缺乏優秀的設計者:如 Fred Brooks 在《人月神話》(The Mythical Man-Month)所強調,沒有具備設計基本功的設計者,整個團隊的設計品質都會受到拖累。
- 未確實應用設計原則:理論上知道原則但未實際落實,導致程式碼難以擴充與修改。
- 缺乏對壞味道與重構的認知:設計壞味道在不知不覺中蔓延;若團隊不認識它們、不執行重構,技術債會持續累積。
在現實的成本與時程約束下,短期借入技術債是可以接受的,但前提是越早償還越好。
1.5 如何管理技術債?#
技術債無法完全避免,但可以管理。書中提出三個高層級步驟:
- 建立技術債的認知
- 了解技術債的概念、不同類型、影響、成因。
- 唯有具備認知,組織才能在「專案目標」與「品質目標」間做出明智權衡。
- 偵測並償還技術債
- 衡量產品中技術債的範圍。
- 識別具體的債務實例與其影響,制定系統化的清債計畫。
- 詳細實作方法在第 8 章。
- 預防技術債繼續累積
- 在控制住現有技術債後,全體相關人員應持續追蹤並定期清理,使其長期維持在可管理水準。
認知 → 偵測 → 預防,是技術債管理的核心節奏;缺一不可。