在 Enterprise JavaBeans (EJB) 架構中,實體 Bean 代表持久化數據對象,而會話 Bean 與訊息驅動 Bean 則屬於業務邏輯對象。一般原則建議僅將業務對象(會話 Bean)暴露於 Web 層,由其內部協調實體 Bean 完成數據存取。然而,現實開發中常因便利性需求,允許用戶直接操作數據對象,導致實體 Bean 的遠程介面直接暴露於應用層甚至外部網絡,引發兩大風險:
引入會話 Bean 作為實體 Bean 與客戶端之間的中介層,封裝數據存取邏輯與業務規則。此模式不僅隔離了數據結構,更賦予了業務語義的操作介面。
以 MovieManager 會話 Bean 為例,當實體 Bean Movie 的 getDirector() 因支援多導演改為 getDirectors() 返回列表時,會話 Bean 可保留舊方法並內部委派新實現:
public Person getDirector() {
List directors = getDirectors(); // 調用新方法
return (directors != null && !directors.isEmpty()) ? (Person) directors.get(0) : null;
}
此做法確保現有客戶端代碼零修改繼續運行,同時將遞移邏輯封裝於業務層,避免污染實體 Bean。
進一步以業務場景重新設計會話 Bean 介面。例如合併導演、製片、執行製片查詢為 getCrew(String movieName),合併演員、替身查詢為 getCast(String movieName)。會話 Bean 內部協調多實體 Bean,組裝業務視圖數據:
public List getCrew(String movieName) throws NamingException, RemoteException {
List crew = new LinkedList();
Movie movie = movieHome.findByName(movieName);
crew.addAll(movie.getDirectors());
crew.addAll(movie.getProducers());
crew.addAll(movie.getExecutiveProducers());
return crew;
}
此舉實現三大收益:
將兼容邏輯塞入實體 Bean 看似便捷,實則導致實體 Bean 膨脹為「工具類」,隨業務迭代方法數量指數級增長,嚴重違背「實體 Bean = 數據對象」的設計定位。會話 Bean 天生適合承擔協調、轉換、驗證等業務輔助職責,才是正確歸宿。
Session Facade 模式以輕量級會話 Bean 為樞紐,實現「數據層隔離、介面演進平滑、業務語義顯性化」三重目標。它是 EJB 分層架構的基石,亦為後續引入 Business Interface、DTO 等進階模式鋪平道路。