国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

Session Facade 的規則和模式

瀏覽:10日期:2024-07-20 18:32:15
內容: Kyle Brown Java 執行設計師,IBM WebSphere Service 2001 年 6 月 在過去幾年中,Enterprise JavaBeans&#8482;(EJB)確實已經開始對 Java&#8482; 對象設計產生影響。期間,我們看到的最常使用的 EJB 模式之一是Session Facade 概念。這是一個讓很多開發者都受益匪淺的既強大又非常簡單的概念。然而,我也看到,對這一模式的確切含義及其在實踐中的應用,人們仍有很多誤解。 為了把這個問題講得更明白些,我會在本文中講述 Facade 的一些基本概念以及Session Facade 模式的工作機制,并探討該模式衍生出來的一些問題。希望能借此澄清一些誤解,并幫助開發者正確使用這種模式。 什么是Session Facade?您又為什么需要它? 很多地方都有對Session Facade 模式的清楚描述,也就是 [Sun 2001] 和 [Brown 2000]。我不想照抄那里的全部內容,而打算把它的理論在此作個總結:基本的問題是在 EJB 設計中,EJB 客戶機(例如,Servelet、Java 應用程序,等等)不可直接訪問 Entity bean。 之所以如此,有以下幾個原因: 當依靠 RMI-IIOP 進行跨越網絡的調用時運行態的性能會受到極大影響。如果客戶機請求一個Entity bean 去表示如包含兩項數據(比方說帳戶余額和帳戶所有者姓名)的銀行帳戶,則將需要兩個網絡調用。當大量屬性使網絡調用成倍增加時,很快這些開銷就會變得非常明顯。[Monson-Haefel] 中所說的批量訪問器(bulk accessors)或許是一種解決方案,所謂批量訪問器,就是Entity bean 上的一些方法,它們創建并返回值對象以表示Entity bean 中的數據。它事實上就是 Java VisualAge&reg; 的 CopyHelper Access Beans 采用的解決方案。但是,它有一個令人遺憾的缺陷,就是它假設所有的請求都需要 EJB 中的“所有數據,結果為用戶返回了一些不必要的數據,并導致對更大的值對象進行組織和分解時產生額外開銷。 更重要的是,如果您允許 EJB 客戶機直接訪問Entity bean,那么就要求客戶機了解Entity bean 的內部方法,而這已經超出了客戶機的應知的范圍。例如,操作一個Entity bean 需要知道所涉及到的該實體的關系(關聯,繼承),這樣就把業務模型的所有細節不適當地暴露給了客戶機。另外,操作多個Entity bean 會要求使用客戶端事務 ? 這是另一個使事情復雜化的因素,這意味著 EJB 可能要被從客戶機設計中除去,而不是添加上去。 大多數設計師已經發現為了在 EJB 設計中避免直接訪問Entity bean 的解決方案都可以在 Gamma 中描述的 Facade 中找到。 Gamma 這樣描述 Facade 模式:“為子系統中的一套接口提供了一個統一的接口。Facade 定義了一個更高層次的接口,使子系統更容易使用。1在 EJB 中應用這種思想一般意味著您應該創建一個擔當 Facade 的Session EJB,然后把構成子系統的一套Entity bean “包裝起來。這樣,客戶機就和Entity bean 實現的細節分離開來了,而且不必自己管理事務管理的細節。 但問題是有很多人到此就打住了。然后他們輕松地往下做,開始把Entity bean 包裝到Session bean 中,而不考慮 Facade 模式所描述的其它內容以及 EJB 設計中由 Facade 模式衍生出來的問題。這很可能是由于把得到的 Facade 的“二手信息都當真,而沒去研究原始模式的緣故。如果我們確實花了些時間去理解 Facade 衍生的問題,我們將可以看到很多該模式所固有的其它有益的設計可能性。 Facade 模式的要點 Gamma 中描述了很多我們應該了解的 Facade 模式的要點。前面幾點可在 Facade 模式的“適用性描述部分找到,它描述了在什么情況下您會需要應用該模式。它們是:“當您想為復雜的子系統提供一個簡單接口時……請使用 Facade 模式和“當您想把子系統分層時……請使用 Facade 模式。使用 Facade 為每一層子系統定義一個入口點。2 從對 Facade 模式的討論中,我們可以提煉出兩個觀點。第一點是 Facade 應該提供子系統的一個抽象視圖,而不是簡單地把整個子系統本身的 API 直接包裝起來。不幸的是,我在實際中多次看到開發者創建的Session bean 把Entity bean home 和Entity bean 對象的全部方法直接包裝起來,而不提供任何額外的抽象,這是對該模式最可惡的濫用情況之一。請記住,這種思想是想降低整個系統的復雜性,而不是把復雜性轉移到另一個對象上。 第二點,也是更微妙的一點,與分層有關。這個觀點認為您可以用多重 Facade 來隱藏下層子系統的細節。因此,在這里您可以這樣設想,Session Facade 應該在其它 Facade 之上,位于最上層,是對底層業務邏輯細節的進一步抽象。這一點很關鍵。當您看完下面兩條(分別出自 Gamma 中論述 Facade 模式的“協作和“相關模式部分)敘述后,就會更加清楚這一點: “客戶機通過把請求發送給 Facade,再由 Facade 把請求轉發給適當的子系統對象來與子系統通信。3 “facade 只是對通往子系統對象的接口進行抽象以使它們更易于使用;它不定義新功能。4 我把這幾點總結如下:Facade 不做系統的實際工作;而是委托其他對象輪流做這個工作。由此推理出您必須正確地放置這些對象,以便使該模式能按照您所期望的運行。 這一點是本模式的兩種流行表達 [Sun 2000] 和 [Sun 2001] 之間的主要不同之處。第一個版本,即 [Sun 2000],是 J2EE 規劃的一部分,它把這種模式稱為“Session Entity Facade。它意在表明“為一堆企業 beans 提供單一的接口。它描述了這樣一種模式,即所有的數據存取都通過Entity bean 來完成,Session bean 則為這些Entity bean 提供接口。現在的問題是 [Sun 2000] 不一定非要以 EJB 為中心。它根本不涉及其它對象類型,并且假設系統中只有 EJB 一類對象。根據我的經驗,我認為這會導致根本不能在工程間重用的臃腫的Session對象,而且,在同一個工程內,當需求有一點不同時就會出現問題。 現在,[Sun 2001] 則更通用,也沒有上述問題的困擾。它簡單地把這種模式稱為“Session Facade。它的解決方案規定您應該“把Session bean 當作 facade 來用,以封裝參與工作流的業務對象之間的交互操作的復雜性。它根本不限制您的業務對象應該為 EJB,因此是一個更加靈活的方法。 Session Facade 的重要規則 那么我們該如何應用這些關于針對會話的 Facade 的規則呢?這對我們的 EJB 設計又意味著什么呢?我在設計Session Facade 時遵循三條基本原則: 它們自己不做實際工作;它們委派其它對象做實際工作。這意味著Session facade 中的每個方法都應該很小(異常處理邏輯不計算在內,代碼應為五行或更少)。 它們提供簡單的接口。這意味著 facade 方法的數量應相對較少(每個Session bean 中僅有約 24 個)。 它們是底層系統的客戶端接口。它們應該把特定于子系統的信息封裝起來,并且不應該在不必要的情況下公開它。 那么它的工作機制呢?您還能代理別的哪些類型的對象呢?這又會給您的設計帶來什么好處呢?在我的一篇早期論文和 [Brown 2001] 這本書中,我已論述了其中一些問題,在那里可以找到一些詳細信息。但,總的來說,在我的多數 EJB 設計中我通常會找到以下四類對象: 值對象是包含了客戶機所請求的數據的、可序列化的 Java bean。它包含Entity bean 和其他數據源所包含的數據的一個子集。它是Session EJB 方法的返回類型。[EJB 2.0] 和 [Sun 2001] 都描述了值對象和值對象的用途。請注意 [Fowler 2001] 稱其為“數據傳輸對象( Data Transfer Objects ),[Brown 1999] 也使用這個名稱。我個人覺得數據傳輸對象是描述性更好的術語,但不幸的是,Sun 的術語似乎更通用。 對象制造廠 (Factory) [Brown 1999] [Brown 2000] 負責構建值對象。它能完成辨別不同的數據源、創建值對象的實例、填充值對象的實例等等工作。每個 factory 類 都可以從多個數據源中檢索數據或更新其中的數據。在您的對象模型中,每個“根對象都應該有一個 factory 類。(根對象是那些“包含其它對象的對象。)從某種意義上說,對象 Factory 類在 JDBC 或持久的 Entity bean 子系統上擔當 Facade,實現 Gamma 中提到的分層原則。 Entity EJB 應該是標準的、企業全局范圍內可用的“數據源。Entity bean 不應包含特定于應用程序的域邏輯,也不應限制為只能在單一應用程序內工作。請注意Entity bean 是可選的,它不是這種體系結構中必需的部分;Factory 可能像 JMS 隊列或 JDBC 連接那樣簡單地直接從數據源獲取數據。 Action 對象是Session bean 可能調用的唯一對商業業務進行處理的對象。Action 對象只處理與簡單的創建、讀取、更新或刪除數據無關的商業流程。和對象 Factory 一樣,Action 對象也充當內層 Facade。 一個 EJB 對象示例 描述類似這樣的模式遇到的一個問題是,能夠使用這種模式的示例都太大,以至于無法包含在模式自身的描述中。盡管如此,我還是要嘗試舉出如下示例(它顯然很簡單)來說明一下這些對象看起來是什么樣子。 假設我們正在為銀行構建一個 ATM 系統。這是最老掉牙的 OO 設計問題之一,當然其它很多書籍和論文已經討論過它,但它確實有足夠符合我們要求的有趣特點。通過分析,我們發現了兩種 EJB。 從 ATM 到銀行的連接表示為Session bean。該 bean 上有一些方法負責處理您通過 ATM 可以完成的交易 ? 存款、取款以及帳戶間的資金轉移。 帳戶表示為Entity bean(我們的示例采用 CMP,但它在我們的示例中實際上并沒什么影響)表示。它有返回帳戶余額、對帳戶進行借貸處理的方法。 ATM Session bean 的遠程接口如下: package com.ibm.bankexample.ejbs; import com.ibm.bankexample.domain.*; /** * This is the Enterprise Java Bean Remote Interface * for the ATM example. */ public interface ATM extends javax.ejb.EJBObject { void deposit(java.lang.String accountNumber, double amount) throws java.rmi.RemoteException, com.ibm.bankexample.domain.FactoryException; java.util.Vector getAccounts(java.lang.String userid) throws java.rmi.RemoteException, com.ibm.bankexample.domain.FactoryException; void transfer(java.lang.String fromAccount, java.lang.String toAccount, double amount) throws java.rmi.RemoteException, com.ibm.bankexample.domain.InsufficientFundsException, com.ibm.bankexample.domain.FactoryException; void withdraw(java.lang.String accountNumber, double amount) throws java.rmi.RemoteException, com.ibm.bankexample.domain.InsufficientFundsException, com.ibm.bankexample.domain.FactoryException; } 同樣地,帳戶 EJB 的遠程接口如下: package com.ibm.bankexample.ejbs; /** * This is the Enterprise Java Bean Remote Interface * for the Account Entity EJB. */ public interface Account extends javax.ejb.EJBObject { void deposit(double amount) throws java.rmi.RemoteException; java.lang.String getAccountNumber() throws java.rmi.RemoteException; double getBalance() throws java.rmi.RemoteException; java.lang.String getUserid() throws java.rmi.RemoteException; void setBalance(double newValue) throws java.rmi.RemoteException; void setUserid(java.lang.String newUserid) throws java.rmi.RemoteException; void withdraw(double amount) throws java.rmi.RemoteException; } 現在,我們還發現有另外兩種對象類型對我們的系統是有用的。第一種是描述顯示在 ATM 機上的帳戶信息的值對象。這個類看起來如下所示: public class AccountValue implements java.io.Serializable { private java.lang.String accountNumber; private double balance; } 當然,AccountValue 類也有作為屬性的 getter 和 setter 的方法,但我們暫時不考慮它們。 現在,我們基本上有了足夠的信息來理解 ATM EJB 的 getAccounts() 方法的實現。這個方法的實現如下: public java.util.Vector getAccounts(String userid) throws FactoryException { AccountFactory fact = new AccountFactory(); Vector result = fact.getAccounts(userid); return result; } 這個方法展示了Session Facade EJB 的方法的標準模式。它找到合適的幫助對象(Action 或 Factory,在本例中是 Factory),調用幫助對象上的業務方法,然后返回結果。 如這個方法所指出的,我們需要一個 AccountFactory 類來從 Accounts 構建 AccountValues。這個類的類定義如下: public class AccountFactory { private static AccountHome accountHome = null; } AccountFactory 的 getAccounts(userid) 方法的實現如下: 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 = new AccountValue(); valueObject.setAccountNumber( acc.getAccountNumber()); valueObject.setBalance(acc.getBalance()); vect.addElement(valueObject); } return vect; } catch (Exception e) { throw new FactoryException( 'Cannot generate accounts due to wrapped exception ' + e); } } 這個方法使用一個高速緩存的 AccountHome 實例,它是從以下方法中獲取的: private AccountHome getAccountHome() { if (accountHome == null) { try { java.lang.Object homeObject = getInitialContext().lookup( 'com/ibm/bankexample/ejbs/Account'); accountHome = (AccountHome) javax.rmi.PortableRemoteObject.narrow( (org.omg.CORBA.Object) homeObject, AccountHome.class); } catch (Exception e) { // Error getting the home interface System.out.println( 'Exception ' + e + ' in createTimeSheetHome()'); } } return accountHome; } 正如 [Brown 2001] 和 [Gunther 2000] 所描述的那樣,在 WebSphere&reg; 中,高速緩存 EJB home 是一個極好的習慣,因為獲取 JNDI InitialContext 和從 InitialContext 獲取 EJB Home 需要一段時間。 既然您已經看到了Session、Entity和 Factory 如何組合在一起,那我們就來看一個 Action 類的示例。在本例中,我們有一個處理從一個帳戶到另一個帳戶的資金轉移的 Transfer 對象。Transfer 由 ATM EJB 中的 transfer() 方法的實現中創建,該方法的實現如下: public void transfer(String fromAccount, String toAccount, double amount) throws InsufficientFundsException, FactoryException { Transfer trans = new Transfer(); trans.transfer(fromAccount, toAccount, amount); } 請再次注意同樣的流程。不過,這個方法不必從 Action 對象返回值。Transfer 類的定義如下: public class Transfer { private static AccountHome accountHome; } transfer() 方法的實現如下: public void transfer(String fromAccount, String toAccount, double amount) throws InsufficientFundsException, FactoryException { try { Account from = getAccountHome().findByPrimaryKey( new AccountKey(fromAccount)); Account to = getAccountHome().findByPrimaryKey( new AccountKey(toAccount)); if (from.getBalance() < amount) throw new InsufficientFundsException(); to.deposit(amount); from.withdraw(amount); } catch (Exception e) { throw new FactoryException( 'cannot perform transfer. Nested exception is ' + e); } } 您已經看到,Transfer 對象中的 transfer() 方法處理以下細節:定位兩個 Account 實體,確保“From帳戶有足夠的余額,把轉移金額存入“To帳戶,從“From帳戶中提出轉移金額。同樣地,您可以看到 Action 對象的其它方法可以實現您系統中的其它業務規則。 使用 EJB 對象的原因 那么為什么我們需要這第二層對象呢?難道我們從 CORBA 和 RMI 轉到 Enterprise JavaBean 就使事情更簡單了嗎?為什么不把所有的邏輯都放到 EJB 中呢?這有幾個原因。第一個也是最重要的原因是這是一個分層應用程序。在單個對象中放置太多工作從來不是一個好主意。如果您用這種方式來布置由 EJB 調用的對象,可以帶來以下好處: 把工作放在一個會話層上的一套對象中,使我們可以更容易獨立地測試它們,或許甚至可以在 J2EE 應用服務器環境之外對它進行測試。 不同的多個Session Facade 對象可以使用同一層上的對象,而不必擔心事務語義不正確,也沒有跨Session bean 調用可能帶來的網絡和數據組織/數據分解開銷。 第二層對象允許您對那些對象實現多樣化(通過使用 Gamma 中介紹的 Stragtegy 模式),這樣便可以利用應用服務器的特有功能,同時仍然保持整個設計在應用服務器之間的可移植性。例如,[Brown 2000a] 描述了一些特別的高速緩存策略,用于提高那些能在 WebSphere Application Server(高級版)下工作、卻不能在 IBM CICS EJB 支持下工作的 EJB 的性能。通過為同一個 Factory 類或 Action 類提供兩個實現,您便可以保持整個設計的可移植性,同時也最大程度地利用各個服務器的特有功能。 在您不需要 JTA 事務的情況下(例如,您只對單一數據源進行操作),這個模式允許您選擇部署和構建帶或不帶 EJB 的應用程序。例如,在一些簡單查詢中,為避免 EJB 調用的開銷,您可以直接從 servlet 調用 Factory,這能顯著提高效率。 同時,通過回顧幾個工程,我們發現重用只在少數情況下會出現在會話層上。這是因為,每個會話都有針對一個特定應用程序的一個事務設置與方法的特定組合。有了第二層對象則使您可以在內層級別上進行重用,我們在很多工程中都看到過這種重用,包括在企業的一個工程內(在不同的Session bean 之間)和多個工程之間。 我們已經看到,如果采用這種策略,那么您的設計經常可以把無狀態Session bean 當作 Facade 對象使用。由于對某個用戶而言,每個無狀態Session bean 都不是唯一的,這就使您能夠得到無狀態 bean 所提供的另外的可擴展性。 既然我們已經知道了 facde 背后對象的類型,我們就可以開始看看 facade 能對外提供哪些類型的方法了。我們看到 Facade 方法通常屬于以下幾種類型: Collector 方法通常以“get開頭,返回一個對象或一個對象集合(在 EJB 1.0 中是 Emulation,在 EJB 1.1 和 2.0 中則是一個 Java Collection)。如 [Brown 2000] 所述,collector 方法在 Factory 對象中實現。 Updater 方法根據作為參數傳入的值對象所掌握的信息來定位并更新一個Entity bean 或一個Entity bean 集。方法名稱常常以“update或“set開頭。updater 方法的實現可以像 [Brown 2000] 所說的那樣放在 factory 中,或者在一個單獨的類中。 Action 方法(例如 transfer(String fromAcctNum, String toAcctNum, BigDecimal amount))的實現放在 Action 對象中。 Session Facade 的創建規則 既然您看到了Session Facade 接口的樣子,在Session Facade 背后的又有哪些對象,那么下一個問題就是“我該有多少Session Facade 呢?您不應擁有太多的Session Facade,否則,就喪失了 Facade 模式帶來的好處。但是,若整個應用程序對應一個Session Facade 它可能會成為一個“巨大的對象5并導致它自身的一些問題。這里是設計Session Facade 的一些規則,使您能適當地(不過多或過少)使用它。 從您的應用程序中找出功能子系統。例如,名為定單管理、帳單管理和運輸管理的子系統就是一個應用程序中可能有的三個 Facade 對象。 回到您的用例(Use-case)和相關的用例組。一組相關的用例 (例如購買股票、出售股票和獲取報價)可以形成一個內聚子系統,例如“股票交易。這個內聚子系統就可能要共享很多內層對象,并且是使用Session Facade 的最佳候選。[Sun 2001] 更深入地討論了這個問題。 千萬不要把所有的單個用例都做到Session Facade 中。這將導致系統分布截面過大。這種情況下,客戶機將不得不管理非常多的 EJB 引用和 Home。 完成初步工作后,看一下您的設計中第二層對象之間的關系。如果您看到有值對象、Factory 和 Action 的不相交組,那就根據實際分組法把 Facade 分成兩個或更多 facade。 另一種會話模式 既然您已深信應該使用無狀態的Session Facade 來包裝數據源,也應該在這些 facade 的實現中進行嚴格的分層,您可能會想知道特定于用戶的應用程序狀態(如果有的話)將被保存在什么地方。根據我所主張的把Session facade 設計成能處理多用例請求,您可能還會想知道用例在哪里實際實現。 為了理解如何應用它,我們采用出自 [Jacobson 1999] 的 Control 對象的如下定義:“Control 類代表協調、順序事務以及對其它對象的控制,常用于封裝與特定用例相關的控制。 這個解決方案的目標是實現專門的、與一個單一的用例一一對應的“用例控制器對象。每個用例控制器都將維護一些特定于用戶的狀態,這些狀態與判斷一個用戶在此用例中位于哪里所必需的信息(例如,它們已經執行了多少)相對應,也與用戶輸入的、對執行用例的下一步來說必需的信息相對應。這樣,我們就找到了一個能夠用真正不依賴于 GUI 的方式來實現和編寫用例的方案。 那么,實現這些用例控制器對象,您有哪些選擇呢?因為它們天生就必須是有狀態的,我們有兩個 J2EE 體系結構中自己提供的選擇: 一個選擇是把用例控制器變為可序列化對象(JavaBeans),然后在 HttpSession 中存儲和檢索它們。當然,這只能用在使用 Servlet API 的應用程序中。但它可以應用于很多應用程序,甚至包括那些使用 Applet 和 Application 的客戶機 GUI 的應用程序,因為即使在這些情況下,通過 HTTP(也可能使用 SOAP)來和服務器端對象進行通信也是一個常用的設計策略。用 HttpSession 作為存儲機制會使程序員更輕松,因為在多數應用服務器(例如 WebSphere)中會話的持久和故障轉移細節都是自動處理的。然而,在 WebSphere 中,一個 HttpSession 要得到合理的持久性,則其大小將受到一定的限制(請參閱 Gunther ),所以這個選擇只適合用例控制器對象相對較小的情況。 另一個選擇是把有狀態的Session bean 當作用例控制器用。有狀態的Session bean 是個很好的解決方案,它使程序員不必擔心如何維護會話信息。在有狀態的Session bean 被自動存儲在共享持久存儲器的應用服務器中,這個解決方案甚至能處理故障轉移。但是,在像 WebSphere 這樣的應用服務器中的Session bean 并不存儲在共享持久存儲器中,如果碰上服務器崩潰,這個解決方案將導致用戶會話失敗。而且,以這種方式使用有狀態的Session bean 會使我們回到增大總的分布截面的老問題上。盡管如此,由于有狀態的Session bean 自己充當一個 facade,每個客戶機只需知道少數的用例控制器,這樣就減輕了這個問題。 繞了個圈,這種模式又把我們帶回到我們最初討論的 Facade 模式。這種模式相繼分層的方式使我們可以集中精力處理手邊的工作,同時還允許我們重用一些東西來構成我們的解決方案。我們不必一次性設計出整個系統,但可以反復使用這些模式,然后看著一套可重用的對象作為結果出現。 總結 我在本文中簡要分析了構建Session Facade 的一些規則。您已經看到了該如何組織Session Facade 所調用的對象,如何著手設計Session Facade。您還看到了設計能與Session facade 配合得很好的用例控制器的一些方法。我希望,這些規則的應用能提高您的 EJB 設計的適應性和性能。 致謝 感謝 Martin Fowler 審讀了本文的草稿并提出了深刻的意見。同時感謝 Craig Larman 的深刻見解,他使我明白事實上Session facade 有兩種互補模式。 參考書目 Erich Gamma、Richard Helms、Ralph Johnson 與 John Vlissides 合著的 Design Patterns: Elements of Reusable Object-Oriented Design,Addison-Wesley,1995。 Gamma Martin Fowler 的 Analysis Patterns: Reusable Object Oriented Model,Addison-Wesley,1997。 Fowler Martin Fowler 的 Information Systems Architectur。[Fowler 2001] Sherman Alpert、Kyle Brown 與 Bobby Woolf 合著的 The Design Patterns Smalltalk Companio,Addison-Wesley,1996。 Alpert William Brown、Ralph Malveau、Hays McCormick 與 Thomas Mobray 合著的 AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis,John Wiley and Sons,1998。[Brown 1998] Kyle Brown、Philip Eskelin 與 Nat Pryce 合著的 “A small pattern language for Distributed Component Design,是提交給 1999 年在 Illinois 的 Monticello 召開的程序模式語言(the Pattern Language of Programs,PloP)大會的論文,在 Ratio Group Web site 有它的完整鏡像發布。[Brown 1999] Kyle Brown 的 “Layered Architectures for EJB System,VisualAge Developer Domain。[Brown 2000] Kyle Brown 的 “Choosing the right EJB type:Some Design Criteria,VisualAge Developer Domain。[Brown 2000a] Kyle Brown 與 et. al. 合著的 Enterprise Java Programming for IBM WebSphere,Addison-Wesley Longman,Boston,2001 年 5 月。[Brown 2001] “Session Facade, Sun Java 核心 J2EE 模式,Java 開發者連接。[Sun 2001] Harvey Gunther 的 “WebSphere Application Server Development Best Practices for Performance and Scalability。 Gunther “Session Enity Facade,Sun J2EE 規劃藍圖。[Sun 2000] Sun Microsystems,“EJB 2.0 規范,發布草案 2。[EJB 2.0] Richard Monson-Haefel,Enterprise JavaBeans,第二版,O&acute;Reilly,2000。[Monson-Haefel] Ivar Jacobson 與 et.al 合著的 “The Unified SoftWare Development Process,Addison-Wesley,1999。[Jacobson 1999] 腳注 1 Erich Gamma、Richard Helms、Ralph Johnson 與 John Vlissides 合著的 Design Patterns: Elements of Reusable Object-Oriented Design,Addison-Wesley,1995,第 185 頁。 2 Erich Gamma、Richard Helms、Ralph Johnson 與 John Vlissides 合著的 Design Patterns: Elements of Reusable Object-Oriented Design,Addison-Wesley,1995,第 186 頁。 3Erich Gamma、Richard Helms、Ralph Johnson 與 John Vlissides 合著的 Design Patterns: Elements of Reusable Object-Oriented Design,Addison-Wesley,1995,第 187 頁。 4Erich Gamma、Richard Helms、Ralph Johnson 與 John Vlissides 合著的 Design Patterns: Elements of Reusable Object-Oriented Design,Addison-Wesley,1995,第 193 頁。 5William Brown、Ralph Malveau、Hays McCormick 與 Thomas Mobray 合著的 AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis,John Wiley and Sons,1998,第 73 頁。 關于作者 Kyle Brown 是 IBM WebSphere Service 的高級 Java 顧問。Kyle 在 WebSphere Service 中的職責是就關于面向對象的主題和Java 2 企業版(J2EE)技術,向“財富 500 強客戶提供咨詢服務、教育以及指導 。他是 The Design Patterns Smalltalk Companion(設計模式 Smalltalk 伴侶)的合著者,也是一位著名的撰稿人,還是關于 Enterprise Java,OO 設計和設計模式主題的討論會的發言人。可通過 [email protected] 與 Kyle 聯系。 Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd
相關文章:
主站蜘蛛池模板: 欧美理论大片清免费观看 | 欧美男人操女人 | 97国产影院| 色偷偷亚洲男人天堂 | 高清欧美性xxxx成熟 | 午夜三级毛片 | 京东一热本色道久久爱 | 日韩欧美在线综合网高清 | 中文字幕在线网址 | 老司机亚洲精品影院在线 | 久久er热这里只有精品23 | 国产a级高清版毛片 | 理论片免费午夜 | 午夜欧美成人 | 久国产精品视频 | 在线观看黄网视频免费播放 | 免费视频亚洲 | 99久久免费国产精精品 | 亚洲一区毛片 | 国产精品国产 | 爽爽在线| 久久黄色影院 | 美女视频免费黄色 | 免费一级做a爰片久久毛片 免费一级做a爰片性色毛片 | 91成人爽a毛片一区二区 | 成年男女免费视频网站 | 男女男精品视频在线播放 | 直接看的毛片 | 99精品免费在线观看 | gay毛片| 看中国毛片 | 波多野结衣一区在线观看 | 美女张开腿让男人桶下面 | 欧美成人精品高清在线播放 | 鲁大师成人精品视频 | 色播基地 | 美女视频黄的免费视频网页 | 丝袜美腿精品一区二区三 | 久久久久亚洲日日精品 | 成人精品第一区二区三区 | 免费看一级做a爰片久久 |