模式與J2EE
http://www.itisedu.com   2006-5-12 15:56:28   中科永聯(lián)
[關(guān)鍵字]模式 J2EE


信息工程是以當(dāng)前數(shù)據(jù)系統(tǒng)為基礎(chǔ),在一個(gè)企業(yè)或企業(yè)的主要部門,關(guān)于建設(shè)信息系統(tǒng)的規(guī) 劃、分析、設(shè)計(jì)和構(gòu)成的一整套相互關(guān)聯(lián)的正規(guī)化、自動(dòng)化的技術(shù)應(yīng)用。

 

--- JAMES Martin 

    正如上面信息工程的創(chuàng)始人James Martin為信息工程的概念所做定義似,模式(patterns)的創(chuàng)始人建筑師ChriSTopher Alexander在<模式語言,1977、1979>一書中對(duì)模式的概念進(jìn)行了如下描述(附注:書名后面的年份代表在各個(gè)不同時(shí)期的作品,下面形式同上):
每一個(gè)模式描述了一個(gè)在我們周圍不斷重復(fù)發(fā)生的問題,以及該問題的解決方案的核心。這樣,你就能一次又一次的使用該解決方案而不必做重復(fù)勞動(dòng)。每個(gè)模式是由三部分組成的一個(gè)規(guī)則,這個(gè)規(guī)則描述特定環(huán)境、問題和解決方案之間的關(guān)系。簡(jiǎn)單的說,沒有一個(gè)模式是獨(dú)立的實(shí)體,每個(gè)模式都存在著相互支持,但支持的程度不同:大的模式可以內(nèi)嵌小的模式,同等層次的模式并列存在,而小的模式被嵌入到大的模式之中。
--- Christopher Alexander  
    模式的概念在軟件行業(yè)被采用以后,得到的廣泛的發(fā)展,現(xiàn)在已經(jīng)存在許多種類型的模式應(yīng)用,其中比較有名的箸作有:GoF(Erich GAmma、Richard Helm、Ralph Johnson和John VlissIDEs四人,簡(jiǎn)稱:Gang of Four[GoF])的<設(shè)計(jì)模式,1995>,Martin Fowler的<分析模式,1997>,F(xiàn)rank Buschmann等人的<體系結(jié)構(gòu)模式,1996、2000>、Jim O.Coplien、Niel Harrison等人的<編程模式,1995、1996、1998、1999>和Deepak Alur等人的<J2EE核心模式,2001>等,其中最具影響的是GoF的<設(shè)計(jì)模式>一書,書中詳細(xì)討論了三種類型,共23種模式。好的設(shè)計(jì)源于工作中經(jīng)驗(yàn)的積累,當(dāng)設(shè)計(jì)使用標(biāo)準(zhǔn)的模板以模式的方式進(jìn)行交流時(shí),模式就成了交流和重用的強(qiáng)大機(jī)制,并且可以改善設(shè)計(jì)和開發(fā)軟件的方式。模式可以幫助我們?cè)谝粋€(gè)特定的環(huán)境里整理并記錄已知的可重現(xiàn)的問題及解決方案,并且通過模式來與他人交流這些知識(shí),這些模式可以解決在不同環(huán)境中重復(fù)出現(xiàn)的問題。模式可以使設(shè)計(jì)重復(fù)使用,重復(fù)使用已知的解決方案可以縮短設(shè)計(jì)和開發(fā)應(yīng)用的周期,有效的使用模式,可以使我們遠(yuǎn)離重復(fù)投資的怪圈。模式的關(guān)鍵在于簡(jiǎn)單性和可重現(xiàn)性。
    舉一個(gè)模式應(yīng)用的簡(jiǎn)單示例。例如,在你的便攜式電腦上運(yùn)行一個(gè)進(jìn)程中的對(duì)象,并且這些對(duì)象需要和運(yùn)行在另一進(jìn)程中的別的對(duì)象通信,也許這一進(jìn)程并不在你的便攜式電腦上,而在別的地方。你又不想讓系統(tǒng)中的對(duì)象擔(dān)心如何找尋網(wǎng)上的其他對(duì)象或者執(zhí)行遠(yuǎn)程過程調(diào)用。這時(shí),可以使用代理(Proxy模式,詳見GoF的<設(shè)計(jì)模式>一書)模式來解決這個(gè)問題,你能做的事就是為這個(gè)遠(yuǎn)程對(duì)象在你的本地過程中建立一個(gè)代理對(duì)象,該代理對(duì)象和遠(yuǎn)程對(duì)象具有相同的接口。你的本地對(duì)象利用通常處理過程中的消息發(fā)送來和代理交談。這時(shí)代理對(duì)象負(fù)責(zé)把消息傳送給實(shí)在對(duì)象,而不管實(shí)在對(duì)象位于何處。
    由于下面要講的Java 2平臺(tái)的企業(yè)版(J2EE)應(yīng)用模式中很多用到了設(shè)計(jì)模式與重構(gòu)(Refactoring)的概念,所以在此有必要再概要介紹一下重構(gòu)的概念。重構(gòu)已經(jīng)被證明可以阻止軟件的腐朽和衰敗,關(guān)于重構(gòu)方面的有名箸作當(dāng)然首推是Martin Fowler所寫的<重構(gòu),1999>一書了,書中詳細(xì)介紹了重構(gòu)的七大類型,共70余種具體的重構(gòu)手法,同時(shí)也指出測(cè)試機(jī)制在重構(gòu)中的重要性。書中Martin Fowler對(duì)重構(gòu)的概念進(jìn)行了詳細(xì)說明:
    重構(gòu)是對(duì)軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目地是在不改變[軟件之可察行為]的前提下,提高其可理解性,降低其修改成本。重構(gòu)是一種有紀(jì)律的、經(jīng)過訓(xùn)練的、有條不紊的程序整理方法,可以將整理過程中不小心引入的錯(cuò)誤的機(jī)率降到最低,本質(zhì)上說,重構(gòu)就是在代碼寫好之后改進(jìn)它的設(shè)計(jì)。重構(gòu)之前,首先檢查自己是否有一套可靠的測(cè)試機(jī)制,這些測(cè)試必須有我檢驗(yàn)?zāi)芰Α?/p>


--- Martin Fowler 

    建立于Java編程語言和Java技術(shù)基礎(chǔ)之上的J2EE平臺(tái)是最適用于企業(yè)級(jí)分布式環(huán)境的應(yīng)用結(jié)構(gòu),它被設(shè)計(jì)為面向多層體系的結(jié)構(gòu)。J2EE包含下面關(guān)鍵技術(shù):Java服務(wù)器頁面(Java Service Page,JSP)、Servlet、Enterprise JavaBeans(EJB)組件、Java消息服務(wù)(Java Message Service,JMS)、JDBC和Java命名與目錄接口(Java Naming and DIrECtory Interface,JNDI)。由于J2EE平臺(tái)是分層系統(tǒng),所以我們將J2EE的層次模型化,這個(gè)模型使得我們將職責(zé)邏輯地分到不同的層中,共分了五個(gè)層次:客戶層、表示層、業(yè)務(wù)層、集成層和資源層。因?yàn)榭蛻魧雍唾Y源層并不是J2EE平臺(tái)直接關(guān)注的問題,所以后面介紹的15個(gè)J2EE應(yīng)用模式全部屬于上面五層中的中間三層,其中表示層模式包含與Servlet和JSP技術(shù)相關(guān)的模式、業(yè)務(wù)層模式包含與EJB技術(shù)有關(guān)的模式、集成層模式包含與JMS和JDBC有關(guān)的模式。具體模式可參看下面表格:

表一:表示層模式
模式名 簡(jiǎn)單描述
截取過濾器(Intercepting Filter) 促進(jìn)請(qǐng)求的預(yù)先處理和后處理
前端控制器(Front Controller) 提供請(qǐng)求處理的集中控制器
視圖助手(View Helper) 把與表示層格式化無關(guān)的邏輯封裝到助手組件
復(fù)合視圖(CompOSite View) 從原子的子組件創(chuàng)建一個(gè)聚集視圖
工作者服務(wù)(Service To Worker) 合并分發(fā)者組件、前端控制器和視圖助手模式
分發(fā)者視圖(Dispatcher View) 合并分發(fā)者組件、前端控制器和視圖助手模式,把許多動(dòng)作推遲到視圖處理


