對介面寫程式,而非實作 (Program to an Interface)

★★★★★Studied

FromDesign Patterns (GoF)Design Patterns Explained

📚 From the Books

對介面寫程式,而非實作 (Program to an Interface)ConceptPrinciples

不要把變數宣告為具體 class 的實例,只依賴抽象所定義的 interface。 這是 GoF 全書 Design Pattern 的共通主題,也是它三大核心策略之首(另兩者:偏好組合勝於繼承、找出變動點並封裝)。因為 polymorphism 讓擁有相同 interface 的物件能在 run-time 互相替換,你的程式便不再被綁死在某個實作上。它跟 DIP 是同一件事的兩面:DIP 說「依賴方向朝抽象」,這條說「宣告型別用抽象」。

🧠 When to Use

TIP

訊號:你的變數、參數、回傳型別滿是具體 class 名(ArrayListSqlProductRepository),想換實作就得改一整片呼叫端;或你正在寫一個希望被別人擴充的 framework。

⚖️ Structure & Variants

Interface、Type 與 Polymorphism
  • Interface=物件所有 operation signature 的集合,定義了它能接收哪些請求。
  • Type=特定 interface 的名稱;一個物件可擁有多個 type,不同物件也可共享同一 type。
  • Dynamic binding 讓請求在 run-time 才綁到具體實作;Polymorphism 讓相同 interface 的物件能互換。
// ❌ 綁死具體實作:換 repository 就得改呼叫端
val repo: SqlProductRepository = SqlProductRepository(conn)

// ✅ 宣告成抽象,具體型別只在建立處出現一次
val repo: ProductRepository = SqlProductRepository(conn)
// repo 之後可換成 InMemoryProductRepository、CachingProductRepository… 呼叫端不動
  • 兩個好處:呼叫端不必知道用的是哪個實作,也不必知道實作所屬的 class——只要它符合 interface。
Class inheritance vs Interface inheritance

GoF 特別區分兩種繼承,很多語言(如 C++)混為一談,但實務上分野關鍵:

  • Class inheritance(實作繼承):定義物件的實作,是程式碼與表示的共享機制。
  • Interface inheritance / subtyping:定義物件何時可替代另一物件。

「對介面寫程式」依賴的是後者——許多 pattern(如 Chain of Responsibility)要求物件共享 type 卻不必共享實作。

NOTE

這也連到 GoF 另一條原則:Favor object composition over class inheritance。組合(黑箱重用)透過 interface 互動、不破壞封裝、可在 run-time 替換;繼承(白箱重用)是 compile-time 綁定,父類變動會連累子類。詳見 組合優於繼承。 :::

抽象類別 vs 介面:不是誰比較好,而是各有側重

《Design Patterns Explained》從設計層點出差異:

  • 抽象類別:把相關實作收攏(focus on encapsulating implementations),可帶共同狀態與預設行為,仍可遵循依賴倒置。
  • 介面:思考「使用方需要什麼樣的介面」,可拆得更細、更精簡(thin interface),趨向 ISP

實務組合拳:先用介面定義最小契約,再用抽象類別實作以共享預設行為。

它是 GoF 模式的共通骨幹

「對介面寫程式」不是孤立原則,而是散落在多數模式裡的底層假設:

  • Strategy / State:把演算法、狀態表示為實作共同 interface 的物件,run-time 抽換。
  • Bridge / Abstract Factory:抽象與實作各自沿 interface 變動,互不牽連。
  • Decorator / Proxy / Adapter:包一層、共享(或轉換)interface。

Framework 強調 design reuse 而非只是 code reuse,並帶來控制反轉——成熟的 framework 通常整合多個 pattern,全都建立在「消費者只依賴 interface」之上。

⚠️ Misuse & Anti-patterns

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading