When using an object-oriented analysis and design approach to a project, the design phase is the most complex and time-consuming step. You have to figure out what objects you need and how they should interact to meet the requirements. However, you can speed up the design and development phases by reusing parts of previous applications and adapting them as necessary.
Code reuse is by no means a new idea, and was practiced before object-oriented languages appeared on the scene. In its most primitive form, code reuse takes the form of copying code from an original application and pasting it into a new application. Eventually, we started putting code into libraries to form software components. Code reuse on this level works for individual developers, and possibly across teams of developers. However, reusability across an enterprise, or by the general public, faces some challenges.
The lack of widely accepted best practices leads many developers to build their own, reinventing the wheel. Another issue is the "not invented here" syndrome. There are many reusable components out there, but developers are wary of using components they didn't develop because they can't see the code.
To be truly reusable, software components must be easily understood and extensible. This is where design patterns come in. Design patterns are the result of building architecture research done by Christopher Alexander in the 1970s. After studying many buildings, Alexander determined that certain patterns of design were common to buildings that survived the ages. His research concluded that you could design better buildings by applying generic solutions to common problems. These patterns weren't meant to be the perfect solution to the common problems, but a best practices approach that could be adapted to fit any given situation.
In 1995, four software developers (Gamma, Helm, Johnson, and Vlissides) started thinking about Alexander's research in terms of software design. The Gang of Four (GoF), as they're known, defined 23 patterns to solve common problems developers face in software design.
Making designs understandable
Because the design patterns are well documented and accepted best practices, using them in the design of your application makes the application easier to understand, and stimulates development of software components. Design patterns are expressed in words and diagrams, not code. Applying a familiar standards-based diagramming approach such as the Unified Modeling Language (UML) lets you easily understand and accept the design and underlying code.
Software components based on patterns are understandable, and therefore much more acceptable to a developer for potential reuse. In addition, components aren't tightly coupled with the applications they compose, and are extensible, improving the likelihood of code reuse.
Adapting and combining patterns
It's important not to take a purist approach to the use of patterns. Although completely changing a pattern lessens its understandability, modifying a pattern slightly to fit the environment in which it is being used makes sense. The concept of adapting and combining patterns as you see fit is important in the successful use of patterns.
You can also combine patterns to solve multiple issues simultaneously. For example, in my Web applications I use the State pattern inside the Command pattern to verify that a given command is valid for the present application state. So, if the user is on the checkout page (in the Checkout state), presses the Back button a couple of times and tries to add something to the shopping cart, it's an illegal command for that state and I can deal with it gracefully.
Where's the catch?
Design patterns are simply narrative and diagrammatic concepts that are programming language agnostic. The biggest challenge when using design patterns is finding a description pertinent to the type of problem you're trying to solve that has examples in the programming language you're using. Design Patterns by Erich Gamma et al, was written during the client-server era, and therefore describes pattern use in client-server concepts for applications with a GUI front-end written in C++. However, for folks working with the WebSphere platform the challenge is to understand how patterns apply to Web applications and how to implement patterns in Java.
Over the last year, I've done considerable research into this and have built frameworks around pattern implementations that I've found tremendously valuable. Some of the patterns I've used are Factory Method, Singleton, Command, State, and Façade. Look for articles on how to implement these patterns in upcoming issues of WebSphere Advisor, but also vow to become a student of patterns.
In the spirit of discovering and sharing best practices, the August 2001 issue of WebSphere Advisor offers articles to help you develop and deploy more efficient and secure EJB-based applications. Dennis Pagano's article on page 22 covers the design and development phases, and Bob Balaban's article on page 30 shows how to make sure EJBs are secure before you deploy them.