J2EE Design Patterns
Pages: 1, 2
And the Winner is…
In this section, we will briefly describe the presentation patterns mentioned so far. Most of these descriptions should invoke an "oh, yeah" response, as you identify situations you have faced during development. For a full pattern description, I highly recommend taking a look at Core J2EE Patterns (Alur, et al, Sun Microsystems Press, ISBN 0-13-064884-1) or "J2EE Blueprints."
The Intercepting Filter intercepts incoming requests and outgoing responses, and applies a filter. Filters may be added and removed in a declarative manner, allowing them to be applied in a variety of combinations. After pre- or post-processing is finished, the final filter in the group passes control to the original target object, typically a Front Controller.
A Front Controller is a container that holds common processing logic that occurs within the presentation tier and that may otherwise be misplaced in a View. A controller handles requests and manages content retrieval, security, view management, navigation, and delegation to a Dispatcher component, which further dispatches to a View.
View Helper encourages the separation of formatting-related code from other business logic. It suggests using Helper components to encapsulate logic relating to initiating content retrieval and validation, as well as adapting and formatting the model. The View component is then left to encapsulate the presentation formatting. Helper components typically delegate to Business Services (a business-tier pattern which we won't be discussing further).
The Composite View composes a View from numerous pieces. Multiple smaller views, which could be either static or dynamic, are pieced together to create a single template.
Service to Worker and Dispatcher View
The Service to Worker and Dispatcher View patterns are a combination of other patterns. They share a common structure with common components, consisting of a controller working with a Dispatcher, Views, and Helpers, but the division of labor is different. The Dispatcher View defers content retrieval and error handling to the time of View processing. This pattern also suggests that the Dispatcher plays a more limited role in the View management, as the choice of the View is typically already included in the request.
You may already be using pattern-like strategies in your development process without even being aware of it. By identifying and becoming familiar with particular patterns, you will see that what might first appear as a problem that requires a roll-your-own solution might be better served by using a defined pattern. Let's explore a sample development scenario using the View Helper pattern and see how this might work.
Our scenario is a system that creates presentation content that requires processing of dynamic business data. This is a fairly common scenario to anyone doing J2EE development. The problem is that it is not uncommon for changes to occur in the presentation tier during the course of development. When business data logic and presentation-formatting logic are mingled together, the system becomes less flexible, harder to maintain, and provides a poor separation of tiers. Most of us -- even me -- are guilty at one point or another of coding Java into our JSPs. We want to avoid this situation.
Enter the View Helper pattern. The solution is to enforce this pattern so that the View contains formatting code, delegating its processing responsibilities to its helper classes. These classes might be implemented in a number of ways, including JavaBeans or custom tags. Helpers also store the View's intermediate data model and serve as business data adapters. It is important not to confuse a solution with its implementation strategy. For example, it's possible to implement this type of solution using a JSP View strategy, which uses a JSP as the View component. While this is a common strategy, it's also possible to take a Servlet View strategy, which uses a Servlet as a view instead. While we all know that a JSP actually becomes a Servlet, the strategy chosen becomes a matter of preference among the teams involved, as well as of the requirements of your project.
We have identified that we will use the View Helper pattern in our project. The class diagram for this pattern is shown in Figure 1.
The class diagram tells us what components we will need to create in order to realize this pattern. Remember the naming conventions we spoke about earlier! (As a side note, if you are working with Rational Rose, there are a number of patterns included in v2002 that allow for the actual classes that need to be realized for a pattern to be generated for you. Depending on the pattern you select, the appropriate classes are created. It's quite convenient.) By using a sequence diagram that represents the View Helper pattern, we are quickly able to see the logic flow.
The View represents and displays information to the client. Dynamic data is required, and the display is retrieved from a model. The helpers are used to support the View by encapsulating and adapting the model for displaying. A Helper is called a ValueBean if it is storing intermediate data from the model needed by the View. How the helper is implemented doesn't really matter; it could be a JavaBean or a custom tag, as we previously discussed. It could also be an XSL transformer, if XSL is being used for converting the model into the appropriate output for a specific client device. The Business Service is the service the client is trying to access -- the Business Service would typically branch off into another pattern specific to handling control and protection of the business service.
By using this pattern, we improve the tier partitioning and maintainability of our application by using helpers, as well as providing JavaBeans, custom tags, or XSL files that could very well be reused on other projects. The View Helper is also a good example of when a pattern is commonly used in conjunction with other patterns.
Take note: this is just the beginning. While this simple sequence diagram is a starting point, you will have to learn how to adapt your system modelling to your own development. Transforming patterns and strategies into an implementation is non-trivial. The more familiar you become with patterns, their strategies, and their implementation, the quicker you will be able to determine what you need for a specific project.
I hope this article has whet your appetite for using patterns in your development process. While this article only touched on presentation-tier patterns, there is a whole slew of patterns for the business and resource tiers that you should also become aware of (if you aren't already). By becoming familiar with patterns, as well as when and how to use them, you will ultimately become a better engineer. You will also find that your development process will improve, because you will more than likely be using tools that help create artifacts of your projects, including use-cases, sequence and class diagrams, and complete UML models of your systems.
Return to ONJava.com.