
你有沒有去日本旅遊帶了一堆 3C 產品,結果發現插頭規格不同的經驗?你不會為了這個把手機的充電孔改掉吧?你會買一個轉接頭。
Adapter Pattern 就是程式世界的轉接頭。
先講結論
Adapter 做的事情很單純:把介面 A 包一層,讓它看起來像介面 B。舊系統不用改、新系統也不用遷就,中間放一個 Adapter 就搞定了。
classDiagram class PaymentProcessor { <<interface>> +processPayment(amount)* boolean } class OldPaymentSystem { +makePayment(value) boolean } class PaymentAdapter { -oldSystem : OldPaymentSystem +processPayment(amount) boolean } PaymentProcessor <|.. PaymentAdapter PaymentAdapter --> OldPaymentSystem : 轉接呼叫 note for PaymentAdapter "將 processPayment()\n轉換為 makePayment()"
最常見的場景
你接手了一個案子,新系統的支付介面叫 processPayment(amount),但舊系統的方法叫 makePayment(value)。PM 說「舊系統不能動」,你怎麼辦?

// 舊系統——不能改、不敢改、改了會爆
class OldPaymentSystem {
makePayment(value) {
console.log(`Processing payment of $${value} via old system`);
return true;
}
}
// Adapter:把 processPayment 轉成 makePayment
class PaymentAdapter {
constructor() {
this.oldSystem = new OldPaymentSystem();
}
processPayment(amount) {
return this.oldSystem.makePayment(amount);
}
}
// 新系統只認得 processPayment,完全不知道背後是舊系統
const processor = new PaymentAdapter();
processor.processPayment(100);就這樣。Adapter 沒有什麼花俏的操作,它的價值在於「不動舊的、不改新的、中間包一層」。
什麼時候該用?什麼時候不該用?
該用:舊 API 改不了、第三方套件介面不合、API 版本升級要向下相容
不該用:如果你能直接改原始碼,那就改。包一層 Adapter 本質上是在增加間接性,能不包就不包。
Adapter Pattern 就像那個萬用轉接頭——不優雅,但能救命。不過你帶了七八個轉接頭串在一起的時候,就該考慮換一條線了。