In most J2EE systems such factories/managers are stateless session beans. EJB containers handle the demand for stateless session beans by creating as many instances of them as required or by reusing existing ones. The problem is that each new bean instance must be initialized with exactly the same set of listeners as exists for all other instances. A logical solution occurs when a stateless session bean instance is created, and the bean goes to some repository where it somehow retrieves relevant listeners and attaches them to itself. In this tip, I will show you how to implement this solution.
Consider this typical design scenario. An online auctioning system has a stateless session bean called AuctionFactory, which creates auction objects. For each newly created auction, the business logic requires the system to do some extra work,
like sending email, updating user profiles, and so on. In many systems, the code for creating an auction and performing the
aforementioned tasks looks like this:
public Auction createAuction(int numOfContainers) throws RemoteException{
SomeAuctionClass auction = new SomeAuctionClass (numOfContainers);
//and after creation there is notification code like this(instead of
//firing an "auction created" event):
sendEmailsAboutNewAuction(auction);
updateUserProfiles(auction);
doOtherNotificationStuffAboutNewAuction(auction);
//etc..
return auction;
}
The reason for such poorly written code lies in the difficulties of initializing each bean instance with some set of required listeners. If this bean were a publisher of events and each bean instance were initialized with a set of required listeners, the code would be much cleaner and robust, like this:
public Auction createAuction(int numOfContainers) throws RemoteException{
SomeAuctionClass auction = new SomeAuctionClass (numOfContainers);
fireAuctionCreated(auction);
return auction;
}
The framework principle I will describe is very simple. A ListenerRegistry class maps a publisher class and the listeners that need to be assigned to it. The system's startup module initializes the
ListenerRegistry with a required set of listeners for each publisher type. When each publisher is constructed or activated, it goes to the
ListenerRegistry, passes its class to the ListenerRegistry, and in return gets a set of listeners. Then the publisher assigns all these listeners to itself. It's that simple.
The following UML diagram depicts the ListenerRegistry interface and the relationship between participants in the framework: