J2EE 是Java技術在企業運算上的應用,它包含多種運算標準,如EJB組件架構、JDBC數據庫運算、JMS信息傳遞、Java Servlets/JSP等Web組件程序等,功能強大且內容博大精深。為了讓使用者可以有一個設計J2EE架構應用程序的模板,Sun做出一套系統名為“Java寵物商店(Pet Store)”。這個網上寵物店的范例是針對已經熟悉Java程序設計和J2EE概念人員的。這個系統是使用正規方式設計出來的,使得使用J2EE架構的人員有了一個參考的依據。這個范例一出來,很快就被用來當成比較各家J2EE兼容產品的依據。Oracle的J2EE Application Server(Oracle 9iAS)、BEA WebLogic Server、IBM WebSphere都有相應的產品。Java標準的精神原本就是各家廠商合作制定技術標準,然后再根據這個標準來評選出最優產品。
Java Pet Store使用的架構設計就是所謂的MVC 設計模式。MVC是Model-View-Controller的簡寫,是設計模式的一種,源自Smalltalk。MVC模式則是將對象分成三類,Model對象專門用來包裝應用程序的狀態,View用來負責屏幕上的展現,Controller則負責定義應用程序的各種動作和反應。Java寵物店系統利用MVC模式設計整個系統架構,將各層的對象清楚地分開。Java寵物店的目的是展示一個具有擴充性的企業運算架構,就是采用三層(3-Tiers)式設計:資料展現層在最外面,中間是執行企業運算邏輯的中間層組件,后端就是單純存放資料的關系型數據庫。Java寵物店當初的用意也只是當成一個J2EE架構設計的模板,并沒有特別針對加速執行效能作額外的設計。
系統構架與寵物商店簡介
系統構架
Pet Store網站系統采用松耦合的設計架構,可以和多個數據源、EIS進行交互。這個例子共分成4個部分:
1.Web購物站點;
2.管理部分,包括銷售統計、手工接受/拒絕訂單;
3.訂單處理,包括以下4部分內容:
◆ 通過JMS接受/處理訂單消息;
◆ 用Java Mail來通知客戶;
◆ 通過JMS發訂單給供應商;
◆ 維護訂單數據庫。
4.供應商,此部分包括以下內容:
◆ 通過JMS接受訂單;
◆ 派送貨物給用戶;
◆ 提供一個基于Web的庫存管理;
◆ 維護庫存數據庫。
寵物店網上商店功能
通過瀏覽器可以訪問此商店。客戶通過瀏覽,可以把貨物放入購物車,創建賬戶/登錄賬戶,創建訂單,然后通過信用卡支付。
寵物商店結構
寵物店的網站服務是從上而下的。最上層是WAF(Web Application Framework)來控制應用的屏幕跳轉,產生視圖,然后調用商業組件來完成商業處理(如圖1所示)。

圖1 Java Pet Store 結構
WAF提供了許多Web應用所需的服務,包括請求的過濾和分發、模板視圖的產生、一系列可重用的Taglib,以及屏幕流程控制等。應用組件封裝了處理的邏輯,它們代表了商業的數據,并且操作這些商業數據,實體EJB代表了商業實體,如客戶、地址、賬目。會話EJB提供了一些方法,如登陸一個用戶、輸出一個用戶、管理購物車等。其它會話EJB提供了一些共同的方法,如產生唯一標示符。傳統的JavaBean組件變成了值對象,用來在EJB組件和應用間傳遞數據。XML文檔類則用來處理訂單信息。
這個寵物店例子的WAF是對J2EE藍圖Web層規范的實現。一個Web層處理一般可以劃分成四步(如圖2所示):
◆ 解釋一個請求;
◆ 執行一個商業邏輯處理;
◆ 選擇下一個視圖;
◆ 產生這個視圖。

圖2 WAF的Web層處理
寵物店模塊設計
寵物店由一些獨立模塊組成:
◆ 控制模塊 它來分發請求到各個業務處理邏輯、控制屏幕跳轉、處理對應的組件及用戶;
◆ 登錄和注冊 控制模塊由WAF實現和擴展;
◆ 購物車模塊 購物車跟蹤用戶購物過程;
◆ 登錄模塊 需要用戶登錄在某些頁面登錄;
◆ 消息模塊 從寵物店到等單中心用來異步傳輸訂單;
◆ 類別模塊 根據用戶查詢需求提供一個類別視圖;
◆ 客戶模塊 表示客戶信息,如地址、信用卡、聯系方式等(如圖3所示)。