表二:業(yè)務(wù)層模式
模式名 簡(jiǎn)單描述
業(yè)務(wù)委托(Business Delegate) 把表示層和服務(wù)層分隔開,并且提供服務(wù)的外觀和代理接口
值對(duì)象(Value object) 通過減少網(wǎng)絡(luò)對(duì)話,以加速層之間的數(shù)據(jù)交換
會(huì)話外觀(Session Facade) 隱藏業(yè)務(wù)對(duì)象復(fù)性,集中化工作流處理
復(fù)合實(shí)體(Composite Entity) 通過把參數(shù)相關(guān)的對(duì)象分組進(jìn)單個(gè)實(shí)體bean,表示設(shè)計(jì)粗粒度實(shí)體bean的最好經(jīng)驗(yàn)
值對(duì)象組裝器(Value Object ASsembler) 把來自多個(gè)數(shù)據(jù)源的值對(duì)象組裝成一個(gè)復(fù)合值對(duì)象
值列表處理器(Value List Handler) 管理查詢執(zhí)行、結(jié)果緩沖、以及結(jié)果處理
服務(wù)定位器(Service Locator) 封裝業(yè)務(wù)服務(wù)查找和創(chuàng)建的復(fù)雜性,定位業(yè)務(wù)服務(wù)工廠


表三:集成層模式
模式名 簡(jiǎn)單描述
數(shù)據(jù)訪問對(duì)象(Data Access Object) 抽象數(shù)據(jù)源,提供對(duì)數(shù)據(jù)的透明訪問
服務(wù)激發(fā)器(Service Activator) 加速EJB組件的異步處理

    由于J2EE模式眾多,篇幅有限,這里只概要介紹其中的一種應(yīng)用模式 - 集成層的數(shù)據(jù)訪問對(duì)象(DAO)模式,有興趣的讀者可以參看下面參考文獻(xiàn)中的資料。
數(shù)據(jù)訪問對(duì)象模式

 數(shù)據(jù)訪問對(duì)象模式

1、問題
    根據(jù)數(shù)據(jù)源不同,數(shù)據(jù)訪問也不同。根據(jù)存儲(chǔ)的類型(關(guān)系數(shù)據(jù)庫(kù)面向?qū)ο?/font>數(shù)據(jù)庫(kù)等)和供應(yīng)商不同,持久性存儲(chǔ)(比如數(shù)據(jù)庫(kù))的訪問差別也很大。當(dāng)業(yè)務(wù)組件(如會(huì)話bean)或表示組件(如助手組件)需要訪問某數(shù)據(jù)源時(shí),它們可以使用合適的API來獲得連接性,以及操作該數(shù)據(jù)源。但是在這些組件中包含連接性和數(shù)據(jù)訪問代碼會(huì)引入這些組件及數(shù)據(jù)源實(shí)現(xiàn)之間的緊密耦合。組件中這類代碼依賴性使應(yīng)用程序從某種數(shù)據(jù)源遷移到其它種類的數(shù)據(jù)源將變得非常麻煩和困難,當(dāng)數(shù)據(jù)源變化時(shí),組件也需要改變,以便于能夠處理新類型的數(shù)據(jù)源。

2、解決方案
    使用數(shù)據(jù)訪問對(duì)象(DAO)來抽象和封裝所有對(duì)數(shù)據(jù)源的訪問。DAO管理著與數(shù)據(jù)源的連接以便于檢索和存儲(chǔ)數(shù)據(jù),DAO實(shí)現(xiàn)了用來操作數(shù)據(jù)源的訪問機(jī)制。依賴于DAO的業(yè)務(wù)組件為其客戶端使用DAO提供了更簡(jiǎn)單的接口,DAO完全向客戶端隱藏了數(shù)據(jù)源實(shí)現(xiàn)細(xì)節(jié)。由于當(dāng)?shù)蛯訑?shù)據(jù)源實(shí)現(xiàn)變化時(shí),DAO向客戶端提供的接口不會(huì)變化,所以該模式允許DAO調(diào)整到不同的存儲(chǔ)模式,而不會(huì)影響其客戶端或業(yè)務(wù)組件。重要的是,DAO充當(dāng)組件和數(shù)據(jù)源之間的適配器。

