適配器模式屬於結構型模式,目的在於將兩個介面不相容的類別協同工作。核心角色:
// 目標介面
public interface SquarePeg {
void insert(String str);
}
// 被適配者(無法修改)
public class RoundPeg {
public void insertIntoHole(String msg) {
System.out.println("RoundPeg: " + msg);
}
}
// 適配器:實作 Target,持有 Adaptee 實例
public class PegAdapter implements SquarePeg {
private final RoundPeg roundPeg;
public PegAdapter(RoundPeg peg) { this.roundPeg = peg; }
@Override
public void insert(String str) {
roundPeg.insertIntoHole(str); // 委派並轉換介面
}
}
優點:單一職責、可適配 Adaptee 所有子類、符合「組合優於繼承」原則。
public class PegAdapter extends RoundPeg implements SquarePeg {
@Override
public void insert(String str) {
super.insertIntoHole(str); // 直接呼叫父類方法
}
}
缺點:Java 不支援多重繼承,無法同時適配多個 Adaptee;與 Adaptee 耦合度高。
實作兩個目標介面,可在兩種脈絡下互相轉換:
public interface RoundPeg { void insertIntoHole(String msg); }
public interface SquarePeg { void insert(String str); }
public class TwoWayAdapter implements RoundPeg, SquarePeg {
private final RoundPeg round;
private final SquarePeg square;
public TwoWayAdapter(RoundPeg r) { this.round = r; }
public TwoWayAdapter(SquarePeg s) { this.square = s; }
@Override public void insertIntoHole(String msg) { square.insert(msg); }
@Override public void insert(String str) { round.insertIntoHole(str); }
}
搭配反射(Reflection)在執行期動態發現並載入適配器,適用於外掛架構。
Collections.list(Enumeration)、Arrays.asList()| 原則 | 適配器模式體現 |
|---|---|
| 開放封閉原則 (OCP) | 新增適配器不修改既有 Adaptee/Client |
| 單一職責原則 (SRP) | 介面轉換邏輯集中在 Adapter |
| 依賴倒置原則 (DIP) | Client 依賴 Target 抽象,非具體 Adaptee |
| 里氏替換原則 (LSP) | Adapter 可透明替換 Target 實作 |
適配器模式是「介面不兼容」的標準解法。實務上優先選擇物件適配器(組合),搭配介面導向設計,即可在不修改既有程式碼前提下,讓舊資產無縫接入新架構。