J2EE體系架構(gòu)設(shè)計介紹(2) 會話面、數(shù)據(jù)訪問對象
圖6中的類圖簡要描述了會話面的設(shè)計模式,圖7給出了會話面的序列表示,即參與組件及其交互關(guān)系。
圖6 會話面類圖
圖7會話面序列圖
這里我們對于圖7的各個組件加以簡要的介紹:
(1)客戶(Client)。這表示會話面的客戶,即需要訪問相關(guān)企業(yè)服務(wù)的客戶端應(yīng)用程序,當(dāng)然也可以是在同一層面或不同層面的另外一個會話bean。
(2)會話面(Session Facade)。會話面通常是用會話bean來實現(xiàn)的,它管理著多個企業(yè)對象的作用關(guān)系并提供一個高層次的抽象界面給用戶。
(3)業(yè)務(wù)對象(Business Object)。業(yè)務(wù)對象是一個可以使用多個不同設(shè)計方案的對象,例如會話bean、實體bean和數(shù)據(jù)訪問對象。在圖6中業(yè)務(wù)對象負責(zé)提供數(shù)據(jù)和服務(wù),而會話面則需要與多個業(yè)務(wù)對象實例交互而獲得相應(yīng)的服務(wù)。
會話面實際上就是業(yè)務(wù)層的一個控制對象,它負責(zé)控制用戶與企業(yè)數(shù)據(jù)和企業(yè)服務(wù)對象之間的交互;在一個復(fù)雜的應(yīng)用系統(tǒng)中,甚至可能會有多個會話面作為用戶和對象模塊之間的中介。
下面介紹兩種實現(xiàn)會話面的常見方法。
(1)無狀態(tài)的會話面
在實現(xiàn)會話面的時候,首先應(yīng)該決定是用狀態(tài)化還是無狀態(tài)的會話bean來實現(xiàn),這主要取決于會話面所建模的業(yè)務(wù)流程;如果一個業(yè)務(wù)流程只需要一次方法調(diào)用就可以實現(xiàn)其服務(wù),那么就可以使用無狀態(tài)的會話bean來實現(xiàn)它。
(2)狀態(tài)化的會話面
當(dāng)一個業(yè)務(wù)流程需要多次方法調(diào)用來實現(xiàn)其服務(wù)時,開發(fā)人員***使用狀態(tài)化的會話bean來實現(xiàn)這***程,因為每次方法調(diào)用的狀態(tài)信息都必須在會話bean中保存。
通過在應(yīng)用系統(tǒng)中采用會話面的設(shè)計模式,將在系統(tǒng)中得到以下的收益:
①為用戶提供一個簡單的接口,并隱藏所有與系統(tǒng)組件復(fù)雜的交互過程;
②減少暴露給用戶的企業(yè)對象,從而降低它們之間的依賴關(guān)系;
③向用戶隱藏系統(tǒng)組件間的交互過程和依賴關(guān)系,從而使得系統(tǒng)更加容易管理,并提供相當(dāng)?shù)撵`活性;提供一套統(tǒng)一的用戶訪問機制,便于管理用戶對于系統(tǒng)服務(wù)的請求與訪問。
6、 數(shù)據(jù)訪問對象
數(shù)據(jù)訪問對象(data access object,DAO)模式將數(shù)據(jù)訪問邏輯抽象為特殊的資源,也就是說將系統(tǒng)資源的接口從其底層訪問機制中隔離出來;通過將數(shù)據(jù)訪問的調(diào)用打包,數(shù)據(jù)訪問對象可以促進對于不同數(shù)據(jù)庫類型和模式的數(shù)據(jù)訪問。
這種模式出現(xiàn)的背景在于數(shù)據(jù)訪問的邏輯極大程度上取決于數(shù)據(jù)存儲的格式,比如說關(guān)系型數(shù)據(jù)庫、面向?qū)ο髷?shù)據(jù)庫、磁盤文件等。
目前大部分的J2EE應(yīng)用程序都需要在一定程度上使用可持久性的數(shù)據(jù),而實現(xiàn)持久性數(shù)據(jù)的方法因應(yīng)用程序不同而異,并且訪問不同存儲格式數(shù)據(jù)的應(yīng)用程序接口(API)也有著顯著的差別;有的時候,應(yīng)用程序還會訪問存儲在不同操作平臺上的數(shù)據(jù),這使得問題更為復(fù)雜,通常,應(yīng)用程序會使用共享的分布式組件,如實體bean來表達持久性數(shù)據(jù)。應(yīng)用程序可以使用bean管理的持久性實體bean,而在實體bean中植人數(shù)據(jù)訪問邏輯,或者使用容器管理的持久性實體bean,從而使容器管理所有的事務(wù)和持久性細節(jié);而如果應(yīng)用程序?qū)τ跀?shù)據(jù)訪問的需求十分簡單的話,也可以采用會話bean或Servlet直接訪問持久性存儲來讀取和修改數(shù)據(jù)。
一些應(yīng)用程序可以使用JDBC應(yīng)用程序接口來訪問關(guān)系數(shù)據(jù)庫中的數(shù)據(jù),JDBC負責(zé)一般的持久性數(shù)據(jù)訪問和管理,在J2EE應(yīng)用程序中,JDBC中可以嵌入SQL語句,用以訪問關(guān)系型數(shù)據(jù)庫,當(dāng)然根據(jù)數(shù)據(jù)庫類型的不同,SQL語句的詞法和語法也會有所不同;需要說明的是,當(dāng)數(shù)據(jù)存儲格式不同的時候,數(shù)據(jù)訪問邏輯的區(qū)別就更加明顯了,例如關(guān)系型數(shù)據(jù)庫、面向?qū)ο髷?shù)據(jù)庫和磁盤文件,各自數(shù)據(jù)的訪問邏輯各有千秋,這樣一來就造成了程序代碼和數(shù)據(jù)訪問代碼之間的依賴關(guān)系;當(dāng)程序組件,即實體bean、會話bean或servlet、JSP等需要訪問數(shù)據(jù)源時,它們會使用正確的應(yīng)用程序接口來得到連接并管理數(shù)據(jù)源,但這樣也會造成這些組件與數(shù)據(jù)源物理實現(xiàn)之間的依賴關(guān)系,從而使得應(yīng)用程序很難從一個數(shù)據(jù)存儲實體移植到另一個數(shù)據(jù)存儲實體中去;當(dāng)數(shù)據(jù)源的物理實現(xiàn)變化的時候,應(yīng)用程序也必須相應(yīng)地加以改變。
基于以上所討論的問題,開發(fā)人員開始采用數(shù)據(jù)訪問對象的方法。數(shù)據(jù)訪問對象實際上就是包含對于所有數(shù)據(jù)訪問邏輯的對象,并管理著對于數(shù)據(jù)源的連接,根據(jù)數(shù)據(jù)源的不同,數(shù)據(jù)訪問對象實現(xiàn)了不同的訪問機制,這里所說的數(shù)據(jù)源可以是持久性存儲介質(zhì),如關(guān)系型數(shù)據(jù)庫,也可以是外部服務(wù),如B2B的數(shù)據(jù)交換;不僅是用戶,而且包括應(yīng)用系統(tǒng)中的其他組件,也可以使用數(shù)據(jù)訪問對象所提供的數(shù)據(jù)訪問接口,數(shù)據(jù)訪問對象將數(shù)據(jù)源的物理實現(xiàn)細節(jié)與其用戶完全分離開來,并且在底層數(shù)據(jù)源變化的時候,數(shù)據(jù)訪問對象向用戶提供的接口是不會變化的;這種方法使應(yīng)用系統(tǒng)使用數(shù)據(jù)訪問對象時可以適應(yīng)多種數(shù)據(jù)存儲介質(zhì),總之,數(shù)據(jù)訪問對象就是系統(tǒng)組件和數(shù)據(jù)源中間的適配器。
圖8中的類圖表示了數(shù)據(jù)訪問對象設(shè)計模式的參與對象和之間的調(diào)用關(guān)系,圖9是這種設(shè)計模式的序列圖。
圖8 數(shù)據(jù)訪問對象類圖
圖9 數(shù)據(jù)訪問對象序列圖
對于圖9序列圖中的組件加以解釋如下:
(1)業(yè)務(wù)對象(Business Object)。表示數(shù)據(jù)的用戶,它需要對于數(shù)據(jù)的訪問,一個業(yè)務(wù)對象可以用會話bean、實體bean或是其他Java程序來實現(xiàn)。
(2)數(shù)據(jù)訪問對象(Data Access Object)。數(shù)據(jù)訪問對象是這種模式中的主題,它提供了底層數(shù)據(jù)訪問的對象,并將其提供給業(yè)務(wù)對象以使得后者能夠透明地訪問數(shù)據(jù)源;同時業(yè)務(wù)對象也將數(shù)據(jù)的加載和存儲操作移交給數(shù)據(jù)訪問對象處理。
(3)數(shù)據(jù)源(Data source)。這里指的是數(shù)據(jù)源的物理實現(xiàn),這個數(shù)據(jù)源可以是一個數(shù)據(jù)庫,包括關(guān)系型數(shù)據(jù)庫、面向?qū)ο髷?shù)據(jù)庫或文件系統(tǒng)。
(4)傳輸對象(Transfer Object)。這里的傳輸對象指的是數(shù)據(jù)載體。數(shù)據(jù)訪問對象可以使用傳輸對象來向用戶返回數(shù)據(jù),而數(shù)據(jù)訪問對象同樣可以從用戶那里得到傳輸對象來對數(shù)據(jù)源中的數(shù)據(jù)進行更新。
下面給出幾種實現(xiàn)數(shù)據(jù)訪問對象設(shè)計模式的方法。
(1)自動數(shù)據(jù)訪問對象代碼的生成
既然每一個業(yè)務(wù)對象都對應(yīng)于一個數(shù)據(jù)訪問對象,那么開發(fā)人員就可以建立業(yè)務(wù)對象、數(shù)據(jù)訪問對象和底層實現(xiàn)的關(guān)系;一旦這種關(guān)系建立起來,開發(fā)人員就可以為所有的數(shù)據(jù)訪問對象編寫特殊的代碼生成工具。
生成數(shù)據(jù)訪問對象的信息通常存儲在一個開發(fā)人員定義的描述文件中,如果對于數(shù)據(jù)訪問對象的要求過于復(fù)雜,開發(fā)人員可以考慮使用第三方工具來為關(guān)系型數(shù)據(jù)庫提供對象對關(guān)系的映射。這些工具通常是一些GUI程序,可以用來將業(yè)務(wù)對象映射為持久性的存儲對象,并定義中間運作的數(shù)據(jù)訪問對象,在映射完成的時候,這些工具可以自動地生成代碼,并提供一些相應(yīng)的功能,如緩存結(jié)果、緩存查詢、與應(yīng)用服務(wù)器整合、與第三方產(chǎn)品整合等。
(2)數(shù)據(jù)訪問對象代理(Factory for Data Access Objects)
當(dāng)?shù)讓拥臄?shù)據(jù)存儲不會輕易改變的時候,開發(fā)人員可以采取這種方法來實現(xiàn)相應(yīng)的,數(shù)據(jù)訪問對象,圖10是這種方法的類圖。
圖10 使用DAO代理類圖
當(dāng)?shù)讓拥臄?shù)據(jù)存儲可能會變化的時候,開發(fā)人員可以采用抽象代理的方法來實現(xiàn)數(shù)據(jù)訪問對象;抽象代理的方法會創(chuàng)建一些虛擬的數(shù)據(jù)訪問對象代理和各種類型的實際數(shù)據(jù)訪問對象代理,每種對象對應(yīng)一種持久性存儲介質(zhì)的實現(xiàn),一旦組件得到這些代理,就可以利用來創(chuàng)建需要使用的數(shù)據(jù)訪問對象。
圖11給出了這種情況的類圖。該類圖表示了一個基礎(chǔ)的數(shù)據(jù)訪問對象代理,它是一個抽象類,被其他一些實際的數(shù)據(jù)訪問對象代理繼承以支持特定的數(shù)據(jù)訪問函數(shù);用戶可以得到一個實際的數(shù)據(jù)訪問對象,并利用它來創(chuàng)建需要的數(shù)據(jù)訪問對象而訪問相關(guān)的數(shù)據(jù),每一個實際的數(shù)據(jù)訪問對象都負責(zé)建立對于數(shù)據(jù)源的連接,并得到和管理所支持的業(yè)務(wù)數(shù)據(jù)。
圖11 抽象代理使用DAO
下圖12是這種情況下的序列圖。
圖12抽象代理使用DAO序列圖
這種設(shè)計模式的優(yōu)勢:
透明性好。業(yè)務(wù)對象可以在不知道數(shù)據(jù)源實現(xiàn)細節(jié)的情況下訪問數(shù)據(jù)。由于一切數(shù)據(jù)訪問細節(jié)被數(shù)據(jù)訪問對象所隱藏,所以這種訪問過程是透明的。
可移植性好。在應(yīng)用系統(tǒng)中添加數(shù)據(jù)訪問對象,可以使得前者能夠很方便地移植到另外一種數(shù)據(jù)庫實現(xiàn)上。業(yè)務(wù)對象與數(shù)據(jù)實現(xiàn)是隔離的,所以在移植過程中,僅僅對數(shù)據(jù)訪問對象進行一些變化即可。
減少業(yè)務(wù)對象的代碼復(fù)雜度。由于數(shù)據(jù)訪問對象可以管理所有的數(shù)據(jù)訪問復(fù)雜細節(jié),這也就簡化了業(yè)務(wù)模塊和其他數(shù)據(jù)客戶的代碼。同時也提高了應(yīng)用系統(tǒng)的整體可讀性和開發(fā)率。
集中處理所有數(shù)據(jù)訪問。由于所有的數(shù)據(jù)訪問操作都移交給數(shù)據(jù)訪問對象,這樣應(yīng)用系統(tǒng)其他部分就與數(shù)據(jù)訪問實現(xiàn)隔離開來,而全部相關(guān)操作都與數(shù)據(jù)訪問對象集中處理,這樣也使得相關(guān)操作更加容易被維護和管理。
這種設(shè)計模式的缺陷:
對于容器管理的持久性不能利用。如果EJB容器采取容器管理的方式,那么所有對于持久性數(shù)據(jù)存儲的管理都由容器負責(zé)。這樣的話應(yīng)用系統(tǒng)就無需實現(xiàn)數(shù)據(jù)訪問對象了,因為應(yīng)用服務(wù)將透明地提供這一功能。
添加了額外的層面。數(shù)據(jù)訪問對象在數(shù)據(jù)用戶和數(shù)據(jù)源之間添加了一個層面,也就增加了一些額外的設(shè)計和實現(xiàn)的負擔(dān)。當(dāng)然,我們認為它是物有所值的。
總之,在開發(fā)人員選擇不同模式的時候,應(yīng)該注意,一定的模式對應(yīng)于一定的應(yīng)用層次。比如說,與視圖和顯示相關(guān)的模式就是在Web層應(yīng)用的。而一些與業(yè)務(wù)邏輯控制相關(guān)的模式則是與EJB層次相關(guān)的。另外一些關(guān)于讀取數(shù)據(jù)和分派操作的模式則適用于不同的層次之間。
【編輯推薦】