適配器模式將不兼容的介面轉換為客戶期望的介面,使原本無法協作的類能夠協同工作。本文通過「電腦 USB 接口適配圓口鍵盤」經典案例,完整展示類適配器(多重繼承/實現)與對象適配器(組合委派)兩種實現,並給出選型建議。
USB(含 receive() 方法)KeyBoard(含 input() 方法,圓口)Computer 僅支援 USB 介面// 目標介面
interface USB { void receive(); }
// 被適配類
class KeyBoard { public void input() { System.out.println("鍵盤輸出數據"); } }
// 類適配器:繼承 KeyBoard、實現 USB
class USBAdapter extends KeyBoard implements USB {
public void receive() {
System.out.println("USB適配器:讓圓口鍵盤接入USB電腦");
super.input(); // 直接復用父類方法
}
}
// 客戶端
public class Computer {
public void show(USB usb) {
usb.receive();
System.out.println("電腦顯示輸出數據");
}
public static void main(String[] args) {
new Computer().show(new USBAdapter());
}
}
// 對象適配器:持有 KeyBoard 引用
class USBAdapter implements USB {
private KeyBoard keyboard;
public USBAdapter(KeyBoard keyboard) { this.keyboard = keyboard; }
public void receive() {
System.out.println("USB適配器:讓圓口鍵盤接入USB電腦");
keyboard.input(); // 委派給被適配對象
}
}
// 客戶端調用變化
public static void main(String[] args) {
KeyBoard kb = new KeyBoard();
USB usb = new USBAdapter(kb); // 注入具體鍵盤實例
new Computer().show(usb);
}
| 維度 | 類適配器 | 對象適配器 |
|---|---|---|
| 核心機制 | 繼承(extends)+ 實現(implements) | 組合(持有引用)+ 委派 |
| 適配範圍 | 只能適配單一具體類(Java 單繼承) | 可適配該類及其所有子類 |
| 覆寫靈活性 | 可覆寫被適配類方法 | 無法覆寫,需子類化後再適配 |
| 耦合度 | 較高(繼承關係) | 較低(介面依賴) |
| 對象適配器優勢 | ✓ 符合「組合優於繼承」 ✓ 一個適配器服務多種鍵盤子類 ✓ 不破壞封裝性 ✓ 易於測試 | |
優先使用對象適配器。除非必須覆寫被適配類方法,或被適配類為 final 無法繼承時,才考慮類適配器(或結合代理模式)。
InputStreamReader 適配 InputStream → Reader(字節流轉字符流)HandlerAdapter 適配各種 Controller 介面若需雙向轉換,可實現雙重介面:
class TwoWayAdapter implements USB, PS2 {
private KeyBoard kb;
private Mouse mouse;
// 同時實現 USB.receive() 和 PS2.connect()
}
適配器模式是系統集成、遷移、解耦的核心利器,靈活運用組合式適配器能顯著降低架構耦合度。