<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    love fish大鵬一曰同風起,扶搖直上九萬里

    常用鏈接

    統計

    積分與排名

    friends

    link

    最新評論

    EJB設計模式概述(轉)





    本文關鍵字:EJB,?設計模式,?pattern,?session bean,?entity bean,?message driven bean,?command,?dto,?factory
    文章工具
    推薦給朋友?推薦給朋友
    打印文章?打印文章
    一. 設計模式重要性
    采用EJB技術的J2EE項目中,EJB架構的設計好壞將直接影響系統的性能、可擴展性、可維護性、組件可重用性及開發效率。項目越復雜,項目隊伍越龐大則越能體現良好設計的重要性。

    二. 常見EJB設計模式

    Session Facade Pattern
    通常項目中,客戶端往往需要頻繁的對服務器端數據進行操作。當采用實體EJB作為數據的抽象層時,如果直接讓客戶端程序與實體EJB交互,會產生實現一個業務需求便需要大量的EJB屬性操作(如下圖1)。這直接導致如下問題:網絡負載大(遠程客戶端時)、并發性能低、客戶端與服務器端關聯度大、可重用性和可維護性差、性能
    因此有必要在客戶端與實體EJB層間加入Session?。牛剩聦樱赟essino EJB中實現商業邏輯并封裝對實體EJB的操作。(如下圖2)

    圖1:客戶端直接與實體EJB交互

    圖2:通過SessionEJB層實現
    Session Fa?ade模式的好處是:降低了網絡負載,SessionEjb可以調用實體EJB的本地接口;將商業邏輯與商業數據隔離;維護與開發方便;顯著提高性能。
    Session Fa?ade模式因其簡單使用,是目前使用很廣的模式。但具體應用過程中應注意:避免將所有的操作封裝到一個很大的SessionEJB內;服務器端數據結構應由實體EJB實現,除非特例否則避免直接的數據庫操作;SessionEjb內某些系統通用操作的代碼容易重復(比如權限檢查等,解決辦法是將系統通用服務封裝在Java Class內)。

    Message Facade Pattern
    很多時候,一次Request需要操作多個EJB又不需要得到即時返回。對這種異步調用,通常應用Message Fa?ade Pattern.
    這種時候,如采用Session Fa?ade Pattern存在如下問題:
    1. 客戶端等待返回的時間過長。一個SessionEjb的實例在完成客戶請求過程中中涉及到的每一次對其他實體Ejb的調用過程中都會被鎖定直到得到實體EJB返回信息后才能進行下一步操作。這樣造成客戶不必要的等待,并很容易因時間導致整個事務失敗。
    2. 系統可靠性和容錯性低。如果需要調用不同系統或服務器上或多個異構數據源的多個EJB時,任何一個環節出錯,均導致客戶請求失敗。
    以Message-Driven Bean為基礎的Message Facade Pattern則可以解決上述異步請求需求。具體架構見下圖3

     圖3:使用Message Facade Pattern

    Message Facade Pattern的不足之處在于:
    1. Message-Driven Bean沒有返回值。這樣通知客戶執行結果只能依賴于Email或人工等其他手段。
    2. Message-Driven Bean執行過程中無法將捕獲的異常直接返回給客戶端,即無法使客戶端直接直到錯誤信息。
    3. Message-Driven Bean通過接收Message響應客戶請求,對Message內容的合法性(比如對象的類型等)依賴與客戶端.容易產生運行時錯誤。
    Message Facade Pattern經常與Session Facade Pattern在同一個項目里共同使用。

    EJB Command Pattern

    Session Facade Pattern中將商業邏輯實現封裝在Session EJB中,這種做法帶來諸多益處之外也帶來如下問題:
    1. 由于業務經常的變化,導致經常需要更新Session EJB代碼。
    2. 客戶端代碼不得不包含大量EJB相關的API,不利于后期項目維護。
    3. 項目開發測試需要經常的EJB重部署過程。
    引起上述問題的重要根結就是Session EJB本身重量級組件,其開發測試部署工作量較大,開發周期較長。以上不足可以通過EJB Command Pattern克服。
    EJB Command Pattern中將商業邏輯實現封裝在普通的Java Class(稱之為Command Bean)中。該模式的具體實現有很多種,通常的框架都包括三部分:
    1. Command Bean.由應用開發者寫的具體實現某商業操作的Java Class.主要包含getXXX(),setXXX(),execute()方法。
    2. Client-Side Routing Logic.由多個Class組成,用于將請求轉發至Command Sever,這個過程對客戶是透明的。這部分代碼可以跨項目使用。路由規則中可以考慮用XML技術。
    3. Remote Command Server.實際執行商業操作請求。通??梢杂肧ession EJB層實現。

     整個框架見下圖4:



     圖4:Command的基本框架
    EJB Command Pattern具有如下好處:
    1. 適應與需要快速開發環境。因Command Bean是輕量級的Java Class,其編譯和調試比較方便。
    2. 將表現層與商業實現層隔離,同時將客戶端代碼與EJB層隔離。
    3. 將客戶端代碼開發與服務器端代碼開發相對清晰。早期可以創建空的Command Bean方便客戶端代碼調試。
        EJB Command Pattern的弱處在于:
    1. Command Bean中對事務的控制不如Session EJB中。
    2. Command Bean是無狀態的。
    3. 無法將異常直接返回給客戶。
    4. 在大項目中,由于商業邏輯復雜,常導致大數量的Command Bean存在.
    5. 作為Command Server的Session EJB打包時必須包含Command Bean以致存在維護上的不便。
      EJB Command Pattern的一個實際實現可以參考IBM's Command Framework.


    Data Transfer Object Factory
    基于EJB的J2EE項目,經常需要在客戶端與服務器端傳輸大量數據。數據的組織形式常用的是DTO(Data Transfer Object,服務器端數據對象的抽象)。但因為客戶端表現層經常是變化的,所需要服務器端數據也變動頻繁,換句話說,DTO的數量和屬性經常要更改。因此如何以及在何處生成和維護DTO便是需要考慮的問題。
    一種解決方案是直接在Entity EJB中直接處理,即在Entity EJB的Bean類中加入getXXXDTO()、setXXXDTO()等。但這樣做導致EJB與DTO層緊緊綁定。一旦DTO更改,與該DTO相關的EJB即需要重編譯打包。EJB層與客戶端層相關聯不僅使維護困難而且導致EJB的重用性大大降低。
    更好的解決方案是利用Data Transfer Object Factory封裝對DTO的操作邏輯(如下圖6)。


    圖6:DTO Factory示例
    DTO Factory具體實現方式通常有兩種:
    1. 普通Java Class實現,用于Session Facade Pattern使用DTO環境下。
    2. Stateless Session EJB實現,用于非EJB客戶端使用DTO環境下(見圖7)。


    圖7:SessionEJB實現DTOFactory
    DTO Factory帶來如下好處:
    1. 使Entity EJB的重用成為可能。由于不含DTO處理邏輯,Entity EJB功能單一化,只作為數據源。不通客戶端通過各自的DTO Factory可以從同一個Entity EJB得到各自所需的個性化數據(自定義DTO)。
    2. 提高可維護性和性能。
    3. 可以根據在DTO Factory層生成很復雜的DTO結構,諸如繼承、關聯關系等,而對客戶端提供一個透明、細化的數據接口。
       使用DTO Factory時需要注意的是:不需為每個Entity EJB定義一個Factory。可以為一系列相關的Entity EJB創建一個Factory,或者只創建一個Factory。

    Generic Attribute Access

    使用Entity EJB作為商業數據層時,我們首先需要從數據庫加載數據,創建對應的Entity EJB實例,之后對內存中Entity EJB實例的屬性進行相應操作。對屬性的操作比較直接的做法是:直接調用Entity EJB的getXXX()/setXXX(),通常利用EJB2.0的本地接口;通過DTO Factory生成DTO。但這兩種做法都存在如下問題:
    1. 當Entity EJB的屬性特別多時候,以上做法會帶來復雜羅嗦的代碼,使EJB變的龐大無比。
    2. 使Entity EJB的客戶端(比如Session EJB)和Entity EJB的接口緊密關聯。Entity EJB屬性的增刪都需要更改客戶端代碼,給項目開發和維護帶來不便。
    事實上可以利用更通用的方式訪問Entity EJB的屬性,即定義Generic Attribute Access Interface。見下圖8:


     圖8:Generic Attribute Access Interface示例

    Generic Attribute Access Interface由Entity EJB的本地或遠程接口實現,并利用Hash Maps傳輸數據。實現方式常見如下:
    1. BMP類型實體EJB可以在Bean類中定義包含所有屬性的私有成員變量HashMap。
    2. CMP類型實體EJB可以在Bean類中可以適用Java Reflection API實現。
    3. 建立一個父類,在不同的情況下定義子類重載父類方法。
    使用Generic Attribute Access Interface需要在客戶端與服務器端對屬性以及對應的關鍵字建立統一的命名習慣。常見的做法如下:
    1. 建立并保持良好的文檔記錄和命名約定。
    2. 在實體EJB的實現類中定義靜態成員映射屬性。
    3. 創建共享靜態類,通過成員變量映射實體EJB屬性。
    4. 通過JNDI在服務器端保存屬性映射關系。
    Generic Attribute Access Interface的運用帶來一下益處:
    1. 接口實現后對不通實體EJB都適用。
    2. 對屬性較多實體EJB能精簡代碼,并更具維護性。
    3. 使運行中動態增刪實體EJB屬性成為可能。
    Generic Attribute Access Interface的缺點在于:
    1. 訪問EJB屬性時增加了額外的操作。需要通過關鍵字映射屬性,最后還需進行類型轉換。
    2. 需要建立客戶端與服務器端的命名約定。
    3. 因為通過HashMap操作時候需要進行類型轉換,容易產生運行時類型不匹配異常。


    Business Interface

    EJB規范要求Bean實現類必須實現所有在遠程(或本地)接口中定義的所有方法,同時不允許Bean實現類直接繼承遠程(或本地)接口。這就導致編譯時候很容易產生兩者不一致的問題,即遠程(或本地)接口中定義的某方法為在Bean實現類中被實現等錯誤。為避免上訴錯誤,可以利用應用服務器廠商所提供的工具。但也可以應用EJB的設計架構來實現:定義商業接口。
    Business Interface即創建自定義商業接口,在接口中定義所有EJB提供的商業方法,并讓Bean實現類和遠程(或本地)接口都實現該商業接口。其繼承關系見下圖9:


    圖9:商業接口的使用
    Business Interface是個普通的Java Class。依賴于使用本地接口與遠程接口的不通,Business Interface的定義略有不同:應用與遠程接口時,在接口中的方法需要拋出java.rmi.RemoteException;而應用與本地接口時候則不需要作任何特別處理。
    應用Business Interface時候必須注意一點:EJB規范不允許直接EJB的實例將對自己的引用(this對象)返回給客戶端,否則編譯時候即報錯。但使用Business Interface后,編譯時候無法檢查出有無將this對象返回給客戶端。這一點需要程序員自己保證。


    三. 內部數據轉換策略

    Data Transfer Object
    基于EJB的J2EE多層架構應用中,經常涉及的一個問題就是如何在各層之間傳遞批量數據,比如客戶端對服務器端數據的批量讀寫操作等。比如需要得到實體EJB的屬性,直接的方法是多次調用不通的屬性,如下圖10:


    圖10:低效的數據傳遞方式
      但這種方法容易導致許多問題,比如性能以及代碼的復雜度等,更有效的辦法是在一個調用中得到所有需要的屬性。所以可以引入Data Transfer Object來封裝所需要的屬性,并在客戶與服務器端通過傳遞該對象一次實現對數據的操作。如下圖11:

     圖11:通過DTO傳遞數據
      
    DTO為普通的Java Class,通常是服務器端數據的快照。由于網絡傳輸的需要,DTO應該實現java.io.Serializable接口。
    DTO的設計有兩種模型:Domain DTO以及Custom DTO。
    Domain DTO僅僅實現對服務器數據的拷貝,通常與實體EJB為一對一的關系(也存在為多個相關聯的實體EJB對應一個Domain DTO)。Domain DTO通常除用于讀取更改實體EJB屬性外也可用于創建實體EJB時候。實體EJB與Domain DTO對應關系如下圖12:

     圖12:Account EJB 與 Account DomainDTO
    Domain DTO的應用除了DTO所具有的一般優點外,還有別的益處:
    1. 開發迅速。因為一旦實體EJB設計好后,很容易轉換得到Domain DTO。
    2. 可以利用Domain DTO的setXXX()方法在客戶端進行屬性有效性效驗。
    Domain DTO的缺點有:
    1. 客戶端綁定了服務器端數據模型,不利于維護。
    2. 不夠靈活,無法處理客戶端的多樣化數據要求。對一個數百個屬性的實體EJB請求一個屬性時候卻返回一個包含所有屬性值的Domain DTO明顯是笨重的實現。
    3. 導致代碼的重復。
    4. Domain DTO中如果嵌套包含了別的Domain DTO時,一旦需服務器端數據的更改而需要重定義Domain DTO模型時候異常困難。

    Custom DTO則可以克服上述的一些缺點。Customer DTO僅僅封裝用戶感興趣的服務器數據集即可以根據客戶端需求創建Customer DTO。這樣作的優點是靈活高效;缺點是大項目中可能導致大量的Customer DTO存在。
    通常Domain DTO可以用于數據的更新與創建;Customer DTO可以用于客戶用于表現層的數據讀取。兩者可以相輔相成。而且使用DTO一般與DTO Factory同時使用。

    Domain Transfer Hash Map
      DTO的使用往往缺乏通用性。不通的用戶案例需要創建不同的DTO。當項目很復雜時,從維護性考慮需要更好的數據傳輸的實現方式。
    Domain Transfer Hash Map即利用HashMap作為客戶所需數據集的封裝。好處是:
    1. 良好的維護性。
    2. 較大的通用性。不同的客戶端可以使用相同的數據傳遞方式。
    缺點是:
    1. 需要維護客戶端與服務器端在屬性及其對應關鍵字的映射關系。
    2. 當需要使用基本類型的數據時候,因為Hash Map的限制必須將基本類型先轉換成對象。
    3. 使用得到的數據時,需要進行類型強制轉換。

    Data Transfer RowSet
    當需要處理直接的JDBC調用得到的結果集時,顯然用DTO/Hash Map已經不合適,因為需要對大量數據進行類型轉換等額外操作是很費資源和不必要的,而且最終用戶常需要以表格式樣顯示數據。
    所以對二維表式數據,更好的處理方式是利用Data Transfer RowSet。Data Transfer RowSet通過將ResultSet直接轉換為RowSet傳遞給客戶端。
    在Session EJB中使用RowSet的一段示例代碼如下圖13:

    圖13:使用RowSet
    使用RowSet的好處很多:
    1. 接口通用于各樣的數據庫查詢操作。
    2. 當需要表格式數據顯示時,因為直接從ResultSet得到,所以不需要額外的數據類型轉換。
    缺點是:
    1. 數據庫結構暴露給客戶端。
    2. 不符合面向對象設計思想。
    3. 依賴于SQL。
    Data Transfer RowSet通常用于只讀式數據的顯示操作,經常和JDBC for Reading Pattern連用。

    四.事務和數據持久機制

      JDBC for Reading Pattern

    基于EJB的J2EE應用中,通過EJB對數據庫的操作可以有兩種方式:實體EJB或者Session EJB中直接利用JDBC訪問。
    客戶很多時候取出數據庫中數據并以表格方式顯示。這種情形如果使用實體EJB會導致如下問題:
    1. 引用服務器端頻繁的數據庫查詢和加載操作。因為加載N個實體EJB總需要進行一次find()操作                                                           N次數據加載。
    2. 如果使用Remote接口,引起頻繁的額外網絡操作。
    3. 對關聯關系比較復雜的數據庫表結構,很難直接通過Entity EJB表現。
    因此建議在只需對數據庫表數據進行只讀訪問時候,應該采用JDBC for Reading Pattern,即通過JDBC直接訪問數據庫。除了避免上述使用實體EJB的缺點還帶來一下好處:
    1. 充分利用數據庫能力,比如數據庫的緩存機制。
    2. 減少了對事務控制的資源。
    3. 利用自定義SQL可以按需要比較靈活的讀取數據。
    4. 只需要一次數據查詢,減少了數據庫操作。
    缺點是:
    1. 于J2EE應用的面向對象設計相違背。
    2. 因為Session EJB代碼中包含了自定義SQL,維護性差。
    3. Session EJB中不得不包含JDBC的API,并且需要了解數據庫結構。

    posted on 2006-07-03 09:30 liaojiyong 閱讀(695) 評論(0)  編輯  收藏 所屬分類: EJB

    主站蜘蛛池模板: 亚洲人AV永久一区二区三区久久| 日韩免费观看视频| 亚洲av永久无码精品国产精品| 精品亚洲福利一区二区| 国产美女精品久久久久久久免费| 亚洲日日做天天做日日谢| 青草草色A免费观看在线| 亚洲一级片在线观看| 欧美好看的免费电影在线观看| 国产成人亚洲综合一区| 成人影片麻豆国产影片免费观看| 77777亚洲午夜久久多喷| 成人黄软件网18免费下载成人黄18免费视频 | 最近中文字幕免费完整| 亚洲成AV人片在| 一级毛片aaaaaa视频免费看| 亚洲无码黄色网址| 免费看无码特级毛片| 亚洲AV无码一区二区三区DV| 久久久久久国产精品免费免费男同 | 国产L精品国产亚洲区久久| 免费毛片毛片网址| 无码欧精品亚洲日韩一区夜夜嗨 | 黄页视频在线观看免费| 国产精品亚洲玖玖玖在线观看| 久久嫩草影院免费看夜色| 人人狠狠综合久久亚洲婷婷| 57pao一国产成视频永久免费| 亚洲人成网国产最新在线| 国产91久久久久久久免费| 国产精品免费看久久久香蕉| 久久精品国产亚洲av麻豆色欲| 日韩版码免费福利视频| 精品亚洲成A人在线观看青青| 国产成人综合亚洲AV第一页 | 理论亚洲区美一区二区三区| 日韩亚洲变态另类中文| 亚洲高清免费在线观看| 美女被免费网站在线视频免费 | 欧美a级成人网站免费| 搜日本一区二区三区免费高清视频 |