轉接器 (Adapter)

★★★★Studied

FromDesign Patterns (GoF)大話設計模式Design Patterns Explained

📚 From the Books

轉接器 (Adapter)ConceptStructural

把一個既有類別「不相容的介面」包成 client 期望的介面,讓兩邊在不改原始碼的前提下接得起來。重點是轉換介面,不是加強行為。

🧠 When to Use

TIP

訊號:你手上有個好用的類別(常是第三方或 legacy),但它的方法名 / 簽章跟你的程式期望的介面對不上。

⚖️ Structure & Variants

Object Adapter — 用組合包裝(首選)
// client 期望的目標介面
interface PaymentGateway { fun pay(cents: Int): Boolean }

// 第三方類別,介面不相容、無法修改
class StripeSdk { fun charge(dollars: Double, currency: String): Stripe.Result { /* ... */ } }

// Adapter 持有 adaptee,做介面與單位的轉換
class StripeAdapter(private val stripe: StripeSdk) : PaymentGateway {
    override fun pay(cents: Int): Boolean =
        stripe.charge(cents / 100.0, "USD").isSuccess
}

val gateway: PaymentGateway = StripeAdapter(StripeSdk())
  • 組合持有 adaptee,彈性高、能同時轉接多個物件。
Class Adapter — 用繼承
  • 直接繼承 adaptee(多重繼承的語言)或實作其介面,覆寫成目標介面。
  • Kotlin / Java 單繼承下較受限;綁死特定 adaptee 類別,無法在執行期替換。
  • 一般偏好 object adapter,因為它符合組合優於繼承
和 Decorator / Facade 的差別
  • Adapter改變介面,把 A 轉成 B,目的是相容,通常一對一。
  • Decorator:介面不變,加強行為,可疊加。
  • Facade:對一整組子系統提供新的簡化入口,不是一對一轉接。

⚠️ Misuse & Anti-patterns

🔑 Takeaways

✍️ My Notes

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

📖 Further Reading