本章主軸#
轉接模式(Adapter)的核心:有個物件做的事是對的、但介面不對。Adapter 為它套上一層,讓它能以期望的介面被使用。它在許多其他模式中都會被搭配使用,是極為常見的工具。
GoF 對 Adapter 的意圖描述#
把一個類別的介面轉換成 client 期望的另一個介面。Adapter 讓原本因介面不相容而無法合作的類別能夠協同工作。
一個啟發式範例:Shape 與 XXCircle#
設想需求:
- 設計 Point、Line、Square 等類別,皆有
display行為 - Client 不應在意自己拿到的是哪種具體形狀
用繼承達成多型#
- 抽出抽象類別
Shape,定義display、fill、undisplay等方法 - 讓 Point、Line、Square 各自繼承並實作

Figure 7-1: 我們有的(Points、Lines、Squares)對 Client 而言應該都是 Shape

Figure 7-3: 抽象 Shape 介面下的 Point、Line、Square 實作了 display、fill、undisplay 等方法
來了個新需求:加入圓形#
- 同事 Jill 已經寫好
XXCircle,方法名為displayIt、fillIt、undisplayIt

Figure 7-4: Jill 的 XXCircle 類別——名稱與參數都和 Shape 不一致
- 但無法直接套用:
- 方法名稱與參數不同
XXCircle沒有繼承Shape
- 改 Jill 的程式既冒風險、又破壞她現有的使用者
解法:包一層 Adapter#
- 建立
Circle類別,繼承Shape Circle內部持有一個XXCircleCircle.display()內部委派給XXCircle.displayIt()
class Circle extends Shape {
private XXCircle myXXCircle;
public Circle() {
myXXCircle = new XXCircle();
}
public void display() {
myXXCircle.displayIt();
}
}這樣便保留多型,又不必改動 XXCircle。

Figure 7-6: Adapter 模式的通用結構——Adapter 包住 Adaptee 並符合 Target 介面
Adapter 的關鍵特性#
| 欄位 | 內容 |
|---|---|
| Intent | 把無法控制的既有物件,匹配到特定介面 |
| Problem | 系統有正確的資料與行為,但介面不對 |
| Solution | Adapter 提供一層具備所需介面的包裝 |
| Consequences | 讓既有物件得以納入新類別結構,而不被原介面所限 |
| Implementation | 把既有類別包進新類別,新類別實作所需介面、轉呼叫包進去的物件 |
Adapter 的兩種變體#
- Object Adapter:透過「持有」既有物件來實作(前述例子)
- Class Adapter:用多重繼承——
public繼承所需抽象類別、private繼承既有類別
Object Adapter 與 Class Adapter 的取捨牽涉問題領域中的力量;GoF 書中第 142–144 頁有詳細討論。
部分功能不全的 Adapter#
當被包進來的物件只能滿足一部分需求時,仍可使用 Adapter:
- 既有方法 → 透過 Adapter 轉發
- 缺少的方法 → 在 Adapter 類別內自行實作
雖然不像「完美包裝」那樣優雅,但仍可避免從零實作整套功能。
Adapter vs Facade#

Figure 7-7: Client 透過介面使用既有但介面不對的物件
兩者乍看都是「包裝(wrapper)」,常被混淆:
| 比較項 | Facade | Adapter |
|---|---|---|
| 是否有既有類別 | 是 | 是 |
| 是否要符合特定介面 | 否 | 是 |
| 是否需要多型行為 | 否 | 通常是 |
| 是否提供更簡單介面 | 是 | 不一定 |
重點差異:Facade 簡化 介面,Adapter 轉換 介面。
也常聽見人說「Facade 包多個類別、Adapter 只包一個」。雖然多數情況如此,但這並非模式的定義:Facade 可以包單一複雜物件,Adapter 也可以包多個小物件來合成一個介面。
與 CAD/CAM 問題的關聯#
V2 中的 OOGFeature 物件做的事是對的,但介面非作者設計,無法直接套用為 Feature 的子類別。Adapter 正是把 OOGFeature 包成符合 Feature 介面的最佳工具。
本章要記住的事#
- Adapter 讓「正確但介面不對」的物件得以被納入既有結構
- 它幾乎是其他模式(特別是 Bridge、Abstract Factory)必備的搭檔
- 設計時可以先不必擔心既有類別的介面——後續 Adapter 永遠救得了
- Facade 是「簡化」介面、Adapter 是「轉換」介面,別搞混