「抽象原則主張透過化簡與泛化來簡化實體:化簡靠移除非必要細節,泛化靠識別並具體化共同且重要的特徵。」

抽象的力量:從一張笑臉開始#

世界上有上百萬張臉,每張幾乎都是獨一無二的。為什麼我們一眼就能說出「這是一張人臉」?因為我們做了抽象

  • 化簡:去除髮型、髮色等非本質細節。
  • 泛化:抓住共通特徵——兩隻眼睛、嘴角上揚就是微笑。

Figure 3.1: 人類的笑臉

公司商標、交通號誌、數學符號、程式語言……都是抽象的具體應用。抽象既是溝通工具,也是解決問題的利器。

現代軟體動輒上百萬行程式碼,要馴服這份複雜度,抽象是最強大的武器之一。

應用抽象的五項使能技巧(enabling techniques)#

Figure 3.2: 應用抽象原則的使能技巧

要在軟體設計中真正落實抽象原則,書中歸納出五項關鍵技巧:

  • 提供清晰的概念邊界與唯一的身份
    • 不要把一組相關資料(例如日期的年月日、矩形的座標、圖片的屬性)四處傳遞。
    • 將它們抽出為獨立的抽象,賦予它清楚的邊界與識別名稱。
  • 對應問題領域中的實體(map domain entities)
    • 問題領域中存在的概念(例如「剪貼畫 ClipArt」),解決方案中應該也有對應的抽象。
    • 名稱與概念對齊,能大幅降低理解成本。
  • 確保連貫性與完整性
    • 抽象一旦承擔某個責任,就要把該責任完整地支援。
    • 例如:若提供「停用」就要提供「啟用」;若提供「隱藏」就要提供「顯示」。
  • 指派單一且有意義的責任
    • 每個抽象都應有「唯一且非瑣碎」的責任。
    • 不要把格式轉換等多重責任硬塞進 Image 類別;也不該為了存放常數 π 而建立 PI 類別。
  • 避免重複
    • 每個抽象——名稱與實作——應只在設計中出現一次。
    • 同名的 List 出現在 GUI、資料結構、TODO 清單三處時,使用者會混亂。
    • 重複的實作(例如把優先佇列的程式碼複製到排程器)會帶來雙倍維護成本。

抽象壞味道與使能技巧的對應#

本章七個壞味道正好一一對應到上述使能技巧的違反

Figure 3.3: 違反抽象原則所產生的壞味道

設計壞味道違反的使能技巧
Missing Abstraction提供清晰的概念邊界與唯一身份
Imperative Abstraction對應問題領域中的實體
Incomplete Abstraction確保連貫性與完整性
Multifaceted Abstraction、Unnecessary Abstraction、Unutilized Abstraction指派單一且有意義的責任
Duplicate Abstraction避免重複

在本章中,「抽象」一詞若無特別說明,皆指類別(class)或介面(interface)