「程式被持續演化時,其複雜度會不斷上升,除非有人投入心力去維持或降低它。」 — 萊曼複雜度遞增定律(Lehman’s law of Increasing Complexity)

這本書談什麼?#

軟體必須持續演化以應付使用者不斷增加的需求,但軟體無形的本質讓「持續變更」這件事極難管理。最終的結果,往往是軟體品質低落,並累積大量的技術債(technical debt)

本書的核心命題:

  • 透過辨識並處理設計中的「壞味道」(smells),可以提升軟體品質、降低技術債。
  • 借用醫療領域的比喻:「好醫師熟知藥方,偉大的醫師則理解病灶。」同理:

好的設計者熟知設計解法;偉大的設計者能在設計中辨識「病灶」(壞味道),理解其成因,並運用扎實的設計原則加以治療。

本書的內容範圍#

本書呈現一份包含 **25 個結構性設計壞味道(structural design smells)**及其對應重構方法的目錄,以協助讀者管理技術債。

整體編排有幾個關鍵設計:

  • 以設計原則為分類骨幹:作者採用 Booch 提出的四項基礎設計原則作為分類框架——抽象(abstraction)、封裝(encapsulation)、模組化(modularization)、階層(hierarchy)。
  • 依違反的原則命名壞味道:每個壞味道都揭示其違反的原則、可能的成因、受影響的品質屬性。
  • 真實案例與重構建議:每個壞味道都附上實務範例與軼事,並提供對應的潛在重構解法。
  • 明確區分「設計層級」與「結構性」壞味道:本書聚焦於「設計層級」的「結構性」壞味道,不涵蓋程式碼層級或行為性壞味道。

壞味道的影響取決於它出現的設計脈絡。本書也會探討某些情境下壞味道是被「刻意引入」的——例如語言或平台限制,或為了實現整體設計目標。

適合讀者#

讀者類型從本書能獲得什麼
軟體架構師與設計者立即可用的設計改善構想;對「微小決策如何衝擊整體品質」有更深體會
軟體開發者認識到開發捷徑與隱性設計決策的長遠代價,學會辨識並處理問題
專案經理理解進度延誤與成本超支背後的技術債,並重視重構的價值
學生透過「錯誤應用原則所產生的壞味道」反向學習設計原則的真正意義

閱讀本書的先備知識#

  • 物件導向程式設計與設計的基礎概念
  • 至少熟悉一種物件導向語言(C++、Java、C#)
  • 物件導向核心概念:類別(class)、抽象類別(abstract class)、介面(interface)、繼承(inheritance)、委派(delegation)、組合(composition)、多型(polymorphism)

本書的閱讀路徑#

整本書邏輯上分為三大區塊:

  1. 設定脈絡(第 1–2 章)
    • 第 1 章介紹技術債的概念、成因與影響。
    • 第 2 章介紹設計壞味道,以及本書採用的「以原則為基礎」分類方案。
  2. 壞味道目錄(第 3–6 章)
    • 對應四項基礎原則,每章列出該原則被違反時所產生的壞味道。
    • 每個壞味道附範例、品質衝擊、重構建議。
  3. 反思與實踐(第 7–8 章)
    • 第 7 章探討壞味道與設計脈絡之間的互動,以及壞味道彼此間的交互影響。
    • 第 8 章提供在真實專案中償還技術債的實務指引。

本書不必從頭讀到尾。可依目錄挑選感興趣的章節跳讀。

為什麼撰寫本書?#

作者在研究設計品質時發現,許多工程師雖具備設計原則的理論知識,卻不知如何在實務中應用,導致壞味道叢生。在彙整出 530 個壞味道後,他們嘗試各種分類方式皆不滿意,最終得到關鍵洞察:

將每個壞味道視為「違反一個或多個底層設計原則」時,我們不但能更深入地理解這個壞味道,更能自然地導向潛在的重構方向。

基於此洞察,他們以 Booch 的四項基礎原則為分類依據,最終整理為本書的設計壞味道目錄。