国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

在EJB環(huán)境中實現(xiàn)“觀察者”模式

2019-11-18 13:36:35
字體:
來源:轉載
供稿:網(wǎng)友

  在EJB環(huán)境中實現(xiàn)“觀察者”模式

Observer模式(“觀察者”模式)或許是降低對象結合程度的最佳方法之一。例如,在編寫一個典型的應用程序時,你可能決定提供一個工廠或治理器觸發(fā)適當?shù)氖录?,以這些事件的一組監(jiān)聽器的形式提供分離的業(yè)務邏輯;此后,系統(tǒng)的啟動類就在工廠或者治理器創(chuàng)建完畢之后,把這些監(jiān)聽器關聯(lián)到工廠或者治理器。

在大多數(shù)J2EE系統(tǒng)中,這種工廠/治理器都是無狀態(tài)的會話Bean。EJB容器處理對無狀態(tài)會話Bean的請求,根據(jù)請求創(chuàng)建無狀態(tài)會話Bean的實例,或重用現(xiàn)有的實例。問題在于,每次初始化一個新的Bean實例時都必須伴有一組監(jiān)聽器,這組監(jiān)聽器和為其他實例而運行的監(jiān)聽器完全相同。合理的方案應該是,當一個無狀態(tài)會話Bean實例被創(chuàng)建的時候,它訪問某個知識庫,通過一定的方法獲知相關的監(jiān)聽器,然后建立和這些監(jiān)聽器的關系。在這篇文章中,我要介紹的就是如何實現(xiàn)這一方案。

一種典型的情形
請考慮下面這種典型的情形。一個在線拍賣系統(tǒng)有一個無狀態(tài)會話Bean,名為AUCtionFactory,這個Bean創(chuàng)建拍賣(auction)對象。對于每一個新創(chuàng)建的拍賣對象,業(yè)務邏輯要求系統(tǒng)執(zhí)行一些附加的操作,比如發(fā)送email、更新用戶摘要文件,等等。在許多系統(tǒng)上,創(chuàng)建拍賣對象和執(zhí)行這些附加操作的代碼如下所示:

public Auction createAuction(int numOfContainers) throws RemoteException{ SomeAuctionClass auction = new SomeAuctionClass (numOfContainers); // 創(chuàng)建拍賣對象之后,接下來要編寫下面這種執(zhí)行附加操作的代碼 //(而不是簡單地發(fā)送一個“拍賣對象已經(jīng)創(chuàng)建”的事件) sendEmailsAboutNewAuction(auction); updateUserPRofiles(auction); doOtherNotificationStuffAboutNewAuction(auction); //等等.... return auction;}


之所以要編寫這種質量很差的代碼,原因就在于初始化各個Bean實例時附帶一組必需的監(jiān)聽器很困難。假如這個Bean是一個事件發(fā)布者,而且每一個Bean實例初始化的時候都帶有一組它需要的監(jiān)聽器,上述代碼可以變得更簡潔、更強壯,例如:

public Auction createAuction(int numOfContainers) throws RemoteException{ SomeAuctionClass auction = new SomeAuctionClass (numOfContainers); fireAuctionCreated(auction); return auction;}


基本原理說明
實現(xiàn)本文技巧的基本原理其實很簡單。一個ListenerRegistry類實現(xiàn)事件發(fā)布者類和必須關聯(lián)到該類的監(jiān)聽器之間的映射。系統(tǒng)的啟動模塊初始化ListenerRegistry,為每一種發(fā)布者類型初始化一組必需的監(jiān)聽器。當發(fā)布者被創(chuàng)建或激活,它就訪問ListenerRegistry,把它的類傳遞給ListenerRegistry,獲得一組監(jiān)聽器。然后,發(fā)布者把所有這些監(jiān)聽器關聯(lián)到自身。就這么簡單。


你也許會很自然地問,“什么是ListenerSupplier?”和“為什么不直接注冊和使用EventListener?”確實可以;事實上,該框架的第一個版本就是直接使用事件監(jiān)聽器。但是,假如在ListenerRegistry中使用監(jiān)聽器,這些監(jiān)聽器必須在注冊的時候就存在。另一方面,假如注冊的是一個“中介者”ListenerSupplier(監(jiān)聽器提供者),你就可以自由地把創(chuàng)建/提取監(jiān)聽器延遲到它絕對必需的時候。ListenerSupplier類似于工廠,但兩者的不同之處在于,ListenerSupplier并非必定要創(chuàng)建新的監(jiān)聽器,它的目標是返回監(jiān)聽器。每次getListener()方法被調用時,ListenerSupplier是創(chuàng)建一個新的監(jiān)聽器,還是每次都返回同一實例,這一切由開發(fā)者自己決定。

因此,結合運用ListenerRegistry和監(jiān)聽器提供者,我們可以在事件發(fā)布者和觀察者(或監(jiān)聽器)不存在的情況下,建立兩者之間的關系。可以認為,這個優(yōu)點很重要,它延遲了發(fā)布者和觀察者的實例化。

具體實現(xiàn)
在這一部分,你將看到整個框架中所有組成部分的實現(xiàn)代碼。我假定你已經(jīng)了解必要的基礎知識,比如EJB、同步,當然還有java核心庫。完整的源代碼可以從本文最后下載。

下面是ListenerRegistry接口的代碼:

//ListenerRegistry.javapackage com.jwasp.listener;import java.util.EventListener;import java.rmi.RemoteException;import com.jwasp.listener.ListenerSupplier;/*** 框架的核心。實現(xiàn)事件發(fā)布者類和監(jiān)聽器提供者之間的映射*/public interface ListenerRegistry {void addListenerSupplier(ListenerSupplier listenerSupplier, Class publisherClass);void removeListenerSupplier(ListenerSupplier listenerSupplier, Class publisherClass);EventListener[] getListeners(Class publisherClass) throws RemoteException, ListenerActivationException;}


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 剑河县| 象州县| 惠安县| 江安县| 西丰县| 盘山县| 莎车县| 应城市| 吉水县| 阜城县| 克东县| 长宁区| 焉耆| 正定县| 余干县| 托里县| 荥阳市| 睢宁县| 郴州市| 晋中市| 天门市| 老河口市| 大石桥市| 日照市| 辛集市| 四会市| 普安县| 新源县| 腾冲县| 丁青县| 通城县| 锦州市| 通海县| 长沙县| 阜平县| 习水县| 阿坝县| 枣强县| 岢岚县| 洛川县| 清水县|