Department of Computer Science
University of Northern Iowa
Cedar Falls, Iowa 50614-0507
Over the last five years, a vibrant community of researchers and practitioners has grown up around the idea of patterns. Originally explored by architect Christopher Alexander, patterns and pattern languages capture common wisdom about good design and present it in a literary form that enables others to reuse this experience. Each pattern addresses a particular design problem in a particular context, discusses the forces that make finding a good solution difficult, and presents a solution that has been found to be successful in mediating these forces. Nothing about patterns is inherently object-oriented, but the vast majority of work in the patterns community involves OO analysis and design.
With this book, editors Jim Coplien and Doug Schmidt introduce the world at large to the diverse pattern community. The chapters of Pattern Languages of Program Design are based on papers presented at the First Annual Conference of Pattern Languages of Programs, held in August 1994. This was a new kind of conference, where people presented not new research but "old" solutions, ones that they had found repeatedly useful in their own software practices. A central feature of PLoP was the use of the writer's workshop in place of traditional paper presentations. At workshops, writers listened to a small group of reviewers discuss their papers, the ideas therein, and the effectiveness of their form. As a result, Coplien and Schmidt claim "The chapters in this book are certainly among the most intensely edited works in contemporary software literature." This is not a vacuous claim; each chapter of the book is informative, well-written, and enjoyable to read.
Sections 1, 5, and 7 present patterns that are, for the most part, general to the notion of object-oriented software development. In the first section, four chapters address the use of patterns in developing frameworks and reusable components. These chapters also demonstrate the great breadth of the pattern literature. Chapter 2, by Riehle and Zullighoven, describes a pattern language for designing frameworks from the perspective of tools and materials. They extrapolate from an interesting metaphor to a set of design patterns that present insight into the design of most any application framework. On the other hand, Chapter 1, by Adams, presents a single pattern Functionality Ala Carte in a mere two pages. This pattern addresses the thorny issue of how extend the capabilities of a framework without leading to undesirable trade-offs in performance.
The chapters in Section 5 look inward to the issue of pattern classification. Two of these chapters focus on different dimensions by which patterns can be organized, so that appropriate patterns can be identified by software designers at precisely the right moment. The chapter that I found most interesting, however, was Robert Martin's catalog of patterns that he found in a large body of existing code. Martin's patterns are practical looks at the kinds of decisions made by developers in all large software projects. Finally, Section 7 involves patterns in the design of individual objects. that promote reuse. Two of these chapters are among the best in the book. Viljamaa's description of the Client-Specified Self pattern in Chapter 26 clearly explicates a solution to the problem of delegating responsibility in contexts where the role that an object plays can change dynamically. In Chapter 27, Auer gives a pattern language for designing objects using self-encapsulation. This technique results in objects that are maximally reusable in the context of future subclasses. This chapter is so good, and addresses such an important problem, that it should be required reading for all object-oriented programmers.
Sections 2, 6, and 8 deal with patterns for distributed computing. The richness of this domain has led to a wealth of work in the pattern community on issues of synchronization, concurrency, application integration, and event handling. The chapters in these sections present patterns that are of interest even to designers who do not work in this domain, of which this reviewer is one. Their value stems from the value of the pattern form, which encourages discussion of problems and solutions at a level that makes interesting design decisions explicit and palpable. Many of these decisions appear, albeit in slightly different forms, in other kinds of systems, and so the patterns provide a form of inspiration that may not otherwise be available. Among the more generally accessible chapters in these sections are Meszaros' discussion of the Half-Object Plus Protocol pattern for decomposing a single object across multiple hosts in a way that is transparent to users and Schmidt's Reactor pattern for recognizing and dispatching multiple event handlers in an event-driven system.
Section 3 is the only section that is specific to a particular domain, that of business. As a person with experience building models of business processes and expertise, I found this slim section of three chapters to be of tremendous interest. These chapters again demonstrate the great breadth of the pattern literature. Chapter 11, by Wake, outlines a single pattern for Account Number objects. His short discussion of the issues that underlie specification, creation, and use of these objects is lucid and full of important points. In Chapter 10, Cunningham takes a topic of seeming simplicity data validation in entry systems and crafts an insightful language of eleven patterns that captures fundamental expertise for maintaining the integrity of information in a diverse software system.
Section 4 extends the topic of program design in the book's title to its broadest sense, that of process and organization in software development. Each of the four chapters in this section will be of great interest to anyone engaged in the process of building large software systems. Coplien's Chapter 13 describes a language of forty-two patterns for the generative development of a quality software organization that is based on an extensive study of successful software projects. These patterns cover the full range of activities from Size the Organization to Compensate Success. Chapter 14, by Foote and Opdyke, presents patterns that address issues of evolution in object systems and how designers can facilitate the natural flow from prototype through expansion of responsibility to the consolidation of mature objects in a delivered system. Whitenack outlines the beginnings of a pattern language for requirements analysis in Chapter 15. Finally, in Chapter 16, Kerth reports a pattern language aimed at "purifying" the analysis phase of software development. His contention is that, prior to the creation of such pattern languages, the process of analysis and design were so hard to describe that design considerations (such as objects categories) became intermingled in analysis.
Regarding the book as a whole, there is a common feel to all eight sections that is uncommon in most collections of conference papers. The pattern theme is still fresh in the community, and the authors of all thirty chapters have written of patterns in a way that provides a striking unity to the book. Unfortunately, this unity also manifests itself in the form of considerable redundancy across chapter introductions and bibliographies. The narrative descriptions of Alexander's patterns and inspiration to the software community actually lend a nice feeling of homeyness to the proceedings, but the repeated bibliographic entries make following citations across papers a difficult task. One side effect is that papers can be read relatively independent of one another, although I would suggest a substantial reading of the book in order to receive the full impact of what patterns have to offer.
The newness of the field also means that many authors describe patterns that are very similar to others described elsewhere in the text. A task that remains for the pattern community is the integration of different but similar pattern languages into coherent wholes. But this task will not be an easy one, as Kerth discusses in Chapter 16. Finally, the book demonstrates a good balance of patterns that are not language-centric but that are often reported in the context of a single language (usually Smalltalk or C++).
Coplien and Schmidt have assembled a highly readable and informative survey of the work being done on patterns for software design. They acknowledge in their preface that the broad range of problems and solutions presented in this first volume is demanding of the reader and that, as a result, not all chapters will be of equal interest to every reader. I concur with this assessment, but I also concur with their encouragement to partake of all eight sections. After scanning through the book for the first time, my mind was racing with ideas that had been either planted or awakened by various papers in the book. These ideas necessitated my second read, during which I was able to glean the significance of some of the chapters at a much deeper level. And, if you have only limited time, I encourage you to read Section 4 on process and organization. It exemplifies the pattern approach, captures the spirit of examining the process behind the artifact, and is appropriate to readers of all backgrounds. After reading it, you will almost certainly want to go back for more.
Date written: December 1995.