圖3 Java pet Store 模塊設計
在圖3中,控制模塊控制所有的交互和執行,每個用戶會話都有一個購物車對應。
寵物店的組件
1. EJB,代表了商業數據和執行商業邏輯處理;
2. JSP頁面, 定義了整個應用的視圖框架模板(template.jsp)和模板組成的各個JSP文件,以及各種被引用的圖形文件;
3. XML文件,用來定義屏幕、屏幕跳轉控制、綁定URL到某個HTML Action、定制signOn以及J2EE部署的部署XML文件;
4. Servlet過慮器, 用來校驗用戶安全的登陸和輸出的編碼;
5. 異步信息發送組件,傳輸使用XML封裝的訂單到訂單處理中心;
6. 一個安裝程序,用來產生例子數據庫。
分析寵物商店的應用
下面就按照MVC架構和層次化應用模型來分析這個應用。
模型—視圖—控制架構
1.應用模型劃分方法
分析一個實際應用可以有三種劃分的方法:第一種劃分方法為模型—視圖—控制(MVC)架構。這種方法把應用分解成數據、顯示和控制三個部分。第二種劃分方法把應用按照不同的角色劃分成不同的層次,分離客戶端、Web層、EJBs層和底端的數據層或遺留系統層,即J2EE應用的層次劃分方法。第三種劃分是傳統的功能模塊劃分。
劃分的目的是使復雜的問題清晰化、條理化。每一種劃分雖然增加了額外的復雜性,但也有它的好處。MVC架構為應用組件提供一個靈活的、可重用的、易測試的、可擴展的和清晰的設計角色。多層設計使實現技術的選擇靈活,同時具有可升級和可擴展性。模塊化的設計把系統分解成小的直接模塊,可以進行單獨分析、測試和理解。
現在企業級應用與以前相比,要更多地支持使用不同類型接口的多類型用戶,例如在線商店需要為Web顧客提供HMTL主頁、為無線顧客提供XML主頁、為系統管理員提供JFC/Swing接口、為供應商提供基于XML的Web服務等(見圖4)。

圖4 Java Pet Store 支持的各種類型用戶關系圖
當開發一個支持單一類型客戶端的應用時,可以把數據訪問邏輯、顯示控制邏輯和接口邏輯交織在一起。但對于支持多類型客戶端的企業系統來說,這是很麻煩的。因此:
◆ 對于每種類型的客戶端接口,需開發不同的應用;
◆ 每個應用的非界面代碼是重復的,在實現、測試和維護方面需重復工作;
◆ 復制工作本身是昂貴的,因為界面與非界面代碼交織;
◆ 重復工作不可避免,而且是有缺陷而緩慢的。
2.使用模型—視圖—控制架構
通過在J2EE應用中使用模型—視圖—控制架構,把核心數據和數據訪問功能與使用這些功能的顯示控制邏輯分開,如圖5所示。這種分離允許多視圖共享同樣的企業數據模型。

圖5 MVC架構
MVC架構起源于Smalltalk,最初用來在傳統的圖形用戶界面模型中映射輸入、處理和輸出任務。然而,它可以直接用來映射多層企業應用中的相關概念,具體概念介紹如下:
模型(Model)代表企業數據和業務規則,用來控制訪問和數據更新。模型是接近現實世界的服務軟件,因此現實世界的建模技術可以應用模型。
視圖(View)代表模型的內容。它通過模型訪問企業數據并指定這些數據的顯示。視圖負責模型狀態改變后呈現給用戶的數據也相應改變。可以通過推(Push)模型實現,即視圖在模型中注冊獲取更新指令,或者拉(Pull)模型,即由視圖負責在需要獲取最新數據的時候調用模型。
控制(Controller)把與視圖交互轉化成模型執行的動作。在獨立運行的GUI客戶端,用戶交互可能是按鈕或菜單,而在Web應用中是GET和POST HTTP請求。模型執行的動作包括激活業務處理進程或改變模型狀態。以用戶交互和模型動作結果為基礎,控制通過選擇合適的視圖完成相應功能。
MVC架構有如下優點:
◆ 多視圖使用同一模型。模型與視圖分離允許多視圖使用同一企業模型。因此,企業級應用模型組件容易實現、測試和維護。
◆ 容易支持新類型的客戶端。支持一個新類型的客戶端,只需寫一個視圖和控制,然后把它連到現存的企業模型中。
分析Java Pet Store應用
視圖
視圖是用戶界面和應用程序的接口。在Java Pet Store中,視圖在Web層實現。共有三種組件實現視圖:JSP頁面、JSP自定義標記和JavaBean。視圖部分涉及到三方面內容:
1.屏幕
屏幕是一個頁面顯示的所有內容。根據需要,在ScreenDefinitions.jsp中定義如下屏幕:
Name:MAIN_SCREEN,DEFAULT_SCREEN
Name:CATEGORY_SCREEN
Name:SEARCH_SCREEN
Name:PRODUCT_SCREEN
Name:PRODUCT_DETAILS_SCREEN
Name:CART_SCREEN
Name:CHECKOUT_SCREEN
Name:PLACEORDER_SCREEN
Name:COMMIT_ORDER_SCREEN
Name:SIGNIN_SCREEN
Name:SIGNUP_SCREEN
|
2.模板
因為要使整個網站的頁面具有相同的特征,如每個頁面都要有Logo、Banner等相同的元素,所以采用模板定義頁面的不同組成部分。本示例中定義的模板元素有footer.jsp、banner.jsp和index.jsp等。ScreenDefinitions.jsp定義好的屏幕包括這些模板元素,通過include指令包含到頁面中
3.視圖選擇
視圖的選擇是通過控制來完成的。控制根據實際情況分析用戶顯示視圖的ID,運行模板把整個視圖顯示出來,如圖6所示。

