J2EE的Web和企業架構(WEA)設計模式
更新時間: 2007-05-18 15:12:59來源: 粵嵌教育瀏覽量:737
由于GoF(Gamma, Helms, Johnson, and Vlissides)的設計模式的廣發普及,軟件工程專家們找到了一個新的強有力的設計方法。什么是設計模式?他們這樣定義:“設計模式就是描述一個反復出現的問題,以及解決這個問題的方案的核心。你可以重復使用這個解決方案而無須再做重復勞動。”一般來說,一個設計模式包括四個基本要素:模式名稱,需要解決的問題,解決方案和使用帶來模式的效果(或后果)。
在GoF中描述的設計模式,諸如Factory Method, Observer, Façade等,在現在的應用設計領域已是人人皆知,家喻戶曉。正像編者在先前說的那樣,設計模式的命名與描述和一樣起著相當重要的作用。在設計會議中人們使用設計模式的命名比使用他們枯燥乏味的描述節省工作量是可以用人小時估算出來的。
這本書出版七年以后,我們發現設計模式大致和從前是相對一致的。盡管后來也有人增加了一些設計模式,但遠遠不及起初GoF的提出設計模式集合價值高。經試驗證明,沒有一個設計模式能達到初的那23種設計模式的普及和聲望。借用經濟學的一個術語來說就是,新的模式的邊際效用幾乎趨近于零。因此設計模式科學是無非是一個一次性思想的靜態集合。
正相反,從一個Web領域應用程序設計者的經驗來講,我們發現一些歷史經驗(如果你愿意也可以叫模式)事實上是無法實施在應用程序級或子系統級上實現一套指定的方法集這樣的需求,同樣的方式,初的設計模式就能完成這種低級別功能標準化的需求。
接下來我們討論的內容其實也不是什么新東西。它們是一些許多有經驗的開發人員所知道的并經常使用的簡單,標準,通用的方法。仿照初設計模式集的方式,我們對這些顯而易見的方法分類和命名,希望可以使用這些命名(通過生動地捕捉這些方法的基本功能獲得的)來證明它們是非常有價值的。我們把它們命名為“Web和企業架構設計模式(Web and Enterprise Architecture Design Patterns)”,簡稱“WEA設計模式”一個應用程序級的設計模式的宏觀命名。
作為一個J2EE的熱衷者,我們僅僅關注與Java相關的問題和解決方案上,盡管這樣,許多概念對其他技術也還是相當有幫助的。(難道設計模式不是獨立于語言的嗎?這是一個相當吸引人的想法,但是確實存在爭論,如GoF的模式Abstract Factory and Prototype對C++和SmallTalk是非常有用的,而對Java來說是多余的。因為Java的Class類和類的反射機制非常好的解決了這些問題。)
WEA設計模式的分類和注意事項
回想GoF,它把設計模式分為三類,通俗易懂,便于記憶:創建(Creational),結構(Structural), 和 行為(Behavioral)。
秉承這一優良傳統,我們把我們的模式分為劃分(Partitioning),作用域(Scope),安全(Security),導航(Navigation)和數據量控制(Data Volume Control)五類。這并不是一個詳盡列表,而僅僅是初的感覺比較適當的模式類型集。
模式描述
我們粗略地使用GoF建立的描述結構來描述我們的模式。為了簡便,我們將壓縮處理為三個大標題。在“意圖(Intent)”標題下,我們用一行陳述使用這個模式的意圖。我們在“問題和方案(Problem and Solution)”標題下闡述要解決的問題及其解決方案。,我們在“效果(Consequences)”標題下詳盡論述使用此模式帶來的積極和消極的因素。
為了簡潔,我們也省去UML類圖描述。我們的模式是相當簡單,并不需過多的描述。我們也省去了Java代碼樣例。我們相信大多數J2EE開發人員都能明白這些模式。
劃分模式(Partitioning Patterns)
在應用程序中,客戶端(瀏覽器)和服務器都能執行邏輯,客戶端通過javascript完成,服務器通過服務器端腳本語言如Java或PHP執行。但由于各種原因應該把這兩個層中應用程序邏輯分開。
1. 啞客戶端(Dumb Client)
意圖(Intent)
不用客戶端(瀏覽器)執行應用程序邏輯。
問題和方案(Problem and Solution)
許多應用程序采取一種避免使用javascript的策略。一個非常普遍的原因就是當用戶
當關掉瀏覽器的支持javascript功能時,應用程序就不能正常的運轉了。還有就是開發人員開發時還需要考慮對瀏覽器不同版本的支持。(盡管現在許多瀏覽器都改善了對w3c的兼容,但是這種考慮并沒有消除)
如果有這些的原因其中一種,我就必須把所有的處理放到服務器上完成。即使是非常簡單的屬于前臺的,而且使用javascript非常容易實現的操作也要放到服務器上執行。例如,許多電子商務應用程序在服務器端計算總數,盡管計算所需的信息都在客戶端。
效果(Consequences)
使用啞客戶端模式給應用程序帶來的好處就是可以在任何版本瀏覽器上運行,包括老以
前的版本。可以相當好的支持安全要求,不允許用戶執行任何客戶端腳本。
使用這個模式的短處就是增加了網絡傳輸和服務器的負載。這可能對應用程序的性能造成不良的影響,盡管這種影響我們可以在用例級精確地評測出來。除此之外,許多操作不支持本地執行之后,操作會變得粗糙不流暢,使應用程序交互性變差,不友好。
2. 獨立客戶端(Independent Client)
意圖(Intent)
使用交互接口提高客戶端和服務器的執行能力
問題和方案(Problem and Solution)
現在大多數Web應用程序都是客戶端和服務器都需處理邏輯的智能混合體。客戶端使用javascript執行本地的表單驗證來提高交互能力,服務器執行一些需要和后臺交互的請求的處理。客戶端和服務器代碼單獨編寫,這樣可能造成在兩個層中一定程度的代碼冗余。
效果(Consequences)
使用獨立客戶端模式的優點就是使應用程序更自然,更舒服。許多操作可以不和服務器交互在很短的響應時間內就完成。網絡傳輸降到小,服務器負載降到小。
使用此模式的缺點就是使兩個層之間邏輯代碼造成冗余。例如客戶端的驗證要比服務器端的驗證更友好,因為它的更易給用戶快速反饋。但它并不能代替服務器端驗證,因為后臺并不能依靠前臺驗證,后臺必須執行自己的驗證來保證不被錯誤數據侵害。這種冗余可能會造成異常和錯誤,尤其是在維護階段邏輯發生變化的時候。由于Java和javascript的差異很可容易使我們掉入陷阱。
3. 改良服務器客戶端(Server-Modified Client)
意圖(Intent)
通過少量服務器端處理來提供的客戶端交互。
問題和方案(Problem and Solution)
有時,客戶端的處理需要一些存儲在數據庫或后臺的數據。應用程序可以預先把這些數據取出來放到一個數據結構中,當javascript需要時,就可以輕松的訪問這個數據結構,而不需要每次都去和服務器交互一次。這樣一旦一個頁面被載入,客戶端操作就可以迅速的訪問他想要訪問的數據了。例如,動態和有條件的裝配一個下拉框,javascript就可以訪問使用從后臺數據庫獲得數據組裝成的一個數組完成。
一些更復雜的應用程序可能需要后臺來生成javascript函數。例如,用服務器控制客戶端驗證。
改良服務器客戶端模式目的是為了處理javascript代碼和使用Web層Java代碼數據結構的變化。并不是用于生成HTML元素,那是JSP的基本功能。(當然,灰色域也是一種隱式商業邏輯,如有條件生成的HTML導航元素)
效果(Consequences)
使用改良服務器客戶端模式的優勢就是,在沒有冗余的情況下達到良好交互。使在一點控制客戶端和服務器端邏輯成為可能。兩個層之間的異常得以減少或消除。
使用這一模式的劣勢在于增加了復雜度。因為生成javascript代碼是相對簡單,而維護生成這些代碼的代碼,復雜程度一般會增加一個數量級。
作用域模式(Scope Patterns)
作用域一般指一些信息的生命周期,經驗告訴我們,我們遇到的作用域有下面幾種:請求(Request)、會話(Session)和關系(Relationship)。
一個請求作用域變量在客戶端請求返回之前都是可以訪問的。一個會話作用域變量從用戶登陸到會話未結束之前一直可以訪問。,一個關系作用域變量,只要在應用程序中存在這個用戶的詳細資料,這個變量就一直存在。關系作用域并不是JSP規范定義的一種作用域類型,而是根據現實中抽象出來的,諸如個性化。(我們并不去過多考慮JSP定義的Page和Application這兩個作用域)
4. 請求訪問器
意圖(Intent)
在多步驟的服務器端處理中,提供對請求作用域變量的統一訪問的機制。
問題和方案(Problem and Solution)
大多數Web開發的初學者會發現JSP的一個殘酷而又明顯的缺陷之一就是沒有一個像HttpServletRequest對象的getParameter()方法一樣的設置器。這樣就可能使請求在組件間傳來傳去時,在Web層進行一系列操作變得特別頭疼。有些操作可能還需要請求作用域變量進行修改,而缺少setParameter()方法,這將會變得極其糟糕。
請求對象的用于處理指定對象的getAttribute()(與getParameter()方法相比,它將返回一個指定字符串)和setAttribute()給了我們一線希望。可是,使用getAttribute()方法從一個新來自瀏覽器請求對象中獲得參數是無效的,還必須調用getParameter()方法。
請求訪問器模式被設計為,使用一個兼容的接口來對請求對象的檢索、存儲和重檢索進行管理。更簡單的說,這個模式就是,工具類的一個靜態方法(可以叫getAttributeOrParameter