在軟體開發的實戰中,適配器模式的應用頻率極高。從早期的 ListView、GridView 到現今主流的 RecyclerView,無一不依賴 Adapter 進行資料綁定。然而,開發過程中效能優化的瓶頸與易錯點,往往也集中在適配器的實作細節上。本文將深入剖析適配器模式的設計哲學、兩種核心實作形式,並透過經典的「充電器」案例演示其運作機制。
適配器模式的本質,在於將兩個不兼容的介面轉換匹配,使它們能在不修改原有程式碼的前提下協同工作。想像一個場景:現有系統需整合新廠商的類別庫,但新舊介面定義截然不同。若無法修改廠商原始碼,或不願為單一應用重構既有介面,此時引入一個「適配器」類別,將新介面轉接為系統預期的介面,即可輕鬆化解整合難題。適配器宛如一位中介者,將客戶端的請求轉譯為被適配者能理解的操作。
透過繼承 Adaptee(被適配者)並實作 Target(目標介面)達成轉接。優點在於可重寫被適配者的方法,靈活性較高;缺點是採用靜態繼承,一旦建立即與特定被適配者綁定,且無法適配被適配者的子類別,違反「合成優於繼承」的設計原則。
持有 Adaptee 的引用,透過委派方式完成介面轉換。這完美遵循「組合優於繼承」原則,不僅能適配介面及其所有子類別,且被適配者的方法不會暴露在適配器中,介面更乾淨,耦合度更低,擴充性與維護性均優於類適配器。
// 目標介面:客戶端期望的 5V 電壓
public interface Voltage {
int getVoltage();
}
// 被適配者:大陸 220V 電壓
public class ChinaVoltage implements Voltage {
public int getVoltage() { return 220; }
}
// 手機電壓(Adaptee):實際僅提供 5V
public class PhoneVoltage {
public int getPhoneVoltage() { return 5; }
}
// 物件適配器:充電器
public class Charger implements Voltage {
private PhoneVoltage phoneV;
public Charger(PhoneVoltage phoneV) { this.phoneV = phoneV; }
public int getVoltage() { return phoneV.getPhoneVoltage(); } // 轉接邏輯
}
// 客戶端測試
public class Client {
public static void main(String[] args) {
PhoneVoltage phone = new PhoneVoltage();
Charger charger = new Charger(phone);
System.out.println("轉換後電壓: " + charger.getVoltage()); // 輸出 5
}
}
適配器模式是解決介面不兼容的經典方案,Android 開發中無處不在。掌握其「物件適配器」的組合實作精髓,能讓你在面對系統整合、第三方 SDK 接入等場景時,寫出更靈活、可維護的程式碼。