「介面」是 Java 核心機制之一,卻常被誤解為「脫褲子放屁」的多餘代碼。本文透過電腦主板介面(USB、SATA、PCIe 等)的硬體標準類比,深入淺出闡述介面的本質是「標準與契約」,並實戰展示三大核心應用場景:標準化資料存取、多型參數傳遞、標記介面實現框架級功能開關。
主板廠商不生產 CPU、記憶體、硬碟,但定義了 Socket AM4、DDR4 288-pin、SATA 3.0 等介面標準。任何符合標準的零件皆可插上即用,廠商間零耦合、自由組合。軟體介面同理:定義規範,分離「做什麼」與「怎麼做」。
public interface CPU接口 {}
public interface SocketAM4 extends CPU接口 {}
public class Ryzen5700X implements SocketAM4 {} // AMD 實作
public class 主板 { public 主板(SocketAM4 cpu) {} } // 僅依賴介面
定義 IDAL 介面封裝 CRUD,SqlDAL/OracleDAL/MySqlDAL 分別實作。業務層 Business 僅依賴 IDAL,透過 web.config 指定實作類別,達到零代碼修改切換資料庫。
public interface IDAL { void Delete(String pk); }
public class SqlDAL implements IDAL { ... }
public class Business {
private IDAL dal = (IDAL) Class.forName(config.get("DatabaseType")).newInstance();
public void Remove(String id) { dal.Delete(id); }
}
優點:高內聚低耦合、團隊平行開發、單元測試易 Mock。
Hibernate save/update 接受 Object 過於寬鬆。引入空介面 IModel extends Serializable,所有實體 implements IModel。通用 DaoBase.add(IModel) 僅接受實體類別,編譯期即可攔截錯誤傳入。
public interface IModel extends Serializable {}
public class Account implements IModel { ... }
public class DaoBase {
public boolean add(IModel model) { getHibernateTemplate().save(model); return true; }
}
IRequiresSessionState、IReadOnlySessionState 均為空介面。ASP.NET 執行緒池在 HttpContext.Handler 設定時檢查 instanceof,決定是否綁定 Session。同理 AjaxPro 透過屬性標記決定同步/非同步 Handler 是否實作這兩個介面。
public class AjaxSyncHttpHandlerSession extends AjaxSyncHttpHandler implements IRequiresSessionState {}
// 框架內部:
if (handler instanceof IRequiresSessionState) ctx.RequiresSessionState = true;
這是「標記介面模式」經典應用:零方法定義,純粹賦予類別身份標識,供框架反射檢查。
| 層面 | 說明 |
|---|---|
| 標準契約 | 定義行為規範,實作類別保證符合契約 |
| 解耦依賴 | 高層模組依賴抽象,不依賴具體實作 |
| 多型替換 | 執行期動態切換實作(Strategy、Plugin 架構) |
| 類型約束 | 參數類型收斂,編譯期保證類型安全 |
| 身份標記 | 標記介面賦予元資料,驅動框架行為 |
介面不是多餘,而是架構彈性的基石。善用介面,才能打造可維護、可擴展、可測試的系統。