圖6 視圖選擇
模型
模型的狀態是視圖顯示的數據來源,也是控制的具體對象。在J2EE中,描述模型的狀態采用三種EJB:無狀態會話EJB、有狀態會話EJB和實體EJB。
1.輔助對象
有兩種主要的輔助對象:數據庫訪問對象和值對象。對于實體EJB來說,數據庫訪問對象封裝了數據庫訪問的方法,如AccountDAO等。對于所有EJB的屬性值,則都由一個值對象來封裝,如ShoppingCartModel、AccountModel等。
2.EJBs
本示例用到的EJBs如圖7所示。

圖7 Java Pet Store使用到的EJBs
3.模型狀態到視圖的綁定
一個模型對應多個視圖,實現視圖的綁定方法是:ModelUpdateListener和ModelUpdateNotifier實現了一種注冊-監聽模式,通過調用監聽器的performUpdate方法來使視圖得到更新。例如:
public class AccountWebImpl extends AccountModel
implements ModelUpdateListener{
private ModelManager mm;
private Account acctEjb;
public AccountWebImpl(ModelManager mm){
super(null,null,null};
this.mm=mm;
mm.addListener(JNDINames.ACCOUNT_EJBHOME,this);
}
public void performUpdate(){
if(acctEjb==null) {
acctEjb=mm.getAccountEJB();
}
try{
if(acctEjb !=null)copy(acctEjb.getDetails());
}catch(RemoteException re){
throw new GeneralFailureException(re);
}
}
}
|
控制
控制負責處理用戶請求、調用相應的模型、更新模型的狀態、刷新視圖以及返回用戶合理的頁面。示例的所有控制對象如圖8所示。

圖8 控制對象圖
1.RequestProcessor
RequestProcessor接收并處理用戶的所有請求,調用RequestToEventTranslator對象把請求轉換成預定義的事件,在事件處理完成后,進行視圖更新。 代碼如下所示:
public class RequestProcessor{
private ShoppingClientControllerWebImpl scc;
private ModelManager mm;
private ModelUpdateNotifier mun;
private RequestToEventTranslator eventTranslator;
private SecurityAdapter securityAdapter;
public void init(...) {
mm = (ModelManager)session.getAttribute("modelManager");
mun = mm;
SCC = new ShoppingClientControllerWebImpl(session);
eventTranslator= new RequestToEventTranslator(this,mm);
}
public void processRequest(HttpServletRequest req){
checkForWebServerLogin(req);
EStoreEvent event = eventTranslator.processRequest(req);
if (event != null){
Collection updatedModelList = scc.handleEvent(event);
mun.notifyListeners(updatedModelList);
}
}
}
|
2.ShoppingClientControllerWebImpl
ShoppingClientContronerWebImpl是調用EJB層的ShoppingClientController代理對象,代碼如下所示:
public class ShoppingClientControllerWebImpl{
private com....ejb.ShoppingClientController sccEjb;
private HttpSession session;
public ShoppingClientControllerWebImpl(HttpSession session){
this.session = session;
ModelManager mm= (ModelManager)session.getAttribute("modelManager");
sccEjb = mm.getSCCEJB();
}
public synchronized AccountModel getAccount(){
return sccEjb.getAccount().getDetails();
}
......
public synchronized Collection handleEvent(EStoreEvent ese){
return sccEjb.handleEvent(ese);
}
public synchronized void remove() {
sccEjb.remove();
}
}
|
3.ShoppingClientController
ShoppingClientController是有狀態的會話EJB,它為每個用戶建立一個單獨的實例,負責購物車和賬號的生命周期,并負責處理事件。同時它也控制狀態機StateMachine的生命周期。代碼參見賽迪網http://linux.ccidnet.com的期刊瀏覽2003年第6期。
4.StateMachine
StateMachine實現核心的業務邏輯,它負責改變模型的狀態,包括處理每個業務事件的方法。代碼參見賽迪網http://linux.ccidnet.com的期刊瀏覽2003年第6期。
小結
J2EE網站的開發方法,即是Internet的開發方法。Internet開發的發展可以劃分為三個階段:第一階段是將業務邏輯和表現邏輯完全集成在一起,采用HTML、JSP和Servlets技術開發;第二階段是將業務邏輯和表現邏輯分開,采用HTML、JSP、Servlets、JavaBeans Compoments和Custom Tags技術開發;第三個階段是MVC設計模式(J2EE的開發方法)。今天,MVC設計模式已成為Internet開發發展的主流。無論是通過第一階段開發的應用,還是通過第二階段開發的應用,都會面臨著開發人員的分工、應用的可維護性和可擴展性及可測量性的問題。為此,我們在設計階段關心的重點是系統結構的復雜程度、代碼之間的耦合度、代碼的易維護性、應用框架的可重用性、EJB組件的可重用性和易測試性,以及不同技能開發人員的分工等。用縱觀全局的眼光來看,在Internet系統開始設計的時候,就要考慮開發、運行、維護階段的問題
|