`
`1}
`u.
`
`H.
`
`'1'"
`
`if.
`2"
`fr
`If}
`
`'4'"-
`
`_f'
`
`1 7
`
`:F1
`1.....-
`
`J‘-
`I.
`
`r”
`g-
`
`H.
`
`.-----.I
`
` El
`
`V r
`
`‘"_...l
`
`T..-F'-
`
`_'.
`
`/_'1H1
`
`'J"
`_—
`3':
`
`'4'”
`
`Design Patterns
`
`Elements of Reusable
`Object-Oriented Software
`
`Erich Gamma
`Richard Helm
`Ralph Johnson
`John Vlissides
`
`
`
`.
`.
`(”Milwut1ld--- lui-qu 'I"
`
`I.
`
`II...I.I.'
`
`Foreword by Grady Booth
`
`1
`
`CONFIGIT 1025
`
`CONFIGIT 1025
`
`1
`
`
`
`Creational Patterns
`
`Abstract Factory (87) Provide an interface for creating families of related or dependent
`objects without specifying their concrete classes.
`
`Builder (97) Separate the construction of a complex object from its representation so
`that the same construction process can create different representations.
`
`Factory Method (107) Define an interface for creating an object, but let subclasses de-
`cide which class to instantiate. Factory Method lets a class defer instantiation to
`subclasses.
`
`Prototype (117) Specify the kinds of objects to create using a prototypital instance, and
`create new objects by copying this prototype.
`
`Singleton (127) Ensure a class only has one instance, and provide a global point of
`access to it.
`
`Structural Patterns
`
`Adapter (139) Convert the interface of a class into another interface clients expect.
`Adapter lets classes work together that couldn’t otherwise because of incompat-
`ible interfaces.
`
`Bridge (151) Decouple an abstraction from its implementation so that the two can vary
`independently.
`
`Composite (163) Compose objects into tree structures to represent part-whole hierar-
`chies. Composite lets clients treat individual objects and compositions of objects
`uniformly.
`
`Decorator (175) Attach additional responsibilities to an object dynamically. Decorators
`provide a flexible alternative to subclassing for extending functionality.
`
`Facade (185) Provide a unified interface to a set of interfaces in a subsystem. Facade
`defines a higher-level interface that makes the subsystem easier to use.
`
`Flyweight (195) Use sharing to support large numbers of fine-grained objects effi-
`ciently.
`
`Proxy (207) Provide a surrogate or placeholder for another object to control access to
`it.
`
`2
`
`
`
`Behavioral Patterns
`
`Chain of Responsibility (223) Avoid coupling the sender of a request to its receiver by
`giving more than one object a chance to handle the request. Chain the receiving
`objects and pass the request along the chain until an object handles it.
`
`Command (233) Encapsulate a request as an object, thereby letting you parameter—
`ize clients with different requests, queue or log requests, and support undoable
`operations.
`
`Interpreter (243) Given a language, define a represention for its grammar along with
`an interpreter that uses the representation to interpret sentences in the language.
`
`Iterator (257) Provide a way to access the elements of an aggregate object sequentially
`without exposing its underlying representation.
`
`Mediator (273) Define an object that encapsulates how a set of objects interact. Mes
`diator promotes loose coupling by keeping objects from referring to each other
`explicitly, and it lets you vary their interaction independently.
`
`Memento (283) Without violating encapsulation, capture and externalize an object’s
`internal state so that the object can be restored to this state later.
`
`Observer (293) Define a one-to-many dependency between objects so that when one
`object changes state, all its dependents are notified and updated automatically.
`
`State (305) Allow an object to alter its behavior when its internal state changes. The
`object will appear to change its class.
`
`Strategy (315) Define a family of algorithms, encapsulate each one, and make them
`interchangeable. Strategy lets the algorithm vary independently from clients that
`use it.
`
`Template Method (325) Define the skeleton of an algorithm in an operation, deferring
`some steps to subclasses. Template Method lets subclasses redefine certain steps
`of an algorithm without changing the algorithm's structure.
`
`Visitor (331) Represent an operation to be performed on the elements of an object
`structure. Visitor lets you define a new operation without changing the classes of
`the elements on which it operates.
`
`3
`
`
`
`This page intentionally left blank
`
`4
`
`
`
`Design Patterns
`
`5
`
`
`
`Addison-Wesley Professional Computing Series
`Brian W. Kernighan, Consulting Editor
`
`Matthew H. Austern, Generic Programming and the STL: Using and Extending the C++ Standard Template Library
`David R. Butenhof, Programming with POSIX® Threads
`Brent Callaghan, NFS Illustrated
`Tom Cargi11,C++ Programming Style
`William R. Chesw1ck/Steven M. Bellovm/Av1e1 D. Rubin, Firewalls and Internet Security, Second Edition. Repelling
`the Wily Hacker
`David A. Curry, UNIX® System Security: A Guide for Users and System Administrators
`Stephen C. Dewhurst, C++ Gotchas: Avoiding Common Problems in Coding and Design
`Dan Farmer /Wietse Venema, Forensic Discovery
`Erich Gamma /Richard Helm/Ralph Johnson/John Vlissides, Design Patterns: Elements of Reusable Object-
`Oriented Software
`Erich Gamma /Richard Helm/Ralph Johnson/John Vlissides, Design Patterns CD: Elements of Reusable Object-
`Oriented Software
`Peter Haggar, Practical Java” Programming Language Guide
`David R. Hanson, C Interfaces and Implementations: Techniques for Creating Reusable Software
`Mark Harrison/Michael McLennan, Efi‘ective Tcl/Tk Programming: Writing Better Programs with Tcl and Th
`Michi Henm'ng/ Steve Vinoski, Advanced CORBA® Programming with C++
`Brian W. Kernighan/Rob Pike, The Practice of Programming
`S. Keshav, An Engineering Approach to Computer Networking: ATM Networks, the Internet, and the Telephone Network
`
`John Lakos, Large—Scale C++ Software Design
`Scott Meyers, Efective C++ CD: 85 Specific Ways to Improve Your Programs and Designs
`Scott Meyers, Effective C++, Third Edition: 55 Speafic Ways to Improve Your Programs and Designs
`Scott Meyers, More Effective C++: 35 New Ways to Improve Your Programs and Designs
`Scott Meyers, Efiective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library
`
`Robert B. Murray, C++ Strategies and Tactics
`David R. Musser/Gillmer J. Derge/Atul Saini, STL Tutorial and Reference Guide, Second Edition:
`C++ Programming with the Standard Template Library
`John K. Ousterhout, Tcl and the Tk Toolkit
`
`Craig Partridge, Gigabit Networking
`Radia Perlman, Interconnections, Second Edition: Bridges, Routers, Switches, and Internetworking Protocols
`Stephen A. Rage, UNIX® System V Network Programming
`Eric S. Raymond, The Art of UNIX Programming
`Marc J. Rochkind, Advanced UNIX Programming, Second Edition
`Curt Schimmel, UNIX“ Systemsfiir Modern Architectures: Symmetric Multiprocessing and Cachingfor Kernel Programmers
`W. Richard Stevens, TCP/IP Illustrated, Volume 1: The Protocols
`
`W. Richard Stevens, TCP/IP Illustrated, Volume 3: TCP for Transactions, HTTP, NNTP, and the UNIX”
`Domain Protocols
`
`W. Richard Stevens/Bill Fenner/Andrew M. Rudoff, UNIX Network Programming Volume 1, Third Edition: The
`
`Sockets Networking API
`W. Richard Stevens / Stephen A. Rago, Advanced Programming in the UNIX® Environment, Second Edition
`W. Richard Stevens /Gary R. Wright, TCP/IP Illustrated Volumes 1—3 Boxed Set
`John Viega/Gary McGraw, Building Secure Software: How to Avoid Security Problems the Right Way
`Gary R. Wright/W. Richard Stevens, TCP/IP Illustrated, Volume 2: The Implementation
`Ruixi Yuan/W. Timothy Strayer, Virtual Private Networks: Technologies and Solutions
`
`Visit www.awprofessional.com/series/professionalcomputing for more information about these titles.
`
`6
`
`6
`
`
`
`Design Patterns
`Elements of Reusable Object-Oriented Software
`
`
`Erich Gamma
`
`Richard Helm
`
`Ralph Johnson
`
`John Vlissides
`
`AV
`
`V
`
`ADDISON—WESLEY
`
`Boston 0 San Francisco - New York - Toronto - Montreal
`
`London 0 Munich - Paris 0 Madrid
`
`Capetown 0 Sidney 0 Tokyo - Singapore - Mexico City
`
`7
`
`
`
`Material from A Pattern Language: Towns/Buildings/Constmction by Christopher Alexander,
`copyright © 1977 by Christopher Alexander is reprinted by permission of Oxford University
`Press, Inc.
`
`Many of the designations used by manufacturers and sellers to distinguish their products are claimed as
`trademarks. Where those designations appearin this book, and we were aware of a trademark claim, the
`designations have been printed in initial capital letters or in all capitals.
`
`The author and publisher have taken care in the preparation of this book, but make no expressed or
`implied warranty of any kind and assume no responsibility for errors or omissions. No liability is
`assumed for incidental or consequential damages in connection with or arising out of the use of the
`information or programs contained herein.
`
`The publisher offers discounts on this book when ordered in quantity for special sales. For more informa-
`tion, please contact:
`
`Pearson Education Corporate Sales Division
`201 W. 103rd Street
`
`Indianapolis, IN 46290
`(800) 428-5331
`
`corpsales@pearsoned.com
`
`Visit AW on the Web: www.awprofessiona1.com
`
`Library of Congress Cataloging-in-Publication Data
`Design Patterns : elements of reusable object-oriented software / Erich Gamma .
`p. cm.—(Addison-Wesley professional computing series)
`Includes bibliographical references and index.
`ISBN 0-201-63361-2
`
`.
`
`. [et 211.].
`
`1. Object—oriented programming (Computer science) 2. Computer software—Reusability.
`I. Gamma, Erich. H. Series.
`
`QA76.64.D47 1994
`005.1’2-‘-dc2.0
`
`Copyright © 1995 by Addisoanesley
`
`94—34264
`CIP
`
`All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or
`transmitted, in any form, or by any means, electronic, mechanical, photocopying, recording, or other-
`wise, without the prior consent of the publisher. Printed in the United States of America. Published
`simultaneously in Canada.
`
`Cover art © M.C. Escher/Cordon Art - Baarn - Holland. All rights reserved.
`
`ISBN 0—201—63361-2
`
`Text printed in the United States on recycled paper at Courier Westford in Westford, Massachusetts.
`
`37th Printing March 2009
`
`8
`
`
`
`To Karin
`
`—-E.G.
`
`To Sylvie
`——R.H.
`
`To Faith
`
`—R.I.
`
`To Dru Ann and Matthew
`
`Ioshua 24:15!)
`——-].V.
`
`9
`
`
`
`Praise for Design Patterns: Elements of Reusable
`Object-Oriented Software
`
`
`
`“This is one of the best written and wonderfully insightful books that I have read in a great long while...this
`book establishes the legitimacy of patterns in the best way: not by argument but by example.”
`- Stan Lippman, C++ Report
`
`“...this new book by Gamma, Helm, Johnson, and Vlissides promises to have an important and lasting
`impact on the discipline of software design. Because Design Patterns bills itself as being concerned with
`object-oriented software alone, I fear that software developers outside the object community may ignore it.
`This would be a shame. This book has something for everyone who designs software. All software design-
`ers use patterns; understanding better the reusable abstractions of our work can only make us better at it.”
`— Tom DeMarco, IEEE Software
`
`“Overall, I think this book represents an extremely valuable and unique contribution to the field because
`it captures a wealth of obj cot-oriented design experience in a compact and reusable form. This book is
`certainly one that I shall turn to often in search of powerful object—oriented design ideas; after all, that’s
`what reuse is all about, isn’t it?”
`
`-—~ Sanjiv Gossain, Journal of Object-Oriented Programming
`
`“This much—anticipated book lives up to its full year of advance buzz. The metaphor is of an architect’s
`pattern book filled with time-tested, usable designs. The authors have chosen 23 patterns from decades of
`object—oriented experience. The brilliance of the book lies in the discipline represented by that number.
`Give a copy of Design Patterns to every good programmer you know who wants to be better.”
`— Larry O’Brien, Software Development
`
`“The simple fact of the matter is that patterns have the potential to permanently alter the software
`engineering field, catapulting it into the realm of true elegant design. Of the books to date on this subject,
`Design Patterns is far and away the best. It is a book to be read, studied, internalized, and loved. The book
`will forever change the way you view software.”
`— Steve Bilow, Journal of Object-Oriented Programming
`
`“Design Patterns is a powerful book. After a modest investment of time with it, most C++ programmers
`will be able to start applying its “patterns” to produce better software. This book delivers intellectual
`leverage: concrete tools that help us think and express ourselves more effectively. It may fundamentally
`change the way you think about programming.
`— Tom Cargill, C++ Report
`
`10
`
`10
`
`
`
`Contents
`
`Preface
`
`Foreword
`
`Guide to Readers
`
`1
`
`Introduction
`
`,
`
`1.1 What Is a Design Pattern? ..........................
`
`1.2 Design Patterns in Smalltalk MVC .....................
`
`1.3 Describing Design Patterns .........................
`
`1.4 The Catalog of Design Patterns .......................
`
`1.5 Organizing the Catalog ...........................
`
`xi
`
`xiii
`
`xv
`
`1
`
`2
`
`4
`
`6
`
`8
`
`9
`
`1.6 How Design Patterns Solve Design Problems ...............
`
`11
`
`1.7 How to Select a Design Pattern ....................... 28
`
`1.8 How to Use a Design Pattern ........................ 29
`
`2 A Case Study: Designing a Document Editor
`
`33
`
`2.1 Design Problems ............................... 33
`
`2.2 Document Structure ............................. 35
`
`2.3 Formatting .................................. 40
`2.4 Embellishing the User Interface ..................... .
`.
`.
`43
`
`2.5 Supporting Multiple Look-and-Feel Standards ..............
`
`2.6 Supporting Multiple Window Systems ...................
`
`2.7 User Operations .............................. c
`
`47
`
`51
`
`58
`
`2.8 Spelling Checking and Hyphenation .................... 64
`
`vii
`
`11
`
`11
`
`
`
`viii
`
`CONTENTS
`
`2.9 Summary ................................... 76
`
`Design Pattern Catalog
`
`3 Creational Patterns
`
`79
`
`81
`
`Abstract Factory .................................. 87
`
`Builder ....................................... 97
`
`Factory Method .................................. 107
`
`Prototype ...................................... 117
`
`Singleton ...................................... 127
`
`Discussion of Creational Patterns ......................... 135
`
`4 Structural Patterns
`
`137
`
`Adapter ....................................... 139
`
`Bridge ........................................ 151
`
`Composite ..................................... 163
`
`Decorator ...................................... 175
`
`Facade ........................................ 185
`
`Flyweight ...................................... 195
`
`Proxy ........................................ 207
`
`Discussion of Structural Patterns ......................... 219
`
`5 Behavioral Patterns
`
`,
`
`221
`
`Chain of Responsibility .............................. 223
`
`Command ...................................... 233
`
`Interpreter ..................................... 243
`
`Iterator ....................................... 257
`
`Mediator ...................................... 273
`
`Memento ...................................... 283
`
`Observer...................." .................. 293
`
`State ......................................... 305
`
`Strategy ....................................... 315
`
`12
`
`12
`
`
`
`CONTENTS
`
`ix
`
`Template Method .................................. 325
`
`Visitor ........................................ 331
`
`Discussion of Behavioral Patterns ......................... 345
`
`6 Conclusion
`
`351
`
`6.1 What to Expect from Design Patterns .................... 351
`
`6.2 A Brief History ................................ 355
`
`6.3 The Pattern Community ........................... 356
`
`6.4 An Invitation ................................. 358
`
`6.5 A Parting Thought .............................. 358
`
`A Glossary
`
`B Guide to Notation
`
`359
`
`363
`
`3.1 Class Diagram ................................ 363
`
`B2 Object Diagram ................................ 364
`
`3.3 Interaction Diagram ............................. 366
`
`C Foundation Classes
`
`369
`
`CI List ...................................... 369
`
`C2 Iterator .................................... 372
`
`C3 ListIterator .................................. 372
`
`CA Point ...................................... 373
`
`C5 Rect ...................................... 374
`
`Bibliography
`
`Index
`
`375
`
`383
`
`13
`
`13
`
`
`
`This page intentionally left blank
`
`14
`
`
`
`Preface
`
`This book isn’t an introduction to object-oriented technology or design. Many books
`already do a good job of that. This book assumes you are reasonably proficient in at least
`one object-oriented programming language, and you should have some experience in
`object-oriented design as well. You definitely shouldn’t have to rush to the nearest
`dictionary the moment we mention "types” and ”polymorphism,” or ”interface” as
`opposed to "implementation" inheritance.
`
`On the other hand, this isn’t an advanced technical treatise either. It’s a book of design
`patterns that describes simple and elegant solutions to specific problems in object-
`oriented software design. Design patterns capture solutions that have developed and
`evolved over time. Hence they aren’t the designs people tend to generate initially. They
`reflect untold redesign and recoding as developers have struggled for greater reuse
`and flexibility in their software. Design patterns capture these solutions in a succinct
`and easily applied form.
`
`The design patterns require neither unusual language features nor amazing program-
`ming tricks with which to astound your friends and managers. All can be implemented
`in standard object-oriented languages, though they might take a little more work than
`ad hoc solutions. But the extra effort invariably pays dividends in increased flexibility
`and reusability.
`
`Once you understand the design patterns and have had an ”Aha!” (and not just a
`”Huh?”) experience with them, you won’t ever think about object-oriented design in
`the same way. You’ll have insights that can make your own designs more flexible,
`modular, reusable, and understandable—which is why you’re interested in object-
`oriented technology in the first place, right?
`
`A word of warning and encouragement: Don’t worry if you don’t understand this
`book completely on the first reading. We didn’t understand it all on the first writing!
`Remember that this isn’t a book to read once and put on a shelf. We hope you'll find
`yourself referring to it again and again for design insights and for inspiration.
`
`This book has had a long gestation. It has seen four countries, three of its authors’
`marriages, and the birth of two (unrelated) offspring. Many people have had a part
`in its development. Special thanks are due Bruce Anderson, Kent Beck, and André
`Weinand for their inspiration and advice. We also thank those who reviewed drafts
`
`xi
`
`15
`
`15
`
`
`
`xii
`
`PREFACE
`
`of the manuscript: Roger Bielefeld, Grady Booch, Tom Cargill, Marshall Cline, Ralph
`Hyre, Brian Kernighan, Thomas Laliberty, Mark Lorenz, Arthur Riel, Doug Schmidt,
`Clovis Tondo, Steve Vinoski, and Rebecca Wirfs-Brock. We are also grateful to the
`team at Addison-Wesley for their help and patience: Kate Habib, Tiffany Moore, Lisa
`Raffaele, Pradeepa Siva, and John Wait. Special thanks to Carl Kessler, Danny Sabbah,
`and Mark Wegman at IBM Research for their unflagging support of this work.
`
`Last but certainly not least, we thank everyone on the Internet and points beyond who
`cemented on versions of the patterns, offered encouraging words, and told us that
`what we were doing was worthwhile. These people include but are not limited to
`Jon Avotins, Steve Berczuk, Julian Berdych, Matthias Bohlen, John Brant, Allan Clarke,
`Paul Chisholm, Jens Coldewey, Dave Collins, Jim Copiien, Don Dwiggins, Gabriele Elia,
`Doug Felt, Brian Foote, Denis Fortin, Ward Harold, Hermann Hueni, Nayeem Islam,
`Bikramjit Kalra, Paul Keefer, Thomas Kofler, Doug Lea, Dan LaLiberte, James Long,
`Ann Louise Luu, Pundi Madhavan, Brian Marick, Robert Martin, Dave McComb, Carl
`McConnell, Christine Mingins, Hanspeter Mossenbock, Eric Newton, Marianne Ozkan,
`Roxsan Payette, Larry Podmolik, George Radin, Sita Ramakrishnan, Russ Ramirez,
`Alexander Ran, Dirk Riehle, Bryan Rosenburg, Aamod Sane, Duri Schmidt, Robert
`Seidl, Xin Shu, and Bill Walker.
`
`We don’t consider this collection of design patterns complete and static; it’s more a
`recording of our current thoughts on design. We welcome comments on it, whether
`criticisms of our examples, references and known uses we’ve missed, or design pat-
`terns we should have included. You can write us care of Addison-Wesley, or send
`electronic mail to design—patterns@cs . uiuc . edu. You can also obtain softcopy
`for the code in the Sample Code sections by sending the message “send design pattern
`source” to design—patterns—source@cs . uiuc . edu. And now there's a Web page
`at ht tp: / / st—www . cs . uiuc . edu/users /patterns /DPBook/DPBook . html for
`late-breaking information and updates.
`
`Mountain View, California
`
`Montreal, Quebec
`
`Urbana, Illinois
`
`Hawthorne, New York
`
`August 1994
`
`E.G.
`
`R.H.
`
`R.J.
`
`J.V.
`
`16
`
`16
`
`
`
`This page intentionally left blank
`
`17
`
`
`
`
`
`
`
`OBSERVER Object Behavioral
`
`OBSERVER
`
`293
`
`Intent
`
`Define a one—to-many dependency between objects so that when one object
`changes state, all its dependents are notified and updated automatically.
`
`Also Known As
`
`Dependents, Publish-Subscribe
`
`Motivation
`
`A common side—effect of partitioning a system into a collection of cooperating
`classes is the need to maintain consistency between related objects. You don’t
`want to achieve consistency by making the classes tightly coupled, because that
`reduces their reusability.
`
`For example, many graphical user interface toolkits separate the presentational
`aspects of the user interface from the underlying application data [KP88, LVC89,
`P+ 88, WGMSS]. Classes defining application data and presentations can be reused
`independently. They can work together, too. Both a spreadsheet object and bar
`chart object can depict information in the same application data object using
`different presentations. The spreadsheet and the bar chart don’t know about each
`other, thereby letting you reuse only the one you need. But they behave as though
`they do. When the user changes the information in the spreadsheet, the bar chart
`reflects the changes immediately, and vice versa.
`
`observ er a
`
` -——--
`
`__ _ _ _,_
`
`lil'lflllgtfrlLlllllliidlll'Jl'l
`requests modIF-catlons
`
`18
`
`18
`
`
`
`294
`
`BEHAVIORAL PATTERNS
`
`CHAPTER 5
`
`This behavior implies that the spreadsheet and bar chart are dependent on the
`data object and therefore should be notified of any change in its state. And there’s
`no reason to limit the number of dependent objects to two; there may be any
`number of different user interfaces to the same data.
`
`The Observer pattern describes how to establish these relationships. The key
`objects in this pattern are subject and observer. A subject may have any number
`of dependent observers. All observers are notified whenever the subject undergoes
`a change in state. In response, each observer will query the subject to synchronize
`its state with the subject’s state.
`
`This kind of interaction is also known as publish-subscribe. The subject is the
`publisher of notifications. It sends out these notifications without having to know
`who its observers are. Any number of observers can subscribe to receive notifica-
`tions.
`
`Applicability
`
`Use the Observer pattern in any of the folloWing situations:
`
`0 When an abstraction has two aspects, one dependent on the other. Encapsu-
`lating these aspects in separate objects lets you vary and reuse them inde-
`pendently.
`
`0 When a change to one object requires changing others, and you don’t know
`how many objects need to be changed.
`
`a When an object should be able to notify other objECts without making as—
`sumptions about who these objects are. In other words, you don’t want these
`objects tightly coupled.
`
`Structure
`
`
`
`
`
`
`Attach(0bserver)
` A
`for all 0 in observers {
`Detach(0bserver)
`
`Notify/O o ------- } o—>Update()
`
`A
`ConcreteObserver
`
`
`
`
`-
`
`obsenrerState=
`subject—>GetState0
`
`
`
`observers
`
`
`
`'
`
`ConcreteSubiect
`
`Update()
`
`0—-
`
`GetState() o — - -
`
`-
`
`.
`
`
`
`K‘s
`
`
`
`observerState
`
`19
`
`19
`
`
`
`OBSERVER
`
`295
`
`Participants
`
`a Subject
`
`— knows its observers. Any number of Observer objects may observe a sub-
`ject.
`
`—- provides an interface for attaching and detaching Observer objects.
`
`0 Observer
`
`— defines an updating interface for objects that should be notified of changes
`in a subject.
`
`a ConcreteSubject
`
`— stores state of interest to ConcreteObserver objects.
`
`— sends a notification to its observers when its state changes.
`
`a ConcreteObserver
`
`— maintains a reference to a ConcreteSubject object.
`
`— stores state that should stay consistent with the subject’s.
`
`— implements the Observer updating interface to keep its state consistent
`with the subject’s.
`
`Collaborations
`
`o ConcreteSubject notifies its observers whenever a change occurs that could
`make its observers’ state inconsistent with its own.
`
`o After being informed of a change in the concrete subject, a ConcreteObserver
`object may query the subject for information. ConcreteObserver uses this in-
`formation to reconcile its state with that of the subject.
`The following interaction diagram illustrates the collaborations between a
`subject and two observers:
`
`aConcreteSubject
`
`aConcreteObserver
`
`anotherConcreteObserver
`
`
`
`Update()
`
`GetStateO
`
`SetStaieO
`
`GetStateO
`
`20
`
`20
`
`
`
`296
`
`BEHAVIORAL PATTERNS
`
`CHAPTER 5
`
`Note how the Observer object that initiates the change request postpones its
`update until it gets a notification from the subject. Notify is not always called
`by the subject. It can be called by an observer or by another kind of object
`entirely. The Implementation section discusses some common variations.
`
`Consequences
`
`The Observer pattern lets you vary subjects and observers independently. You
`can reuse subjects Without reusing their observers, and vice versa. It lets you add
`observers without modifying the subject or other observers.
`
`Further benefits and liabilities of the Observer pattern include the following:
`
`1. Abstract coupling between Subject and Observer. All a subject knows is that it
`has a list of observers, each conforming to the simple interface of the abstract
`Observer class. The subject doesn’t know the concrete class of any observer.
`Thus the coupling between subjects and observers is abstract and minimal.
`
`Because Subject and Observer aren’t tightly coupled, they can belong to
`different layers of abstraction in a system. A lower-level subject can com-
`municate and inform a higher-level observer, thereby keeping the system’s
`layering intact. If Subject and Observer are lumped together, then the result-
`ing object must either span two layers (and Violate the layering), or it must be
`forced to live in one layer or the other (which might compromise the layering
`abstraction).
`
`. Support for broadcast communication. Unlike an ordinary request, the notifi-
`cation that a subject sends needn’t specify its receiver. The notification is
`broadcast automatically to all interested objects that subscribed to it. The
`subject doesn't care how many interested objects exist; its only responsibil-
`ity is to notify its observers. This gives you the freedom to add and remove
`observers at any time. It’s up to the observer to handle or ignore a notification.
`
`. Unexpected updates. Because observers have no knowledge of each other’s
`presence, they can be blind to the ultimate cost of changing the subject. A
`seemingly innocuous operation on the subject may cause a cascade of updates
`to observers and their dependent objects. Moreover, dependency criteria that
`aren’t well—defined or maintained usually lead to spurious updates, which
`can be hard to track down.
`
`This problem is aggravated by the fact that the simple update protocol pro-
`vides no details on what changed in the subject. Without additional protocol
`to help observers discover what changed, they may be forced to work hard
`to deduce the changes.
`
`Implementation
`
`Several issues related to the implementation of the dependency mechanism are
`discussed in this section.
`
`21
`
`21
`
`
`
`OBSERVER
`
`297
`
`1. Mapping subjects to their observers. The simplest way for a subject to keep
`track of the observers it should notify is to store references to them explicitly
`in the subject. However, such storage may be too expensive when there are
`many subjects and few observers. One solution is to trade space for time by
`using an associative look-up (e.g., a hash table) to maintain the subject-to-
`observer mapping. Thus a subject with no observers does not incur storage
`overhead. On the other hand, this approach increases the cost of accessing
`the observers.
`
`2. Observing more than one subject. It might make sense in some situations for
`an observer to depend on more than one subject. For example, a spreadsheet
`may depend on more than one data source. It’s necessary to extend the
`Update interface in such cases to let the observer know which subject is
`sending the notification. The subject can simply pass itself as a parameter
`in the Update operation, thereby letting the observer know which subject to
`examine.
`
`3. Who triggers the update? The subject and its observers rely on the notification
`mechanism to stay consistent. But what object actually calls Notify to trigger
`the update? Here are two options:
`
`(a) Have state-setting operations on Subject call Notify after they change
`the subject’s state. The advantage of this approach is that clients don’t
`have to remember to call Notify on the subject. The disadvantage is that
`several consecutive operations will cause several consecutive updates,
`which may be inefficient.
`
`(b) Make clients responsible for calling Notify at the right time. The advan-
`tage here is that the client can wait to trigger the update until after a series
`of state changes has been made, thereby avoiding needless intermediate
`updates. The disadvantage is that clients have an added responsibility
`to trigger the update. That makes errors more likely, since clients might
`forget to call Notify.
`
`4. Dangling references to deleted subjects. Deleting a subject should not produce
`dangling references in its observers. One way to avoid dangling references
`is to make the subject notify its observers as it is deleted so that they can
`reset their reference to it. In general, simply deleting the observers is not an
`option, because other objects may reference them, or they may be observing
`other subjects as well.
`
`5. Making sure Subject state is self—consistent before notification. It’s important to
`make sure Subject state is self-consistent before calling Notify, because ob-
`servers query the subject for its current state in the course of updating their
`own state.
`
`This self-consistency rule is easy to violate unintentionally when Subject
`subclass operations call inherited operations. For example, the notification in
`
`22
`
`22
`
`
`
`298
`
`BEHAVIORAL PATTERNS
`
`CHAPTER 5
`
`the following code sequence is trigged when the subject is in an inconsistent
`state:
`
`{
`void MySubject::0peration (int newValue)
`BaseClassSubject::Operation(newValue);
`// trigger notification
`
`_myInstVar += newvalue;
`// update subclass state (too late!)
`
`}
`
`You can avoid this pitfall by sending notifications from template methods
`(Template Method (325)) in abstract Subject classes. Define a primitive op-
`eration for subclasses to override, and make Notify the last operation in the
`template method, which will ensure that the object is self-consistent when
`subclasses override Subject Operations.
`
`(TextRange r)
`void Text::Cut
`ReplaceRange(r);
`Notify();
`
`}
`
`{
`// redefined in subclasses
`
`By the way, it’s always a good idea to document which Subject operations
`trigger notifications.
`
`6. Avoiding observer-specific update protocols: the push and pull models. Implemen-
`tations of the Observer pattern often have the subject broadcast additional
`information about the change. The subject passes this information as an
`argument to Update. The amount of information may vary widely.
`
`At one extreme, which we call the push model, the subject sends observers
`detailed information about the change, whether they want it or not. At the
`other extreme is the pull model; the subject sends nothing but the most
`minimal notification, and observers ask for details explicitly thereafter.
`
`The pull model emphasizes the subject’s ignorance of its observers, whereas
`the push model assumes subjects know something about their observers’
`needs. The push model might make observers less reusable, because Subject
`classes make assumptions about Observer classes that might not always be
`true. On the other hand, the pull model may be inefficient, because Observer
`classes must ascertain what changed without help f