J2EE design patterns
Improve performance and manage complexity with enterprise design patterns from Sun
June 7, 2001— Experienced Java developers are expected to have a collection of design patterns in their toolbox. Sun’s certification exam for Java architects already explicitly tests for knowledge of the Gang of Four’s patterns. When the exam is rewritten for release next year, other enterprise patterns will be added. Mark Johnson and Inderjeet Singh copresented a session on J2EE design patterns for enterprise applications. Their presentation concentrated on the patterns used to construct the Java Pet Store application available on Sun’s site.
Design patterns for managing complexity
Johnson began by characterizing patterns as allowing “you to learn from other’s successes instead of from your own failures.” With patterns, software developers can talk about facades the same way architects might talk about courtyards. Sun has been careful to use names that are consistent with the Gang of Four patterns (i.e., the collection of patterns published in the book Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma et al). In addition to having a Gang of Four-style name, each J2EE pattern addresses an enterprise problem and provides a solution that specifies the elements, responsibilities, and collaborations. The pros and cons of applying each pattern were also presented.
A J2EE pattern is based on experiences of the J2EE community and uses J2EE technology to solve problems. Let’s take the well-known Model-View-Controller (MVC) pattern as an example. In the context of an enterprise application, this can be used naturally to separate the business logic into the model; the presentation logic into the view; and user input into the controller, which turns user gestures into actions on the model. This way the logic is centralized in one place — the model — and that logic is then accessible to multiple views and/or client types. The controller will tend to be tied tightly to the model.
Singh and Johnson recommended using the Front Controller pattern when the controller and the view are linked with complex interactions. The Front Controller gets all requests and acts as a single point of entry to the backend. It allows you to separate your request-processing logic from the response generation. For small applications, the Front Controller is overkill. This pattern also isn’t very beneficial when most content is static.
The Session Facade pattern simplifies access to a complex model. As a metaphor, the speakers offered up the example of a tax accountant who serves as a session facade for the IRS tax code. The facade presents a simpler API and hides the details of what’s going on in the backend. Later in the discussion, it was pointed out that these two patterns work well together. The Front Controller takes all user requests, processes them, and then communicates with a Session Facade that serves as an adapter to the backend processing.
Design pattern for managing vendor independence
When there are vendor-specific requirements in communicating with a data source, you can use the Data Access Object pattern. Here, data access logic is encapsulated with a bridge between a business object and an abstract data access object. You then just write the vendor-specific information and place it in a concrete subclass. This pattern works nicely with the Gang of Four Factory pattern. You can use Factory patterns to create Data Access Object instances. Johnson and Singh suggested that you go further and make them pluggable by using entries in your deployment descriptor or using JNDI. You should also recognize that the implementation of a vendor-specific subclass of an abstract Data Access Object interface is an application of the Gang of Four Adapter pattern.
Design patterns for higher performance
If you make a lot of remote calls for small pieces of information, you should consider using the Value Object pattern. The idea here is that if you request someone’s house number, street name, city name, state name, and zip code in separate calls, there is high latency and unnecessary network overhead.
Instead, you should group this information into a single value object. You can send this object over the wire and then make local calls to get the fine-grained information. There is a downside to this technique: because the object lives on your local machine, you need to handle issues of stale data, just as you would with any other cached information. This pattern becomes unnecessary with the introduction of local interfaces in EJB 2.0.
If you have a site where customers spend more time browsing than making purchases, you don’t want unnecessary transactional overhead when data is accessed by nontransactional means. As an example, think about browsing a catalog. In this pattern, the same data is modeled as an EJB object for remote transactional data and as a read-only database for browsing. The downside is that you have now duplicated some of your functionality and increased your complexity.
When you perform searches, how do you efficiently navigate the long lists that are returned? You can’t use the Value Object pattern for large files, so you instead employ the Page-by-Page Iterator. The Page-by-Page Iterator pattern creates a server-side interface that returns a specified sublist of the returned list. For example, in a query, you don’t want the query executed every time you go to the next page of the returned results. The iterator sits between the EntityList returned by the query and the ClientObject wanting to see the results.