Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Java Tip 110: Implement the Observer pattern with EJBs

Use this convenient framework to assign event listeners to EJBs

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
The Observer pattern is probably one of the best ways to reduce coupling between objects. For example, if you are writing a typical application, you may decide to provide a factory or manager that fires appropriate events, and provide separate business logic functionality as a set of listeners of those events. The system's startup class would then assign such listeners to the factory or manager right after it was internally created.

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.

An example scenario

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;
}


Framework description

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:

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources