`
`>
`
`p=
`wo
`
`i i or
`
`a
`—_
`Pail
`
`72
`
`i 2
`
`7.
`rm—,
`
`S 7
`
`,
`ee
`
`én
`>.
`
`fe
`
`=,
`iw
`Yall
`
`=—
`
`i é
`
`Design Patterns
`
`Elements of Reusable
`Object-Oriented.Software
`Erich Gamma
`Richard Helm
`Ralph Johnson
`John Vlissides
`
`
`
`.Fe|
`
`ee
`
`=
`
`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 sameconstruction 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 Methodlets a class defer instantiation to
`subclasses.
`
`Prototype (117) Specify the kinds of objects to create using a prototypical instance, and
`create new objects by copying this prototype.
`
`Singleton (127) Ensure a class only has one instance, and provide a global point of
`accesstoit.
`
`Structural Patterns
`
`Adapter (139) Convert the interface of a class into another interface clients expect.
`Adapterlets 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
`provideaflexible 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 easierto 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 senderof a requestto 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 handlesit.
`
`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 wayto access the elements of an aggregate object sequentially
`without exposing its underlying representation.
`
`Mediator (273) Define an object that encapsulates howa set of objects interact. Me-
`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 restoredtothisstatelater.
`
`Observer (293) Define a one-to-many dependency between objects so that when one
`object changesstate, all its dependents are notified and updated automatically.
`
`State (305) Allow an object to alter its behavior whenits internal state changes. The
`object will appear to changeits class.
`
`Strategy (315) Define a family of algorithms, encapsulate each one, and make them
`interchangeable.Strategylets the algorithm vary independently from clients that
`useit.
`
`Template Method (325) Define the skeleton of an algorithm in an operation, deferring
`somesteps to subclasses. Template Methodlets 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 changingthe classes of
`the elements on whichit 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, NFSIllustrated
`Tom Cargill, C++ Programming Style
`William R. Cheswick/Steven M. Bellovin/Aviel D. Rubin, Firewalls and Internet Security, Second Edition: Repelling
`the Wily Hacker
`David A. Curry, UNIX® System Security: A Guidefor 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,Effective Tcl/Tk Programming: Writing Better Programs with Tcl and Tk
`Michi Henning/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, Effective C++ CD: 85 Specific Ways to Improve Your Programs and Designs
`Scott Meyers, Effective C++, Third Edition: 55 Specific Ways to Improve Your Programs and Designs
`Scott Meyers, More Effective C++: 35 New Ways to Improve Your Programs and Designs
`Scott Meyers, Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library
`Robert B. Murray, C++ Strategies and Tactics
`David R. Musser/GillmerJ. 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. Rago, UNIX® System V Network Programming
`Eric S. Raymond, The Art of UNIX Programming
`MarcJ. Rochkind, Advanced UNIX Programming, Second Edition
`Curt Schimmel, UNIX® Systemsfor 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
`
`6
`Visit www.awprofessional.com/series/professionalcomputing for more information about thesetitles.
`
`6
`
`
`
`Design Patterns
`Elements of Reusable Object-Oriented Software
`
`
`
`Erich Gamma
`
`Richard Helm
`
`Ralph Johnson
`
`John Vlissides
`
`A v
`
`v
`
`ADDISON-WESLEY
`
`Boston * San Francisco * New York * Toronto * Montreal
`
`London * Munich « Paris « Madrid
`Capetown * Sidney * Tokyo * Singapore * Mexico City
`
`7
`
`
`
`Material from A Pattern Language: Towns/Buildings/Construction by Christopher Alexander,
`copyright © 1977 by Christopher Alexanderis reprinted by permission of Oxford University
`Press, Inc.
`
`Manyofthe designations used by manufacturers and sellers to distinguish their products are claimed as
`trademarks. Where those designations appear in 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.awprofessional.com
`
`Library of Congress Cataloging-in-Publication Data
`Design Patterns : elements of reusable object-oriented software / Erich Gamma. . . [et al.].
`p. cm.—(Addison-Wesley professional computingseries)
`Includes bibliographical references and index.
`ISBN 0-201-63361-2
`1. Object-oriented programming (Computer science) 2. Computer software —Reusability.
`I. Garama, Erich. II. Series.
`QA76.64.D47 1994
`005 .1’2-—-dce20
`
`94-34264
`CIP
`
`Copyright © 1995 by Addison-Wesley
`
`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,.
`
`To Dru Ann and Matthew
`Joshua 24:15b
`—f.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 andlasting
`impact on the discipline of software design. Because Design Patternsbills itself as being concerned with
`object-oriented software alone, I fear that software developers outside the object community may ignoreit.
`This would be a shame. This book has something for everyone whodesigns software. All software design-
`ers use patterns; understanding better the reusable abstractions of our work can only makeusbetteratit.”
`— 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 object-oriented design experience in a compact and reusable form. This bookis
`certainly one that I shall turn to often in search of powerful object-oriented design ideas; afterall, that’s
`whatreuse is all about, isn’t it?”’
`— Sanjiv Gossain, Journal of Object-Oriented Programming
`
`“This much-anticipated booklives up to its full year of advance buzz. The metaphoris of an architect’s
`pattern bookfilled with time-tested, usable designs. The authors have chosen 23 patterns from decades of
`object-oriented experience. The brilliance of the booklies in the discipline represented by that number.
`Give a copy of Design Patterns to every good programmer you know who wantsto 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 applyingits “patterns” to produce better software. This book delivers inteliectual
`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 WhatIsa Design Pattern? .... 2... 2.0.02 eee eee ee eee
`1.2 Design Patterns in SmalltakkMVC .......-.. 0... 0050 0G,
`13 Describing Design Patterns . 1... 1 ee es
`1.4 The Catalog of Design Patterns ......... 2.00. 022 eee eee
`15 Organizing theCatalog .. 1... . 0. ee ee ee ee
`1.6 How Design Patterns Solve Design Problems ......-.........
`1.7 Howto Selecta Design Pattern .. 2... 1. ee ee ee ee ee
`
`18 Howto Usea Design Patten ... 2.1.2.2... 2.0.0.
`
`.2.0 0020005
`
`2 A Case Study: Designing a DocumentEditor
`
`2.1 DesignProblems ... 1... 0. eee eee ee ee te ee ee
`
`2.2 Document Structure... 2.2.2... ee ee ees
`
`2.3 Formatting 2... ee ee ee
`2.4 Embellishing the User Interface... 2... ee ee -
`2.9 Supporting Multiple Look-and-Feel Standards ............0.4.
`2.6 Supporting Multiple Window Systems...............-255-
`2.7 UserOperations 2.0... ee ee ee ee es ‘
`2.8 Spelling Checking and Hyphenation..............0..0..
`
`Vii
`
`11
`
`xi
`
`xiii
`
`OoOoDOfFNm
`
`11
`
`28
`
`29
`
`33
`
`33
`
`35
`
`40
`
`43
`
`47
`
`51
`
`58
`
`64
`
`11
`
`
`
`viii
`
`CONTENTS
`
`2.9 Summary . 0... eee et ee ete ee ee ee ees 76
`
`Design Pattern Catalog
`
`3 Creational Patterns
`
`79
`
`81
`
`6 00ee ee ee ee es 87
`Abstract Factory .
`Builder 2... ee te te ee ee es 97
`
`Factory Method 2... 2. cc ee ee ee 107
`Prototype 2.0... ee ee te ee ees 117
`Singleton 2... ee ee ee eee eee eee 127
`
`Discussion of Creational Patterns... 2... ee ee 135
`
`4 Structural Patterns
`
`137
`
`Adapter... 6c ee ee es 139
`Bridge 20. ee ee ee ee ees 151
`Composite 6... ee ee ee eee teens 163
`Decorator 2... ee ee ee es 175
`
`Facade... 6. ee ee ee ee eet eee ees 185
`
`Flyweight... 0.6 ee ee ee te teens 195
`PYOXY 2c ee ee ee et ee ee ee eee 207
`
`Discussion of Structural Patterns 2.0... te ew 219
`
`221
`_
`5 Behavioral Patterns
`Chain of Responsibility 2... 1. ee ee meee 223
`Command... eee eee 233
`
`Interpreter 266 ee ee eee 243
`Iterator ww ee ee we ee eee ees 257
`
`Mediator 2.1... ce ee ee eee eee ee ee ee ee ee es 273
`
`Memento . 0... ee ee ee eee ee ee ee ee ees 283
`
`Observer 2... . ee ee ee ee ee ee ee 293
`
`State... ee ee ee we ee ee ee ee ee 305
`
`Strategy 2... ee eee tee ee ee eee ees 315
`
`12
`
`12
`
`
`
`CONTENTS
`
`ix
`
`Template Method... 0. ee tt ee ee ee es 325
`Visitor 2. 0 ew te tw et et ee es 331
`
`Discussion of Behavioral Patterns... 2. ...0.0.0.0..0. 6000 eee eee 345
`
`6 Conclusion
`
`351
`
`6.1 What to Expect from Design Patterns... 6... 6 ee eee 351
`6.2 ABrief History... 0.6 ee ee ete ees 355
`6.3 The Pattern Community .......0.00 00. cee eee eee 356
`64 AnlInvitation ........ 00. ee ee ee te et te es 358
`
`6.5 AParting Thought .... 2... 2.0... ee ee eee eee 358
`
`A Glossary
`
`B Guide to Notation
`
`359
`
`363
`
`B.1 ClassDiagram 2... ee ee ee ee eee 363
`B.2 Object Diagram... 0. ee et ee ee 364
`B.3
`Interaction Diagram . 1... 1. ee es 366
`
`C Foundation Classes
`
`369
`
`Cl List 2... ew ee te ee ee ees 369
`
`C.2 Iterator 2... ee tt ee we te ee te eee te 372
`
`C3 Listlterator 2...wt tw ee we we es 372
`
`C4 Point... 0. ee tt ee we ee ee ee ee 373
`
`C5 Rect... 2... ee et ee ee ee ee ee 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 technicaltreatise 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
`andeasily applied form.
`The design patterns require neither unusual language features nor amazing program-
`ming tricks with which to astound yourfriends and managers. All can be implemented
`in standard object-oriented languages, though they mighttake a little more work than
`ad hoc solutions. But the extra effort invariably pays dividendsin increased flexibility
`and reusability.
`Once you understand the design patterns and have had an “Aha!” (and notjust 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 thefirst 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 understandit all on the first writing!
`Rememberthat 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 forinspiration.
`This book has had a long gestation. It has seen four countries, three of its authors’
`matriages, 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é
`Weinandfor 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 butcertainly not least, we thank everyoneon the Internet and points beyond who
`commented 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 Coplien, 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 Méssenbiock, 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 Codesections by sending the message “send design pattern
`source” to design-patterns-source@cs.uiuc.edu. And nowthere’s a Web page
`athttp: //st-www.cs.uiuc.edu/users/patterns/DPBook/DPBook. htmlfor
`late-breaking information and updates.
`
`Mountain View, California
`Montreal, Quebec
`
`Urbana, Illinois
`
`Hawthorne, New York
`
`August 1994
`
`E.G.
`R.H.
`
`RJ.
`
`J.V.
`
`16
`
`16
`
`
`
`This page intentionally left blank
`
`17
`
`
`
`
`
`OBSERVER
`
`293
`
`OBSERVER
`
`Object Behavioral
`
`
`
`Intent
`
`Define a one-to-many dependency between objects so that when one object
`changesstate,all its dependentsare notified and updated automatically.
`
`Also Known As
`
`Dependents, Publish-Subscribe
`
`Motivation
`
`A commonside-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 theclasses 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, WGM88]. 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.
`
` ——e§3change notification
`
`—-——-»
`
`fequests, modifications
`
`observers
`
`subject
`
`18
`
`18
`
`
`
`294
`
`BEHAVIORAL PATTERNS
`
`CHAPTER 5
`
`This behavior implies that the spreadsheet and bar chart are dependenton the
`data object and therefore should be notified of any change inits state. And there’s
`no reason to limit the number of dependent objects to two; there may be any
`numberof different user interfaces to the samedata.
`
`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 dependentobservers. All observers are notified wheneverthe subject undergoes
`a changein 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 subjectis the
`publisherof notifications. It sends out these notifications without having to know
`whoits observers are. Any numberof observers can subscribe to receive notifica-
`tions.
`
`Applicability
`Use the Observer pattern in any of the following situations:
`
`e Whenan abstraction has two aspects, one dependent on the other. Encapsu-
`lating these aspects in separate objects lets you vary and reuse them inde-
`pendently.
`
`e When a changeto one object requires changing others, and you don’t know
`how manyobjects need to be changed.
`
`e When anobject should be able to notify other objects without making as-
`sumptions about whothese objects are. In other words, you don’t wantthese
`objects tightly coupled.
`
`Structure
`
`
`
`
`subject—>GetState(}
`ConcreteSubject
`
`GetState.) O---F-
`SetState()
`
`
`
`Updaie()
`
`fr
`
`observerState =
`
`
`
`
`
`
`Attach(Observer)
`
`Detach(Observer)
`
`
`Notify) o-----4--
`
`
`for all o in observers { Sy
`o->Update()
`}
`
`subjectState
`
`19
`
`19
`
`
`
`OBSERVER
`
`295
`
`Participants
`
`e Subject
`
`— knowsits observers. Any numberof Observer objects may observe a sub-
`ject.
`
`~ provides an interface for attaching and detaching Observerobjects.
`
`e Observer
`
`— defines an updatinginterface for objects that should be notified of changes
`in a subject.
`
`e ConcreteSubject
`
`— stores state of interest to ConcreteObserver objects.
`
`- sends a notification to its observers when its state changes.
`
`e 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
`
`e ConcreteSubject notifies its observers whenever a change occurs that could
`makeits observers’ state inconsistent with its own.
`e After being informed of a change in the concrete subject, a ConcreteObserver
`object may query the subject for information. ConcreteObserveruses 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()
`
`SetState()
`
`20
`
`20
`
`
`
`296
`
`BEHAVIORAL PATTERNS
`
`CHAPTER 5
`
`Note how the Observerobject that initiates the change request postponesits
`update until it gets a notification from the subject. Notify is not alwayscalled
`by the subject. It can be called by an observer or by another kind of object
`entirely. The Implementation section discusses some commonvariations.
`
`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 andliabilities of the Observer pattern include the following:
`
`1. Abstract coupling between Subject and Observer. All a subject knowsis thatit
`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. IfSubject and Observer are lumped together, then the result-
`ing object must either span twolayers (and violate the layering), or it must be
`forced to live in one layer or the other (which might compromisethe 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 manyinterested 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 observerto 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 innocuousoperation onthe subject may cause a cascade of updates
`to observers and their dependent objects. Moreover, dependencycriteria 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
`discussedin 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 whenthere are
`many subjects and few observers. Onesolution 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 somesituations 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 passitself as a parameter
`in the Update operation, thereby letting the observer know which subject to
`examine.
`
`3. Whotriggers the update? The subject andits observersrely on the notification
`mechanism to stay consistent. But whatobject 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 approachis that clients don’t
`have to rememberto call Notify on the subject. The disadvantageis that
`several consecutive operations will cause several consecutive updates,
`which may beinefficient.
`
`(b) Makeclients responsible for calling Notify at the right time. The advan-
`tage hereis 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 disadvantageis that clients have an added responsibility
`to trigger the update. That makes errors more likely, since clients might
`forget to cali 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
`ownState.
`
`This self-consistency rule is easy to violate unintentionally when Subject
`subclass operationscall inherited operations. For example, the notification in
`
`22
`
`22
`
`
`
`298
`
`BEHAVIORAL PATTERNS
`
`CHAPTER 5
`
`the following code sequenceis trigged when the subjectis in an inconsistent
`state:
`
`{
`void MySubject::Operation (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 amountof information may vary widely.
`At one extreme, which wecall the push model, the subject sends observers
`detailed information about the change, whether they wantit or not. At the
`other extreme is the pull model; the subject sends nothing but the most
`minimalnotification, and observers ask for details explicitly thereafter.
`The pull model emphasizes the subject’s ignoranceof 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 Observerclasses that might not always be
`true. On the other hand, the pull model maybeinefficient, because Observer
`classes must ascertain what changed without help from the Subject.
`
`7. Specifying modificationsof interest explicitly. You can improve updateefficiency
`by extendingthe subject’s registration interface to allow registering observers
`only for specific events of interest. When such an event occurs, the subject
`informs only those observers that haveregistered interest in that event. One
`way to supportthis uses the notion of aspects for Subject objects. To register
`interest in particular events, observers are attached to their subjects using
`
`void Subject: :Attach(Observer*, Aspect& interest);
`
`23
`
`23
`
`
`
`OBSERVER
`
`299
`
`where interest specifies the event of interest. At notification time, the
`subject supplies the changed aspect to its observers as a parameter to the
`Update operation. For example:
`
`void Observer: :Update(Subject*, Aspect& interest);
`
`. Encapsulating complex update semantics. When the dependency relationship
`between subjects and observersis particularly complex, an object that main