3、實(shí)現(xiàn)策略
    通過調(diào)整抽象工廠(Abstract Factory)模式和工廠方法(Factory Method,這二個(gè)創(chuàng)建型模式的實(shí)現(xiàn)詳情可參看GoF的<設(shè)計(jì)模式>一書)模式,DAO模式可以達(dá)到很高的靈活度。

當(dāng)?shù)蛯哟鎯?chǔ)不會(huì)隨著實(shí)現(xiàn)變化而變化時(shí),可以使用工廠方法模式來實(shí)現(xiàn)該策略,以產(chǎn)生應(yīng)用程序需要的大量DAO,如下面類圖1所示。
當(dāng)?shù)蛯哟鎯?chǔ)隨著實(shí)現(xiàn)的變化而變化時(shí),策略可以通過使用抽象工廠模式而實(shí)現(xiàn)。抽象工廠可以基于工廠方法實(shí)現(xiàn)而創(chuàng)建,并可使用工廠方法實(shí)現(xiàn),該策略提供一個(gè)DAO的抽象工廠對(duì)象,其中該對(duì)象可以構(gòu)造多種類型的具體的DAO工廠,每個(gè)工廠支持一種不同類型的持久性存儲(chǔ)實(shí)現(xiàn)。一旦你獲取某特定實(shí)現(xiàn)的具體DAO工廠,你可以使用它來生成該實(shí)現(xiàn)中所支持和實(shí)現(xiàn)的DAO,如下面類圖2所示。


 

4、應(yīng)用
    當(dāng)數(shù)據(jù)訪問代碼被直接嵌入到有其他不相關(guān)職責(zé)的某類中時(shí),就會(huì)使修改變的十分困難。這時(shí)可以采用分離數(shù)據(jù)訪問代碼的解決方案,將數(shù)據(jù)訪問代碼抽取到一個(gè)新類中,并且把該新類邏輯或者物理地移動(dòng)到離數(shù)據(jù)源比較近的位置,這樣可以增強(qiáng)模塊性和可重用性,如下面圖3所示。具體作法可以使用提煉類(Extract Class,一種重構(gòu)手法,細(xì)節(jié)可參看Martin的<重構(gòu)>一書)方法創(chuàng)建一個(gè)新類,并將原來類中把數(shù)據(jù)訪問代碼移動(dòng)到這個(gè)新的數(shù)據(jù)訪問對(duì)象(DAO)類,使用這個(gè)新的DAO對(duì)象從控制器類中訪問數(shù)據(jù)。
    示例:持久性邏輯被嵌入到一個(gè)使用新DAO對(duì)象管理的持久性的某企業(yè)新DAO對(duì)象中,把持久性代碼和該企業(yè)新DAO對(duì)象代碼結(jié)合起來會(huì)創(chuàng)建脆弱的、緊密耦合的代碼。當(dāng)持久性代碼是該企業(yè)新DAO對(duì)象的一部分時(shí),對(duì)該持久性存儲(chǔ)的任何改動(dòng)都要求更改該新DAO對(duì)象的持久性代碼。這種耦合對(duì)企業(yè)新DAO對(duì)象代碼維護(hù)會(huì)帶來負(fù)面的影響。下面圖4為運(yùn)用分離數(shù)據(jù)訪問對(duì)象方法對(duì)其進(jìn)行重構(gòu)改進(jìn)后的結(jié)果。

    在15個(gè)J2EE模式中,每個(gè)模式都作用于設(shè)計(jì)模式和構(gòu)架模式之間的某些方面。每個(gè)模式不是孤立存在的,需要其它模式的支持才能更加體現(xiàn)其含義和用處,為了最大限度的用好模式,還需要充分理解模式之間的關(guān)系。

 參考文獻(xiàn)

系統(tǒng)分析員教程 --- 羅曉沛等箸
設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖脑?--- 李英軍等譯
重構(gòu)-改善既有代碼的設(shè)計(jì) --- 侯捷等譯
J2EE核心模式 --- 牛志奇等譯
UML精粹(第二版) --- 徐家福譯