設計模式可以幫助用戶在更高層次上抽象細節
更好地理解體系結構
如果比較熟悉 GoF 設計模式和 JavaServer Faces (JSF) 框架
本文可以幫助您洞察 JSF 框架中使用的設計模式
深入理解其工作原理
本文探討了 JSF 框架中使用的設計模式
詳細討論的設計模式包括 Singleton
Model
View
Controller
Factory Method
State
Composite
Decorator
Strategy
Template Method 和 Observer 模式
設計模式和 JavaServer Faces (JSF) 技術
首先簡要地介紹一下模式和 JSF 框架
模式設計模式是對問題和解決方案進行抽象的普遍適用的方法因為模式是所有開發人員和架構師公認的所以模式可以節約時間和資源用外行話來說模式就是關於某個人所共知的問題的經過驗證的解決方案模式可以重用重用使得解決方案更健壯
Java Server Faces JSF 體系結構是一種 Web 應用程序框架它是 Java Community Process (JCP) 推動的有望成為 Web 應用程序開發的標准框架目前用於開發 Web 應用程序的框架有 多個這說明迫切需要實現框架的標准化這正是 JSF 框架的目標!
深入剖析 JSF 模式 現在我們來討論 JSF 體系結構中的各種設計模式
本文將詳細討論 Singleton
Model
View
Controller
Factory Method
State
Composite
Decorator
Strategy
Template Method 和 Observer 設計模式
我將分析每種模式的用途及其在 JSF 框架中的作用
Singleton 模式
Singleton 模式的目的是保證類只有一個實例被加載
該實例提供一個全局訪問點
當啟動具有 JSF 支持的 Web 應用程序時
Web 容器初始化一個 FacesServlet 實例
在這個階段
FacesServlet 對每個 Web 應用程序實例化 Application 和 LifeCycle 實例一次
這些實例就采用眾所周知的 Singleton 模式
通常只需要該類型的一個實例
使用 JSF 的 Web 應用程序只需要 Application 和 LifeCycle 類的一個實例
LifeCycle 管理多個 JSF 請求的整個生命期
因為其狀態和行為在所有請求之間共享
這些對象采用 Singleton 模式合情合理
LifeCycle 維護的 PhaseListeners 也是 Singleton 模式的
PhaseListeners 由所有 JSF 請求共享
在 JSF 框架中可以廣泛使用 Singleton 模式
以減少內存占用和提供對象的全局訪問
NavigationHandler(用於確定請求的邏輯結果)和 ViewHandler(用於創建視圖)也是使用 Singleton 模式的例子
Model
View
Controller (MVC)
MVC 模式的目的是從數據表示(View)中將數據(即 Model)分離出來
如果應用程序有多種表示
可以僅替換視圖層而重用控制器和模型代碼
類似的
如果需要改變模型
可以在很大程度上不改變視圖層
控 制器處理用戶動作
用戶動作可能造成模型改變和視圖更新
當用戶請求一個 JSF 頁面時
請求發送到 FacesServlet
FacesServlet 是 JSF 使用的前端控制器 servlet
和其他很多 Web 應用程序框架一樣
JSF 使用 MVS 模式消除視圖和模型之間的耦合
為了集中處理用戶請求
控制器 servlet 改變模型並將用戶導航到視圖
FacesServlet 是 JSF 框架中所有用戶請求都要經過的控制器元素
FacesServlet 分析用戶請求
使用托管 bean 對模型調用各種動作
後台(backing)或托管(managed)bean 就是該模型的例子
JSF 用戶界面(UI)組件是視圖層的例子
MVC 模式把任務分解給具有不同技能的開發人員
使這些任務能夠同時進行
這樣 GUI 設計人員就可以使用豐富的 UI 組件創建 JSF 頁面
同時後端開發人員可以創建托管 bean 來編寫專門的業務邏輯代碼
Factory Method 模式
Factory Method 模式的目的是定義一個用於創建對象的接口
但是把對象實例化推遲到子類中
在 JSF 體系結構中
Factory Method 模式被用於創建對象
LifeCycleFactory 是一個創建和返回 LifeCycle 實例的工廠對象
LifeCycleFactory 的 getLifeCycle (String LifeCycleId) 方法采用 Factory Method 模式
根據 LifeCycleId 創建(如果需要)並返回 LifeCycle 實例
自定義的 JSF 實現可以重新定義 getLifeCycle 抽象方法來創建自定義的 LifeCycle 實例
默認的 JSF 實現提供默認的 LifeCycle 實例
此外
對於每個 JSF 請求
FacesServlet 都從 FacesContextFactory 得到 FacesContext
FacesContextFactory 是一個抽象類
公開了 getFacesContext API
JSF 實現提供了 FacesContextFactory 和 getFacesContext API 的具體實現
這是另外一個使用 Factory Method 模式的例子
具體的 FacesContextFactory 實現創建 FacesContext 對象
State 模式
State 模式的目的是在表示狀態的不同類之間分配與狀態有關的邏輯
FacesServlet 對 LifCycle 實例調用 execute 和 render 方法
LifeCycle 協調不同的 Phrase 以便執行 JSF 請求
在這裡 JSF 實現就遵循了 State 模式
如果沒有使用這種模式
LifeCycle 實現就會被大量的條件(即
if
語句)攪得一塌糊塗
JSF 實現為每個狀態(或階段)創建單獨的類並調用 step
phase 是一個抽象類
定了每個 step 的公共接口
在 JSF 框架中定義了六個 phrase(即 step)
RestoreViewPhase
ApplyRequestValues
ProcessValidationsPhase
UpdateModelValuesPhase
InvokeApplicationPhase 和 RenderResponsePhase
在 State 模式中
LifeCycle 把 FacesContext 對象傳遞給 phase
每個階段或狀態改變傳遞給它的上下文信息
然後設置 FacesContext 本身中的標志表明下一個可能的步驟
JSF 實現在每個步驟中改變其行為
每個階段都可以作為下一個階段的起因
FacesContext 有兩種標志 renderResponse 和 responseComplete 可以改變執行的順序
每個步驟執行完成後
LifeCycle 檢查上一階段是否設置了這些標志
如果設置了 responseComplete
LifeCycle 則完全放棄請求的執行
如果經過某個階段後設置了 renderResponse 標志
JSF 就會跳過剩下的階段而直接進入 Render Response 階段
如果這兩個標志都沒有設置
LifeCycle 就會按順序繼續執行下一步
Composite 模式
Composite 模式讓客戶代碼能夠統一處理復合對象和基本對象
復合對象是基本對象的容器
在第一階段(Restore View 階段)和最後一個階段(Render Response 階段)
使用 JSF UI 組件構造 UI View
UIComponentBase 就是 Composite 模式中 Component 抽象類的一個例子
UIViewRoot 是 Composite 類
而 UIOutput(比方說)就是葉子(或者基本類)
UIComponentBase 類定義了葉子和復合對象的公共方法
如編碼/解碼值和子節點管理函數
子節點管理函數
如 getChildren
對於葉子節點返回空列表
對於復合節點則返回其子節點
Decorator 模式
Decorator 模式的目的是不通過子類化動態擴展對象的行為
JSF 框架有很多擴展點(即可插入機制)
JSF 實現可使用 Decorator 模式替換默認的 PropertyResolver
VariableResolver
ActionListener
NavigationHandler
ViewHandler 或 StateManager
通常自定義實現接受通過構造函數傳遞給它的默認實現的引用
自定義實現僅僅改寫功能的一個子集
而將其他功能委托給默認實現
如果希望實現自定義的 ViewHandler
改寫默認 ViewHandler 實現的 calculateLocale 方法
可以像 清單
那樣編寫
CustomViewHandler 類
清單 CustomViewHandler 片段
public class CustomViewHandler extends ViewHandler {
public CustomViewHandler(ViewHandler handler) {
super();
oldViewHandler = handler;
}
private ViewHandler oldViewHandler = null;
public void renderView (facesContext context UIViewRoot view) {
//delegate method to oldViewHandler
oldViewHandlerrenderView(context view);
}
//custom implementation of calculateLocale
public Locale calculateLocale(FacesContext context) {
}
}
Strategy 模式
Strategy 模式的目的是封裝不同的概念
JSF 框架采用 Strategy 模式使用委托實現模型呈現 UI 組件
JSF 技術支持兩種呈現模型
在直接實現模型中
UI 組件對收到的請求中的數據進行解碼
然後編碼這些數據進行顯示
在委托實現模型中
解碼和編碼操作委托給和組建關聯的專門呈現器
後一種模型利用了 Strategy 設計模式
比直接實現更靈活
在 Strategy 模式中
將不同的算法封裝在單獨的對象中
從而可以動態地改變算法
JSF 實現可以用已有的 renderkit 實例注冊另外的呈現器
當應用程序啟動的時候
JSF 實現讀取配置文件將這些呈現器和 UI 組件聯系在一起
Template Method 模式
Template Method 模式的目的是將變化的步驟推遲到子類中
而在父類中定義那些固定的算法步驟
JSF 框架通過 PhraseListeners 展現了 Template Method 模式提供的功能
采用 Template Method(或者
hook
)使得 Web 作者可以為不同階段之間的可選步驟提供實現
而主要階段仍然和 JSF 框架的定義一致
JSF 框架提供了 PhaseListeners
概念上類似於 Template Method 模式中的可變步驟
JSF 框架有六個預定義的階段
在每個階段之間
Web 作者可以實現 PhaseListeners 來提供類似於 Template Method hook 的 hook
事實上
這種結構比 Template Method 模式更具有擴展性
可以通過注冊 PhraseId 為 ANY_PHRASE 的 PhaseListener 在每個階段後提供 hook
如果 PhaseId 是 ANY_PHASE
JSF 實現就會在每個階段之前和之後調用該 PhaseListener
JSF 框架中的實現略有不同
因為可以根本沒有 PhaseListener
但是在 Template Method 模式中
子類通常重新定義父類中抽象的可變步驟
Observer 模式
Observer 模式的目的是當目標對象的狀態改變時自動通知所有依賴的對象(即觀察器)
JSF 在 UI 組件中實現了 Observer 模式
JSF 有兩類內建事件
ActionEvent 和 ValueChangedEvent
ActionEvent 用於確定用戶界面組件(如按鈕)的激活
當用戶單擊按鈕時
JSF 實現通知添加到該按鈕上的一個或多個動作監聽程序
於是該按鈕被激活
或者說按鈕(主體)的狀態改變了
添加到按鈕上的所有監聽程序(即觀察器)都收到通 知該主體狀態已經改變
類似的
當輸入 UI 組件中的值改變時
JSF 實現通知 ValueChangeListener
結束語 JSF 框架利用了 Singleton
Model
View
Controller
Factory Method
State
Composite
Decorator
Strategy
Template Method 和 Observer 設計模式
因為它的體系結構建立在已經驗證的設計模式的基礎上
這是一個健壯的框架
模式在 JSF 框架中得到了很好的利用
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27455.html