程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 兩種設計模式在EJB開發中的應用

兩種設計模式在EJB開發中的應用

編輯:關於JAVA

摘要:本文介紹了J2EE的分層結構,深入研究了如何使用Session Facade模式和ValueObject 模式設計EJB,並對其開發過程做了較詳細的說明。

關鍵字:EJB ;值對象模式;會話外觀模式

一、概述

與傳統的二層體系結構相比,J2EE有兩個特點:

1、定義了一套標准化組件,通過為這些組件提供完整的服務。

2、使用多層分布式的應用程序模型。應用程序的邏輯根據其實現的不同功能被封裝到不同的組件中。如圖1所示。

這種多層結構使企業級應用具有很強的伸縮性,允許各層專注於某種特定的角色:

1、Client Tier用於顯示。

2、Web Tier用於生成動態顯示。

3、Business Tier用於實現業務邏輯。

4、EIS Tier用於數據庫服務。

其中,用於實現業務邏輯的EJB組件架構是J2EE的基礎和最重要的部分。

正是認識到J2EE平台作為一種可擴展的、全功能的平台,可以將關鍵的企業應用擴展到任何Web浏覽器上並可適合多種不同的Internet數據流、可連接到幾乎任何一種傳統數據庫和解決方案,J2EE已經成為開發電子商務應用的事實標准。

為了使開發者開發出規范的、可重用的應用程序,J2EE為我們提供了大量的模式。模式盡管有時不易理解,但使用卻非常簡單,它提供了強大的可重用機制,避免了開發者和設計者的重復投資。

可是,面對如此多的模式,初學者往往不知如何下手,為此,作者結合以往的開發經驗,詳細介紹如何使用模式完成EJB的設計。

二、設計與實現

1.值對象模式

J2EE應用程序把服務器端業務組件實現為會話Bean和實體Bean。對於實體Bean的創建,開發人員通常采用CMP(容器管理持久性)模式,其好處在於容器提供公共的服務,例如目錄服務、事務管理、安全性、持久性、資源緩沖池以及容錯性等,使開發人員不必維護將會集成到業務邏輯中的系統級代碼,只需專注於商業邏輯。

一般來說,有了實體bean,就可以通過調用業務組件的一些方法向客戶端返回數據。初學者往往會認為既然客戶端可以與服務器通信,那麼任務就算完成了。可是,問題恰恰出在這裡。業務組件的get方法只能返回一個屬性值,這就導致需要獲得所有屬性值的客戶端需要多次調用業務對象的get方法,如圖2-1所示。每次調用都是一次網絡調用,都會造成系統性能的退化,當調用次數增多時,系統性能就會嚴重下降。

這就要求有一種方法使客戶端可以一次調用得到所需的大量數據,這種方法就是Value Object(值對象)模式。值對象是任意的可串行化的Java對象,也被稱為值的對象,它在一次網絡傳輸中包含和封裝了大量的數據並被保存在內存中。這樣,當客戶端需要再次使用數據的時候,不用再次到數據庫中查詢,而是直接在內存中讀取值對象,節省了大量的時間和系統開銷,如圖2-2。

值對象模式有兩種策略――可更新的值對象策略和多值對象策略。

可更新的值對象策略中,業務對象負責創建值對象,並且在客戶端請求時把該值對象返回給客戶端;同時,業務對象也可以從客戶端接收數據,形成值對象,並使用該對象來完成更新。

例如,在銀行系統的例子中,Account 中提供一個以AccountValue為參數的setAccountValueObject方法,這樣客戶端可以通過這個方法來設置值對象的值,而不采用實體bean--Account中設置每個屬性的方法(setBalance()),因為後一種方法會導致大量的網絡負載。由於值對象的易變性,所以值對象類必須給每個可以被客戶端更新的屬性提供設置方法。例如,AccountValue中的setBalance()方法。這樣,一旦某客戶端擁有來自業務對象的值對象,客戶端就可以在本地調用必要的設置方法來更改屬性值,然後調用業務對象的setAccountValueObject()方法更新業務對象。

多值對象策略

一些應用程序業務對象往往比較復雜,在這種情況下,根據客戶端請求不同,有可能單個業務對象會產生多個不同的值對象。在這種情況下,可以考慮采用多值對象策略。這種策略的實現比較簡單,就是在entity bean中增加不同的Get×××ValueObject()方法和set×××ValueObject()方法。

2.Session Facade 模式

有了實體Bean,客戶端就可以直接調用它以獲得數據。也就是說實體Bean封裝了業務數據,並把他們的接口暴露給客戶,因而也就把分布式服務的復雜性暴露給客戶。在對J2EE 應用程序環境下,一般會產生如下問題:

1、緊密耦合,這回導致客戶端和業務對象的直接依賴關系

2、客戶端和服務器之間的網絡方法調用太多,容易導致網絡性能問題

3、缺乏統一的客戶訪問策略,容易誤用業務對象

4、如果實體bean的API改動,那麼用戶端的一些代碼也要修改,擴展性很差

解決這些問題的方法就是把客戶端和實體bean分割開。本文采用Session Facade模式,如圖3-2所示。該模式通過一個Session Bean,為一系列的實體bean提供統一的接口來實現流程。事實上,客戶端只是使用這個接口來觸發流程。這樣,所有關於實體bean實現流程所需要的改變,都和客戶端無關。當實體bean改變時,我們不用改變客戶端的代碼,只要對Session Bean做出相應的改變即可,大大提高了系統的可維護性。

通過實體bean來表示業務對象是session fa?ade的最常見用法。但多個實體bean參與某用例時,不必向客戶暴露所有實體bean。相反的,用session bean 包裝這些實體bean ,並且提供粗粒度方法來執行所需的業務功能,從而隱藏了實體bean交互的復雜性。

但是千萬不要以為Fa?ade模式就是簡單的用Session Bean把Entity Bean的所有方法統統封裝起來,而不提供任何額外的抽象。其實這是對Fa?ade模式的濫用。這樣做並不是降低整個系統的復雜性,而是把復雜性轉移到另一個對象上。

正確應用Facade模式應遵循三條基本原則:

1、他們自己不作實際工作,而是委派其他對象作實際工作。

2、他們提供簡單的接口。

3、他們是底層系統的客戶端接口。他們應該把特定於子系統的信息封裝起來,並且不應該在不必要的情況下公開它。

三、具體代碼

下面用一個簡單的銀行系統的例子來解釋Fa?ade模式和Value Object模式的具體應用。

創建Entity Bean。其中對每個屬性的get和set方法是自動生成的,我們不去管它。

public interface Account extends javax.ejb.EJBObject {
private AccountValue creaeAccountValueObject();
void setAccountVauleObject(AccountValue v);
AccountValue getAccountValueObject();
……}

其中

private AccountValue createAccountValueObject(){
AccountValue vo=new AccountValue();
vo. accountNumber=accountNumber;
Vo.balance=balance;
……}
public AccountValue getAccountValueObject(){
return createAccountValueObject();
}
public void setAccountValueObject(AccountValue v){
accountNumber=v. accountNumber;
balance=v.balance;
……}

用值對象封裝Entity Bean數據。

public class AccountValue implements java.io.Serializable {
private java.lang.String accountNumber;
private double balance;
void setBalance(double newValue)
……}

用Factory或者是Action類邏輯方法,涉及到數據的地方使用值對象。

public class AccountFactory {
  private static AccountHome accountHome = null;
   ……
  public java.util.Vector getAccounts(String userid) throws FactoryException {
   try { Vector vect = new Vector();
    AccountHome home = getAccountHome();
    Enumeration accountRefs = home.findByUserid(userid);
    while (accountRefs.hasMoreElements()) {
     Account acc = (Account)accountRefs.nextElement();
     AccountValue valueObject =acc.getAccountValueObjcet();
     vect.addElement(valueObject);}
     return vect; }
   ……}

在Session Bean的get方法中調用Factory或者是Action對象。

public java.util.Vector getAccounts(String userid) throws FactoryException {
  AccountFactory fact = new AccountFactory();
  Vector result = fact.getAccounts(userid);
  return result;
}

正如代碼所示,使用session facade模式,可以

1、提供統一的接口:會話外觀抽象了業務組件交互的復雜性,並且向客戶端提供一個更簡單的接口。

2、減少耦合提高可管理性:會話外觀分離了業務對象和客戶端,這樣可以減少緊密耦合,以及客戶端對業務對象的依賴性。

3、提供粗粒度訪問:會話外觀減少客戶端和服務器之間的網絡負載。客戶端與業務數據的說有交互都是通過會話外觀以粗粒度的發拿過是進行的。

通過使用

從上述代碼可以看出,使用模式之後,大大改善了系統性能,也提高了代碼的可重用性。此外,開發者也可以采用其他的小模式來提高系統性能,比如服務器定位模式,在此不作進一步介紹。

四、總結

綜上所述,本文詳細地介紹了使用值對象模式和會話模式設計商業邏輯層的方法,很好的實現了數據封裝和合理分層,大大提高了系統的可維護性和可伸縮性,也顯著的簡化了具有可伸縮性和高度負責的企業級應用的開發。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved