patterns-orig - Design Patterns Abstraction and Reuse of...

This preview shows page 1 out of 21 pages.

Unformatted text preview: Design Patterns: Abstraction and Reuse of Object-Oriented Design Erich Gamma1? , Richard Helm2, Ralph Johnson3 , John Vlissides2 Taligent, Inc. 10725 N. De Anza Blvd., Cupertino, CA 95014-2000 USA 2 I.B.M. Thomas J. Watson Research Center P.O. Box 704, Yorktown Heights, NY 10598 USA 3 Department of Computer Science University of Illinois at Urbana-Champaign 1034 W. Spring eld Ave., Urbana, IL 61801 USA 1 Abstract. We propose design patterns as a new mechanism for expressing object-oriented design experience. Design patterns identify, name, and abstract common themes in objectoriented design. They capture the intent behind a design by identifying objects, their collaborations, and the distribution of responsibilities. Design patterns play many roles in the object-oriented development process: they provide a common vocabulary for design, they reduce system complexity by naming and de ning abstractions, they constitute a base of experience for building reusable software, and they act as building blocks from which more complex designs can be built. Design patterns can be considered reusable micro-architectures that contribute to an overall system architecture. We describe how to express and organize design patterns and introduce a catalog of design patterns. We also describe our experience in applying design patterns to the design of object-oriented systems. 1 Introduction Design methods are supposed to promote good design, to teach new designers how to design well, and to standardize the way designs are developed. Typically, a design method comprises a set of syntactic notations (usually graphical) and a set of rules that govern how and when to use each notation. It will also describe problems that occur in a design, how to x them, and how to evaluate a design. Studies of expert programmers for conventional languages, however, have shown that knowledge is not organized simply around syntax, but in larger conceptual structures such as algorithms, data structures and idioms [1, 7, 9, 27], and plans that indicate steps necessary to ful ll a particular goal [26]. It is likely that designers do not think about the notation they are using for recording the design. Rather, they look for patterns to match against plans, algorithms, data structures, and idioms they have learned in the past. Good designers, it appears, rely on large amounts of design experience, and this experience is just as important as the notations for recording designs and the rules for using those notations. Our experience with the design of object-oriented systems and frameworks [15, 17, 22, 30, 31] bears out this observation. We have found that there exist idiomatic class and object structures that help make designs more exible, reusable, and elegant. For example, the Model-View-Controller (MVC) paradigm from Smalltalk [19] is a design structure that separates representation from presentation. MVC promotes exibility in the choice of views, independent of the model. Abstract factories [10] hide concrete subclasses from the applications that use them so that class names are not hard-wired into an application. ? Work performed while at UBILAB, Union Bank of Switzerland, Zurich, Switzerland. To appear in ECOOP '93 Conference Proceedings, Springer-Verlag Lecture Notes in Computer Science. Well-de ned design structures like these have a positive impact on software development. A software architect who is familiar with a good set of design structures can apply them immediately to design problems without having to rediscover them. Design structures also facilitate the reuse of successful architectures|expressing proven techniques as design structures makes them more readily accessible to developers of new systems. Design structures can even improve the documentation and maintenance of existing systems by furnishing an explicit speci cation of class and object interactions and their underlying intent. To this end we propose design patterns, a new mechanism for expressing design structures. Design patterns identify, name, and abstract common themes in object-oriented design. They preserve design information by capturing the intent behind a design. They identify classes, instances, their roles, collaborations, and the distribution of responsibilities. Design patterns have many uses in the object-oriented development process: { Design patterns provide a common vocabulary for designers to communicate, document, and explore design alternatives. They reduce system complexity by naming and de ning abstractions that are above classes and instances. A good set of design patterns e ectively raises the level at which one programs. { Design patterns constitute a reusable base of experience for building reusable software. They distill and provide a means to reuse the design knowledge gained by experienced practitioners. Design patterns act as building blocks for constructing more complex designs; they can be considered micro-architectures that contribute to overall system architecture. { Design patterns help reduce the learning time for a class library. Once a library consumer has learned the design patterns in one library, he can reuse this experience when learning a new class library. Design patterns help a novice perform more like an expert. { Design patterns provide a target for the reorganization or refactoring of class hierarchies [23]. Moreover, by using design patterns early in the lifecycle, one can avert refactoring at later stages of design. The major contributions of this paper are: a de nition of design patterns, a means to describe them, a system for their classi cation, and most importantly, a catalog containing patterns we have discovered while building our own class libraries and patterns we have collected from the literature. This work has its roots in Gamma's thesis [11], which abstracted design patterns from the ET++ framework. Since then the work has been re ned and extended based on our collective experience. Our thinking has also been in uenced and inspired by discussions within the Architecture Handbook Workshops at recent OOPSLA conferences [3, 4]. This paper has two parts. The rst introduces design patterns and explains techniques to describe them. Next we present a classi cation system that characterizes common aspects of patterns. This classi cation will serve to structure the catalog of patterns presented in the second part of this paper. We discuss how design patterns impact object-oriented programming and design. We also review related work. The second part of this paper (the Appendix) describes our current catalog of design patterns. As we cannot include the complete catalog in this paper (it currently runs over 90 pages [12]), we give instead a brief summary and include a few abridged patterns. Each pattern in this catalog is representative of what we judge to be good object-oriented design. We have tried to reduce the subjectivity of this judgment by including only design patterns that have seen practical application. Every design pattern we have included works|most have been used at least twice and have either been discovered independently or have been used in a variety of application domains. 2 Design Patterns A design pattern consists of three essential parts: 1. An abstract description of a class or object collaboration and its structure. The description is abstract because it concerns abstract design, not a particular design. 2. The issue in system design addressed by the abstract structure. This determines the circumstances in which the design pattern is applicable. 3. The consequences of applying the abstract structure to a system's architecture. These determine if the pattern should be applied in view of other design constraints. Design patterns are de ned in terms of object-oriented concepts. They are suciently abstract to avoid specifying implementation details, thereby ensuring wide applicability, but a pattern may provide hints about potential implementation issues. We can think of a design pattern as a micro-architecture. It is an architecture in that it serves as a blueprint that may have several realizations. It is \micro" in that it de nes something less than a complete application or library. To be useful, a design pattern should be applicable to more than a few problem domains; thus design patterns tend to be relatively small in size and scope. A design pattern can also be considered a transformation of system structure. It de nes the context for the transformation, the change to be made, and the consequences of this transformation. To help readers understand patterns, each entry in the catalog also includes detailed descriptions and examples. We use a template (Figure 1) to structure our descriptions and to ensure uniformity between entries in the catalog. This template also explains the motivation behind its structure. The Appendix contains three design patterns that use the template. We urge readers to study the patterns in the Appendix as they are referenced in the following text. 3 Categorizing Design Patterns Design patterns vary in their granularity and level of abstraction. They are numerous and have common properties. Because there are many design patterns, we need a way to organize them. This section introduces a classi cation system for design patterns. This classi cation makes it easy to refer to families of related patterns, to learn the patterns in the catalog, and to nd new patterns. Jurisdiction Class Creational Characterization Structural Behavioral Factory Method Adapter (class) Template Method Bridge (class) Object Abstract Factory Adapter (object) Chain of Responsibility Prototype Bridge (object) Command Solitaire Flyweight Iterator (object) Glue Mediator Proxy Memento Observer State Strategy Compound Builder Composite Interpreter Wrapper Iterator (compound) Walker Table 1. Design Pattern Space Design Pattern Name Jurisdiction Characterization What is the pattern's name and classi cation? The name should convey the pattern's essence succinctly. A good name is vital, as it will become part of the design vocabulary. Intent What does the design pattern do? What is its rationale and intent? What particular design issue or problem does it address? Motivation A scenario in which the pattern is applicable, the particular design problem or issue the pattern addresses, and the class and object structures that address this issue. This information will help the reader understand the more abstract description of the pattern that follows. Applicability What are the situations in which the design pattern can be applied? What are examples of poor designs that the pattern can address? How can one recognize these situations? Participants Describe the classes and/or objects participating in the design pattern and their responsibilities using CRC conventions [5]. Collaborations Describe how the participants collaborate to carry out their responsibilities. Diagram A graphical representation of the pattern using a notation based on the Object Modeling Technique (OMT) [25], to which we have added method pseudo-code. Consequences How does the pattern support its objectives? What are the trade-o s and results of using the pattern? What does the design pattern objectify? What aspect of system structure does it allow to be varied independently? Implementation What pitfalls, hints, or techniques should one be aware of when implementing the pattern? Are there language-speci c issues? Examples This section presents examples from real systems. We try to include at least two examples from di erent domains. See Also What design patterns have closely related intent? What are the important di erences? With which other patterns should this one be used? Fig. 1. Basic Design Pattern Template We can think of the set of all design patterns in terms of two orthogonal criteria, jurisdiction and characterization. Table 1 organizes our current set of patterns according to these criteria. Jurisdiction is the domain over which a pattern applies. Patterns having class jurisdiction deal with relationships between base classes and their subclasses; class jurisdiction covers static semantics. The object jurisdiction concerns relationships between peer objects. Patterns having compound jurisdiction deal with recursive object structures. Some patterns capture concepts that span jurisdictions. For example, iteration applies both to collections of objects (i.e., object jurisdiction) and to recursive object structures (compound jurisdiction). Thus there are both object and compound versions of the Iterator pattern. Characterization re ects what a pattern does. Patterns can be characterized as either creational, structural, or behavioral. Creational patterns concern the process of object creation. Structural patterns deal with the composition of classes or objects. Behavioral patterns characterize the ways in which classes or objects interact and distribute responsibility. The following sections describe pattern jurisdictions in greater detail for each characterization using examples from our catalog. 3.1 Class Jurisdiction Class Creational. Creational patterns abstract how objects are instantiated by hiding the speci cs of the creation process. They are useful because it is often undesirable to specify a class name explicitly when instantiating an object. Doing so limits exibility; it forces the programmer to commit to a particular class instead of a particular protocol. If one avoids hard-coding the class, then it becomes possible to defer class selection to run-time. Creational class patterns in particular defer some part of object creation to subclasses. An example is the Factory Method, an abstract method that is called by a base class but de ned in subclasses. The subclass methods create instances whose type depends on the subclass in which each method is implemented. In this way the base class does not hard-code the class name of the created object. Factory Methods are commonly used to instantiate members in base classes with objects created by subclasses. For example, an abstract Application class needs to create application-speci c documents that conform to the Document type. Application instantiates these Document objects by calling the factory method DoMakeDocument. This method is overridden in classes derived from Application. The subclass DrawApplication, say, overrides DoMakeDocument to return a DrawDocument object. Class Structural. Structural class patterns use inheritance to compose protocols or code. As a simple example, consider using multiple inheritance to mix two or more classes into one. The result is an amalgam class that unites the semantics of the base classes. This trivial pattern is quite useful in making independently-developed class libraries work together [15]. Another example is the class-jurisdictional form of the Adapter pattern. In general, an Adapter makes one interface (the adaptee's) conform to another, thereby providing a uniform abstraction of di erent interfaces. A class Adapter accomplishes this by inheriting privately from an adaptee class. The Adapter then expresses its interface in terms of the adaptee's. Class Behavioral. Behavioral class patterns capture how classes cooperate with their subclasses to ful ll their semantics. Template Method is a simple and well-known behavioral class pattern [32]. Template methods de ne algorithms step by step. Each step can invoke an abstract method (which the subclass must de ne) or a base method. The purpose of a template method is to provide an abstract de nition of an algorithm. The subclass must implement speci c behavior to provide the services required by the algorithm. 3.2 Object Jurisdiction Object patterns all apply various forms of non-recursive object composition. Object composition represents the most powerful form of reusability|a collection of objects are most easily reused through variations on how they are composed rather than how they are subclassed. Object Creational. Creational object patterns abstract how sets of objects are created. The Ab- stract Factory pattern (page 14) is a creational object pattern. It describes how to create \product" objects through an generic interface. Subclasses may manufacture specialized versions or compositions of objects as permitted by this interface. In turn, clients can use abstract factories to avoid making assumptions about what classes to instantiate. Factories can be composed to create larger factories whose structure can be modi ed at run-time to change the semantics of object creation. The factory may manufacture a custom composition of instances, a shared or one-of-a-kind instance, or anything else that can be computed at run-time, so long as it conforms to the abstract creation protocol. For example, consider a user interface toolkit that provides two types of scroll bars, one for Motif and another for Open Look. An application programmer may not want to hard-code one or the other into the application|the choice of scroll bar will be determined by, say, an environment variable. The code that creates the scroll bar can be encapsulated in the class Kit, an abstract factory that abstracts the speci c type of scroll bar to instantiate. Kit de nes a protocol for creating scroll bars and other user interface elements. Subclasses of Kit rede ne operations in the protocol to return specialized types of scroll bars. A MotifKit's scroll bar operation would instantiate and return a Motif scroll bar, while the corresponding OpenLookKit operation would return an Open Look scroll bar. Object Structural. Structural object patterns describe ways to assemble objects to realize new functionality. The added exibility inherent in object composition stems from the ability to change the composition at run-time, which is impossible with static class composition. Proxy is an example of a structural object pattern. A proxy acts as a convenient surrogate or placeholder for another object. A proxy can be used as a local representative for an object in a di erent address space (remote proxy), to represent a large object that should be loaded on demand (virtual proxy), or to protect access to the original object (protected proxy). Proxies provide a level of indirection to particular properties of objects. Thus they can restrict, enhance, or alter an object's properties. The Flyweight pattern is concerned with object sharing. Objects are shared for at least two reasons: eciency and consistency. Applications that use large quantities of objects must pay careful attention to the cost of each object. Substantial savings can accrue by sharing objects instead of replicating them. However, objects can only be shared if they do not de ne context-dependent state. Flyweights have no context-dependent state. Any additional information they need to perform their task is passed to them when needed. With no context-dependent state, yweights may be shared freely. Moreover, it may be necessary to ensure that all copies of an object stay consistent when one of the copies changes. Sharing provides an automatic way to maintain this consistency. Object Behavioral. Behavioral object patterns describe how a group of peer objects cooperate to perform a task that no single object can carry out by itself. For example, patterns such as Mediator and Chain of Responsibility abstract control ow. They call for objects that exist solely to redirect the ow of messages. The redirection may simply notify another object, or it may involve complex computation and bu ering. The Observer pattern abstracts the synchronization of state or behavior. Entities that are co-dependent to the extent that their state must remain synchronized may exploit Observer. The classic example is the model-view pattern, in which multiple views of the model are noti ed whenever the model's state changes. The Strategy pattern (page 17) objecti es an algorithm. For example, a text compositio...
View Full Document

  • Spring '16
  • dncj ncnd

{[ snackBarMessage ]}

What students are saying

  • Left Quote Icon

    As a current student on this bumpy collegiate pathway, I stumbled upon Course Hero, where I can find study resources for nearly all my courses, get online help from tutors 24/7, and even share my old projects, papers, and lecture notes with other students.

    Student Picture

    Kiran Temple University Fox School of Business ‘17, Course Hero Intern

  • Left Quote Icon

    I cannot even describe how much Course Hero helped me this summer. It’s truly become something I can always rely on and help me. In the end, I was not only able to survive summer classes, but I was able to thrive thanks to Course Hero.

    Student Picture

    Dana University of Pennsylvania ‘17, Course Hero Intern

  • Left Quote Icon

    The ability to access any university’s resources through Course Hero proved invaluable in my case. I was behind on Tulane coursework and actually used UCLA’s materials to help me move forward and get everything together on time.

    Student Picture

    Jill Tulane University ‘16, Course Hero Intern