In spring 1996, a well-known music and television company sought to create a Java version of its Web site. The company's managers knew how they wanted the site to look and behave but lacked the Java expertise to build the site. So they began looking for a development partner.
Industrial Logic, my company, was contacted by this organization. At our first meeting, I was led through the user interface design. I also learned that the company would want to modify the behavior of the future site without having to call programmers to make every little change. The managers had one question for me: How would I program the site to meet their needs?
Over the next few weeks, I worked with my colleagues to consider designs for the site. All of us were members of the Design Patterns Study Group I had started six months earlier. Our newfound knowledge of patterns was most helpful in our design work. For each of the requirements of the site, we considered what patterns could help us.
It soon became apparent that the Command [DP] pattern would play an essential role in our design. We would program the site in such a way that Command objects would control all behavior. If you clicked somewhere on the screen, a Command object (or many Command objects) would execute. We'd also invent a simple Interpreter [DP] to allow our clients to configure their site to run whatever Command objects they wanted, thereby allowing them to modify their site's behavior without having to call us.
We spent several days documenting our design. Then we had a second big meeting with the music and television folks. The meeting went well and we were asked to return for a third meeting to get into more technical details about our design.
As the weeks ticked by, we had our next meeting and then our next one. By mid-summer, we had not programmed any code for the site; we simply had a growing body of design documents. Finally, sometime in mid-August, we learned that we had won the bid to develop the site.
Over the coming months, we programmed the site, following our design very closely. As we programmed, we found places where we could improve the design by refactoring to the Composite [DP], Iterator [DP], and Null Object [Woolf] patterns. For an example of how and why we refactored to Null Object, see the discussion in Introduce Null Object (301).
By mid-December, about one month beyond the scheduled delivery date, we were done. The site went live. We all celebrated.
I often think of this experience when I consider refactoring and the role of patterns. If we had to do it all over again, would it have been better to evolve our design, instead of doing big design up-front (BDUF)? Would we have been more successful had we exclusively refactored to or towards patterns rather than using a few patterns early in our design?
No. We would not have won the bid for this project had we not thought of a design and presented it, in detail, to the client. BDUF was essential in this context, and our up-front design with the Command and Interpreter patterns was a critical part of our success.
The typical problem with BDUF is that it often wastes time. You come up with a design for requirements and then those requirements change, get dropped, or are deferred to some later date. Or your requirements don't change, but you spend lots of time coming up with a design that's more elegant or sophisticated than it needs to be.
In this case, we didn't encounter such BDUF problems. Our project was small with very fixed requirements. We used every aspect of our up-front design in our programming work. Our code did just what our clients needed and wasn't overly complicated or sophisticated.
However, we were late to deliver the site by one month because of numerous defects we encountered in the Internet browsers. We began testing the Mac version of the site midway through the project and soon found that Netscape on the Mac had serious defects that we needed to program around. In addition, we encountered numerous differences between Internet Explorer and Netscape, which caused us to make many time-consuming modifications to our code.
Being one month late to deliver wasn't a serious problem, though it did cause us some stress. If we had begun programming sooner, before we won the bid, we may have encountered the browser defects earlier. Yet at the time we were reluctant to code anything until we had a client who would pay us for our work.
Since 1996, I've done very little up-front design with patterns. The approach I've taken on project after project has been to evolve a system, refactoring to, towards, or away from patterns as necessary. The Command pattern remains the major exception. Since 1996, I've used it on two or three systems very early in a design because it was easy to implement and the systems clearly required the behavior supplied by the Command pattern.
I included this story in this chapter because I believe it helps illustrate when it makes sense to ignore the ideas in this book. While I don't generally favor up-front design with patterns, I know that it has some place in a designer's toolkit. I use up-front design with patterns rarely and most judiciously, and I recommend you do so as well.