適配器模式將一個類的接口轉換為客戶端期望的另一個接口,使原本不兼容的類能夠協同工作。生活中常見的「變壓器」(220V 轉 110V)即是典型適配器。本文對比類適配器與對象適配器兩種形式,並結合 Android Adapter、JDBC 驅動等實戰場景深度解析。
| 維度 | 類適配器 | 對象適配器 |
|---|---|---|
| 實現方式 | 繼承 Adaptee,實現 Target | 組合 Adaptee 實例,實現 Target |
| 耦合度 | 高(繼承為白箱復用) | 低(組合為黑箱復用) |
| 靈活性 | 只能適配具體 Adaptee 及其子類 | 可適配 Adaptee 及其所有子類 |
| 覆寫行為 | 可覆寫 Adaptee 方法 | 難以覆寫 Adaptee 方法 |
| Java 適用性 | 受單繼承限制,較少用 | 首選形式,符合組合優於繼承原則 |

// 目標接口:客戶端期望的接口
public interface Target {
void request();
}
// 被適配者:現有不兼容接口
public class Adaptee {
public void specificRequest() {
System.out.println("Adaptee 特有功能");
}
}
// 類適配器:繼承 Adaptee + 實現 Target
public class ClassAdapter extends Adaptee implements Target {
@Override
public void request() {
specificRequest(); // 直接復用父類方法
}
}
// 客戶端調用
public class Client {
public static void main(String[] args) {
Target target = new ClassAdapter();
target.request(); // 輸出:Adaptee 特有功能
}
}
// 對象適配器:持有 Adaptee 引用
public class ObjectAdapter implements Target {
private Adaptee adaptee; // 組合
public ObjectAdapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest(); // 委託調用
}
}
// 客戶端:可動態切換不同 Adaptee 實現
public class Client {
public static void main(String[] args) {
Target adapter1 = new ObjectAdapter(new Adaptee());
Target adapter2 = new ObjectAdapter(new SubAdaptee()); // 適配子類
adapter1.request();
adapter2.request();
}
}
本質:將數據源(List<T>、Cursor、數組)適配為 View 列表。
BaseAdapter 實現 ListAdapter 接口(Target),內部持有數據集合(Adaptee),getView() 將數據項轉換為 View。
對象適配器優勢:同一 Adapter 類可適配 ArrayList、LinkedList、Cursor 等任意數據源,只需傳入不同實例。
// Target: java.sql.Driver 接口
// Adaptee: com.mysql.jdbc.Driver、oracle.jdbc.OracleDriver 等
// 適配器: DriverManager 內部註冊表
DriverManager.registerDriver(new com.mysql.jdbc.Driver()); // 適配 MySQL
Connection conn = DriverManager.getConnection(url, user, pwd); // 統一獲取連接
各廠商實現 java.sql.Driver(Target),DriverManager 作為適配器管理註冊表,屏蔽具體驅動差異。
// Adaptee: FileInputStream(字節流)
// Target: Reader(字符流)
// 適配器: InputStreamReader
Reader reader = new InputStreamReader(new FileInputStream("data.txt"), "UTF-8");
reader.read(charBuffer); // 直接按字符讀取,自動處理解碼
裝飾器模式與適配器模式結合:InputStreamReader 適配字節流為字符流,BufferedReader 再裝飾增加緩衝。
DispatcherServlet 調用 HandlerAdapter.handle() 統一處理 Controller、HttpRequestHandler、Servlet 等不同類型 Handler,屏蔽底層差異。
適配器模式是「兼容舊系統、整合第三方庫、屏蔽底層差異」的利器。對象適配器憑藉低耦合、高靈活、符合組合復用原則,成為 Java 開發首選。理解其與裝飾器、代理、外觀模式的邊界,能讓架構決策更精準。