A reusable design must include more information than just the design diagrams. For example,the problem that the design is meant to address must be defined. This information is important because it allows potential reusers, faced with a particular problems, to indentify available designs that are candidates of reuse. Another kind of infomraiton that is needed ina reusable design is the trade-offs imlied by the design. Typically designers must achieve a balance between such competing goals as efficiency, flexibility, fault tolerance, and simplicity (among others). A single problem may give rise to several useful designs, each design offering a different balance among the design factors.
A design pattern is a proposed format for presenting a reusable design. The structure of a design pattern is defined the book "Design Patterns" by Gamma, Helm, Johnson and Vlissides (page 360) as:
A design pattern systematically names, motivates, and explains a general design that addresses a recurring desing problem in object-oriented systems. It describes the problem, the solution, when to apply the solution, and its consequences. It also gives implementation hints and examples. The solution is a general arrangement of objects and classes that solve the problem. The solution is customized and implemented to solve the problem in a particular context.The first sentance of the definition express the intent of a design pattern: to present in a consistent and coherent manner the soltuin to a recurring design problem. The next two sentances of the definition outline the content of a design pattern. The las two sentances explain the usage of a design pattern. The usage makes clear that a design pattern is not a program or code, it is a design thtat must be tailored to fit the specific requirements of a particular problem and then implemented. The "Design Patterns" book contains a collection of design patterns, one of which presented in detail below.
The content of a design pattern is the following twelve elements:
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and composites of objects uniformly.The intent epxresses both the subject matter of the pattern (trees of object related by a part-whole relation) as well as the goal of the pattern (uniformity of treatment). The motivation presented for this pattern describes a typical graphical drawing tool that allows users to draw a variety of predefined basic shapes (rectangles, lines, circles, rounded rectangles, polygons, etc.) and also allows shapes to be composed together. A composite shape is treated as a newly defined basic shape in that it can be composed with other basic or composite shapes. A set of operations (draw, move, resize, etc.) can be applied to any shape (basic or composite). Both a class diagram and an object diagram are used to illustrate a design solution. The class diagram is:
The applicability section defines two conditions: (1)
part-whole hierarchies are being represented, and (2) uniformity of
treatment for parts and a whole is sought. The conditions mirror the
basic ideas presented in the statement of the pattern's intent. The
structure section contains the following generalized class
diagram:
In the generalized class diagram, the specific kinds of "parts" are represented by a single class "Leaf" while the class named "Composite" represents a "whole". The abstract base class, "Component", defines an interface that must be implemented by Leaf classes and the Composite class. The abstract base class reflects the uniform treatment of Leaf and Composite objects. Note also that the generic "Operation" method is an abstraction of some application-specific operation.
The participants section lists the responsibilities of each of the four classes that appear in the structure (Component, Leaf, Composite, Client). For example, the responsibilities of the Composite class are: to define the behvior of "a composition of ojbects, to store the composed (sub)objects, and to implement the operations defined in the abstract base class."
The collaborations section defines how the Composite pattern's participants work together to meet their individual responsibilities and achieve the effect intended for the pattern. For example, in the Composite pattern, the client interacts with the (Leaf or Composite) objects only through the abstract interface defined in the Component class. This collaboration captures a key feature of the pattern: the clinet is able to manipulate Components without regard for whether they are Leaf class objects or Composite class objects.
Two of the consequences of using the Composite pattern are:
The implementation section presents issues relevant to the detailed coding of the classes in the pattern. For example, the trade-off between safety and transparency is considered in this section of the Composite pattern. This trade-off involves where to place the methods for manipulating the children of a Composite. If these methods are placed only in the Composite class it is safer (because attempt to apply them to Leaf components is detected as a compile-time error) but it is less transparent (because Leaf and Composite objects cannot be treated as uniformly as might be desired). Placing the methods in the Component base class yields the opposite trade-off. A compromise strategy introduces a methode Composite* Get Composite() in the Component base class. This method is defined in the Leaf derived class to return a null pointer and defined in the Composite derived class to return its this pointer. This strategy minimizes the loss of transparency (all base class methods apply equally to both Leaf and Composite objects) while retaining a large measure of safety (leaving to the Client the responsibility to differentiation between objects of the two derived classes).
The sample code section gives C++ code for an example of a part-whole problem. This, most detailed, level of presentation helps to give a concrete representation of the pattern that can be compiled and used for experimentation.
The known uses section lists three application domans (user interface toolkits, a compiler, and financial portfolios) where the pattern has been observed.
Finally, four related patterns are noted, including the Iterator pattern that can be used to traverse composite structures.
the ultimate value of design patterns will only be realized by an organized, extensive collection of patterns that encompasses both generic design problems as well as probmes that are specific to particular applications domains. One might imagine a collection of patterns for real-time systems, distributed/concurrent/parallel applications, and other important application areas. The collection of patterns in the Design Patterns book is an important beginning.
Last Updated: January 3, 1996 / kafura@cs.vt.edu