Welcome to the first installment of the "Core J2EE Patterns" column by the Sun Java Center (www.sun.com/service/sunps/jdc). Every other month, we (Deepak Alur, Danny Malks, myself, and other architects from the Sun Java Center) will discuss various topics from our book, Core J2EE Patterns, Best Practices and Strategies (Alur, Crupi, Malks, Prentice Hall/Sun Press, 2001). These topics include each of the 15 J2EE patterns in our catalog, design strategies, bad practices, refactorings and pattern-driven design in the Java 2 Platform, Enterprise Edition (J2EE).
Applying the Technology
Today, as in the past, many of us naively assume that learning a technology is synonymous with learning to design with the technology. Certainly, learning the technology is important for success in designing with the technology. Many existing Java books are excellent at explaining technology details, such as API specifics and so forth, but at the same time they give no insight on applying the technology.
Learning to design comes from experience and from sharing knowledge on best practices and bad practices. The experiences we'll convey in this column are derived from the work we have done in the field. We are part of Sun Microsystems, Inc.'s, Sun Java Center (SJC) consulting organization and have been designing mission-critical J2EE solutions since J2EE technology was introduced.
In our work, we often encounter situations where, because technology is moving so quickly, designers and developers are still struggling to understand the technology, let alone how to design with the technology. It's not good enough to tell designers and developers to write good code, nor is it sufficient to suggest using servlets and JavaServer Pages (JSP) technology for developing the presentation tier and EJB components for developing the business tier.
Since its inception, SJC architects have been working with clients all over the world to successfully design, architect, build, and deploy various types of systems based on Java and J2EE technology and platforms.
Recognizing the need to capture and share proven designs and architectures, we started to document our work on the J2EE platform in the form of patterns in 1999. Although we looked in the existing literature, we couldn't find a complete catalog of patterns that dealt specifically with the J2EE platform. We found many books dealing with one or more of the J2EE technologies, which do an excellent job of explaining the technology and unraveling the nuances of the specifications, but many of these books fall short on design.
After two years of work on capturing J2EE patterns and documenting them in the proper pattern form, at the JavaOne 2001 Conference we launched our book, which includes the SJC J2EE Pattern Catalog. We also announced that four companies and allies, Rational, TogetherSoft, Forte, and iPlanet, have all agreed to bundle the SJC J2EE Pattern Catalog in their respective tools (http://java.sun.com/pr/2001/06/pr010604-25.html).
This is important in our eyes because patterns lend themselves to tools so nicely. As a matter of fact, the pattern-driven design concept in J2EE technology is difficult without tool support. More about this later.
The Essence of Patterns
First, let's start with a brief overview of patterns - starting with some expert definitions.
In A Pattern Language, Christopher Alexander says each pattern is a three-part rule which expresses a relation between a certain context, a problem, and a solution.
Richard Gabriel discusses this definition in more detail in A Timeless Way of Hacking. Gabriel offers his own version of Alexander's definition as applied to software: each pattern is a three-part rule that expresses a relation between a certain context, a certain system of forces that occurs repeatedly in that context, and a certain software configuration that allows these forces to resolve themselves.
This is a fairly rigorous definition, but there are also much looser ones. For example, Martin Fowler, in Analysis Patterns, offers the following definition: a pattern is an idea that has been useful in one practical context and will probably be useful in others.
As you can see, there are many definitions for a pattern, but they all have a common theme relating to the recurrence of a problem/solution pair in a particular context. Some of the common characteristics of patterns:
They're observed through experience
Are typically written in a structure
Prevent reinventing the wheel
Exist at different levels of abstraction
Undergo continuous improvement
Are reusable artifacts
Communicate designs and best practices
Can be used together to solve a larger problem
Patterns, then, represent expert solutions to recurring problems in a context and thus have been captured at many levels of abstraction and in numerous domains. Numerous categories have been suggested for classifying software patterns, with some of the most common patterns being:
Even within this brief list of categories, we see numerous levels of abstraction and orthogonal classification schemes. Thus, while many taxonomies have been suggested, there is no one right way to document these ideas.
In our J2EE pattern catalog, each pattern hovers somewhere between a design pattern and an architectural pattern while the strategies document portions of each pattern are at a lower level of abstraction. The scheme we have introduced is to classify each pattern within one of the following three logical architectural tiers:
Identifying a Pattern
We have successfully completed and deployed many J2EE technology projects at the Sun Java Center, and over time have noticed that similar problems recur across these projects. We have also seen similar solutions emerge for these problems. While the implementation strategies varied, the overall solutions were quite similar. Let's discuss, in brief, our pattern identification process.
When we see a problem and solution recur, we try to identify and document its characteristics using the pattern template. At first, we consider these initial documents to be candidate patterns. However, we don't add candidate patterns to the pattern catalog until we are able to observe and document their usage multiple times on different projects. We also undertake the process of pattern mining by looking for patterns in implemented solutions.
As part of the pattern validation process, we use the Rule of Three, as it is known in the pattern community. This rule is a guide for transitioning a candidate pattern into the pattern catalog.
According to this rule, a solution remains a candidate pattern until it has been verified in at least three different systems. Certainly, there is much room for interpretation with rules such as this, but they help provide a context for pattern identification. Often, similar solutions may represent a single pattern. When deciding how to form the pattern, it's important to consider how to best communicate the solution. Sometimes, a separate name improves communication among developers. If so, then consider documenting two similar solutions as two different patterns. On the other hand, it might be better to communicate the solution by distilling the similar ideas into a pattern/strategy combination.
Patterns vs Strategies
When we started documenting the J2EE patterns, we made the decision to document them at a relatively high level of abstraction. At the same time, each pattern includes various strategies that provide lower-level implementation details. Through the strategies, each pattern documents a solution at multiple levels of abstraction. We could have documented some of these strategies as patterns in their own right; however, we feel that our current template structure most clearly communicates the relationship of the strategies to the higher-level pattern structure in which they are included.
While we continue to have lively debates about converting these strategies to patterns, we have deferred these decisions for now, believing the current documentation to be clear. We have noted some of the issues with respect to the relationship of the strategies to the patterns:
The patterns exist at a higher level of abstraction than the strategies.
The patterns include the most recommended or most common implementations as strategies.
Strategies provide an extensibility point for each pattern.
Developers discover and invent new ways to implement the patterns, producing new strategies for well-known patterns.
Strategies promote better communication by providing names for lower-level aspects of a particular solution.
The Tiered Approach
Since this article describes patterns that help you build applications that run on the J2EE platform, and since a J2EE platform (and application) is a multitiered system, we view the system in terms of tiers. A tier is a logical partition of the separation of concerns in the system. Each tier is assigned its unique responsibility in the system. We view each tier as logically separated from one another. Each tier is loosely coupled with the adjacent tier. We represent the whole system as a stack of tiers.
We used the tiered approach to divide the J2EE patterns according to functionality, and our pattern catalog follows this approach. The presentation-tier patterns are related to servlets and JSP technology. The business-tier patterns are related to the EJB technology. The integration-tier patterns are related to the Java Message Service (JMS) and Java Database Connectivity (JDBC) technology.
Table 1, 2, and 3 each list the patterns and a brief description for each tier.
We use UML extensively in the pattern catalog, particularly as follows:
Class diagrams: We use the class diagrams to show the structure of the pattern solution and the structure of the implementation strategies. This provides the static view of the solution.
Sequence (or interaction) diagrams: We use these diagrams to show the interactions between different participants in a solution or a strategy. This provides the dynamic view of the solution.
Stereotypes: We use stereotypes to indicate different types of objects and roles in the class and interaction diagrams.
Each pattern in the pattern catalog includes a class diagram that shows the structure of the solution and a sequence diagram that shows the interactions for the pattern. In addition, patterns with multiple strategies use class and sequence diagrams to explain each strategy.
Patterns Need Patterns
About a year ago, Sun ran a Java technology developer focus group to gather data about tools and patterns. During the pattern section, the question, "Do you think patterns are useful?" was posed to the group. Almost unanimously, the answer was yes. Next, they were asked, "Do you have any problems with using patterns in development?"
The number one problem identified by the developers was that they did not have a good handle on how and when to use patterns together to solve a business problem. I agree. The value in creating a pattern catalog is not just understanding the isolated patterns, but in how the patterns work together. Even more so, what are the patterns that are commonly used together to solve a common business problem?
We created a pattern relationship guide (also known as a pattern language) to visually see how the patterns relate to each other as shown in Figure 1.
In each column we will attept to put each pattern in the context of a business problem and also discuss the patterns that are commonly used together. We call these pattern frameworks.
In Figure 2, we show an example of a pattern framework. Each pattern is represented by a UML package that contains the participants of each pattern. The diagram identifies the end-to-end (across each tier) patterns as can be applied to a business problem.
In Upcoming Issues
I wanted to give you a flavor of what's to come in future columns. We think this will be a great opportunity and forum to exchange and share with you our ideas, vision, and experiences with applying J2EE patterns in the real world. If there are any J2EE pattern topics you want us to address in future columns, please e-mail us at [email protected].
John Crupi is the chief Java architect of the Sun Java Center. He has more than 15 years of experience in distributed object computing and remains focused on creating reusable, scalable architectures for J2EE technology. He is coauthor of Core J2EE Patterns (Prentice Hall/Sun Press, 2001) and is currently concentrating on pattern-driven design in J2EE.
Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.