Douglas C. Schmidt: Vanderbilt University
Douglas C. Schmidt: Vanderbilt University
Patterns
Douglas C. Schmidt
Vanderbilt University
www.dre.vanderbilt.edu/~schmidt/gof.ppt
[email protected]
Based on material produced by John
Vlissides 1
Overview
Part I: Motivation & Concept
the issue
what design patterns are
what they’re good for
how we develop & categorize them
2
Overview (cont’d)
3
Part I: Motivation &
Concept
OOD methods emphasize design notations
Fine for specification, documentation
4
Part I: Motivation & Concept (cont’d)
Recurring Design Structures
OO systems exhibit recurring structures that
promote
abstraction
flexibility
modularity
elegance
Therein lies valuable design knowledge
Problem:
capturing, communicating, & applying this
knowledge 5
Part I: Motivation & Concept (cont’d)
A Design Pattern…
• abstracts a recurring design structure
• comprises class and/or object
dependencies
structures
interactions
conventions
• names & specifies the design structure
explicitly
• distills design experience
6
Part I: Motivation & Concept (cont’d)
Four Basic Parts
1. Name
2. Problem (including “forces”)
3. Solution
4. Consequences & trade-offs of application
8
Part I: Motivation & Concept (cont’d)
Goals
Codify good design
distill & generalize experience
aid to novices & experts alike
Give design structures explicit names
common vocabulary
reduced complexity
greater expressiveness
Capture & preserve design information
articulate design decisions succinctly
improve documentation
Facilitate restructuring/refactoring
patterns are interrelated
additional flexibility
9
Part I: Motivation & Concept (cont’d)
Design Space for GoF
Patterns
Collaborations
how participants cooperate to carry out their responsibilities
Consequences
the results of application, benefits, liabilities
Implementation
pitfalls, hints, techniques, plus language-dependent issues
Sample Code
sample implementations in C++, Java, C#, Smalltalk, C, etc.
Known Uses
examples drawn from existing systems
Related Patterns
discussion of other patterns that relate to this one
12
Part I: Motivation & Concept (cont’d)
Modified UML/OMT Notation
13
Motivation & Concept (cont’d)
OBSERVER object
behavioral
Intent
define a one-to-many dependency between objects so that when
one object changes state, all dependents are notified & updated
Applicability
an abstraction has two aspects, one dependent on the other
a change to one object requires changing untold others
an object should notify unknown other objects
Structur
e
14
Motivation & Concept (cont’d)
OBSERVER object
behavioral
class ProxyPushConsumer : public // …
virtual void push (const CORBA::Any &event) {
for (std::vector<PushConsumer>::iterator i
(consumers.begin ()); i != consumers.end (); i++)
(*i).push (event);
}
CORBA Notification
Service example using
C++ Standard Template
Library (STL) iterators
(which is an example of
the Iterator pattern
from GoF)
15
Motivation & Concept (cont’d)
OBSERVER (cont’d) object
behavioral
Consequences
+ modularity: subject & observers may vary independently
+ extensibility: can define & add any number of observers
+ customizability: different observers offer different views of subject
– unexpected updates: observers don’t know about each other
– update overhead: might need hints or filtering
Implementation
subject-observer mapping
dangling references
update protocols: the push & pull models
registering modifications of interest explicitly
Known Uses
Smalltalk Model-View-Controller (MVC)
InterViews (Subjects & Views, Observer/Observable)
Andrew (Data Objects & Views)
Pub/sub middleware (e.g., CORBA Notification Service, Java Messaging Service)
Mailing lists
16
Part I: Motivation & Concept (cont’d)
Benefits of Patterns
• Design reuse
• Uniform design vocabulary
• Enhance understanding, restructuring, &
team communication
• Basis for automation
• Transcends language-centric
biases/myopia
• Abstracts away from many unimportant
details
17
Part I: Motivation & Concept (cont’d)
Liabilities of Patterns
• Require significant tedious & error-
prone human effort to handcraft pattern
implementations design reuse
• Can be deceptively simple uniform
design vocabulary
• May limit design options
• Leaves some important details
unresolved
18
Part II: Application:
Document Editor (Lexi)
7 Design Problems
1. Document structure
2. Formatting
3. Embellishment
4. Multiple look & feels
5. Multiple window systems
6. User operations
7. Spelling checking &
hyphenation
19
Note that none of these patterns are restricted to document
Document Structure
Goals:
present document’s visual aspects
drawing, hit detection, alignment
support physical structure
(e.g., lines, columns)
Constraints/forces:
treat text & graphics uniformly
no distinction between one & many
20
Document Structure (cont’d)
Solution: Recursive
Composition
21
Document Structure (cont’d)
Object Structure
22
Document Structure (cont’d)
Glyph
Base class for composable graphical objects
Basic interface:
Task Operations
appearance void draw(Window)
hit detection boolean intersects(Coord, Coord)
Structure e.g.,
Glyph
e.g., e.g.,
Character, Row,
Rectangle, Column
etc.
25
Document Structure (cont’d)
COMPOSITE object
structural
Leaf
Composi Node
te Node
CORBA Naming Service example using
CosNaming::BindingIterator (which is an
example of the “Batch Iterator” pattern
compound from POSA5)
26
Document Structure (cont’d)
COMPOSITE object
structural
class Glyph { Compone
public: nt
virtual void
draw (const Drawing_Region &) = 0;
// ...
protected:
int x_, y_; // Coordinate position. Composit
}; e
Constraints/forces:
support multiple linebreaking
algorithms
don’t tightly couple these algorithms
with the document structure
30
Formatting (cont’d)
Solution: Encapsulate Linebreaking
Strategy
Compositor
base class abstracts linebreaking algorithm
subclasses for specialized algorithms,
e.g., SimpleCompositor, TeXCompositor
Composition
composite glyph (typically representing a
column)
supplied a compositor & leaf glyphs
creates row-column structure as directed by
compositor
31
Formatting (cont’d)
New Object Structure
Generated in accordance
with compositor strategies
& do not affect contents of
leaf glyphs
32
Formatting (cont’d)
STRATEGY object
behavioral
Intent
define a family of algorithms, encapsulate each one, & make them
interchangeable to let clients & algorithms vary independently
Applicability
when an object should be configurable with one of many algorithms,
and all algorithms can be encapsulated,
and one interface covers all encapsulations
Structure
33
Formatting (cont’d)
STRATEGY object
behavioral
class Composition : public Glyph {
public:
void perform_composition (const Compositor &compositor,
const std::vector<Glyphs*> &leaf_glyphs) {
compositor.set_context (*this);
for (std::vector<Glyph*>::iterator Simple
i (leaf_glyphs); algorith
creates i != leaf_glyphs.end (); m
i++) {
row- class SimpleCompositor
this->insert (*i);
column : public Compositor {
compositor.compose (); public:
structure
} virtual void compose ()
as } { /* ... */}
directed
}; };
by Complex
composito algorith
r Compositor
class { class TexCompositor m
public:
: public Compositor {
void set_context
(Composition &context); public:
virtual void compose () = 0; virtual void compose () { /* ... */}
// ... }; 34
};
Formatting (cont’d)
STRATEGY object
behavioral
Hook for
marshaling Hook for
strategy the request
demuxing
Hook for the event strategy
demuxing strategy
Constraints/forces:
embellishments should be reusable
without subclassing, i.e., so they can be
added dynamically at runtime
should go unnoticed by clients
39
Embellishment (cont’d)
Solution: “Transparent”
Enclosure
Monoglyph
base class for glyphs having one child
operations on MonoGlyph (ultimately) pass
through to child
MonoGlyph subclasses:
Frame: adds a border of specified width
Scroller: scrolls/clips child, adds scrollbars
40
Embellishment (cont’d)
MonoGlyph Hierarchy
42
Embellishment (cont’d)
DECORATOR object
structural
Intent
Transparently augment objects with new responsibilities dynamically
Applicability
when extension by subclassing is impractical
for responsibilities that can be added & withdrawn dynamically
Structur
e
43
Embellishment (cont’d)
DECORATOR object
structural
size_t request_count; ACE_Thread_Mutex m;
size_t request_count;
void *worker_task (void *) {
request_count++; void *worker_task (void *) {
m.acquire ();
// ... process the request request_count++;
} m.release ();
ACE_Thread_Mutex m;
size_t request_count;
44
Embellishment (cont’d)
DECORATOR object
structural
Atomic_Op<size_t, ACE_Thread_Mutex> request_count;
45
Embellishment (cont’d)
DECORATOR (cont’d) object
structural
Consequences
+ responsibilities can be added/removed at run-time
+ avoids subclass explosion
+ recursive nesting allows multiple responsibilities
– interface occlusion
– identity crisis
– composition of decorators is hard if there are side-effects
Implementation
interface conformance
use a lightweight, abstract base class for Decorator
heavyweight base classes make Strategy more attractive
Known Uses
embellishment objects from most OO-GUI toolkits
ParcPlace PassivityWrapper
InterViews DebuggingGlyph
Java I/O classes
ACE_Atomic_Op
46
Multiple Look & Feels
Goals:
support multiple look & feel standards
generic, Motif, Swing, PM, Macintosh,
Windows, ...
extensible for future standards
Constraints/forces:
don’t recode existing widgets or clients
switch look & feel without recompiling
47
Multiple Look & Feels (cont’d)
Solution: Abstract Object
Creation
Instead of
MotifSrollbar *sb = new MotifScrollbar();
use
Scrollbar *sb = factory->createScrollbar();
48
Multiple Look & Feels (cont’d)
Factory Interface
• defines “manufacturing interface”
• subclasses produce specific products
• subclass instance chosen at run-time
Scrollbar *MotifFactory::createScrollBar () {
return new MotifScrollbar();
}
Scrollbar *PMFactory::createScrollBar () {
return new PMScrollbar();
} 50
Multiple Look & Feels (cont’d)
ABSTRACT FACTORY object
creational
Intent
create families of related objects without specifying subclass names
Applicability
when clients cannot anticipate groups of classes to instantiate
Structur
e
51
Multiple Look & Feels (cont’d)
ABSTRACT FACTORY object
creational
Constraints/forces:
minimize window system dependencies
in application & framework code
54
Multiple Window Systems (cont’d)
Solution: Encapsulate Implementation
Dependencies
Window
user-level window abstraction
displays a glyph (structure)
window system-independent
task-related subclasses
(e.g., IconWindow, PopupWindow)
55
Multiple Window Systems (cont’d)
Window Interface
class Window {
public:
...
void iconify(); // window-management
void raise();
...
void drawLine(...); // device-independent
void drawText(...); // graphics interface
...
};
56
Multiple Window Systems (cont’d)
Window uses a WindowRep
• abstract implementation interface
• encapsulates window system
dependencies
• window systems-specific subclasses
(e.g., XWindowRep, SunWindowRep)
59
Multiple Window Systems (cont’d)
BRIDGE object
structural
Intent
separate a (logical) abstraction interface from its (physical)
implementation(s)
Applicability
when interface & implementation should vary independently
require a uniform interface to interchangeable class hierarchies
Structure
60
Multiple Window Systems (cont’d)
BRIDGE (cont’d) object
structural
Consequences
+ abstraction interface & implementation are
independent
+ implementations can vary dynamically
– one-size-fits-all Abstraction & Implementor interfaces
Implementation
sharing Implementors & reference counting
creating the right Implementor (often use factories)
Known Uses
ET++ Window/WindowPort
libg++ Set/{LinkedList, HashTable}
AWT Component/ComponentPeer
61
User Operations
Goals:
support execution of user operations
support unlimited-level undo/redo
Constraints/forces:
scattered operation implementations
must store undo state
not all operations are undoable
62
User Operations (cont’d)
Solution: Encapsulate Each
Request
A Command encapsulates
an operation (execute())
an inverse operation (unexecute())
a operation for testing reversibility
(boolean reversible())
state for (un)doing the operation
Command may
implement the operations itself, or
delegate them to other object(s)
63
User Operations (cont’d)
Command Hierarchy
void PasteCommand::execute ()
{
// do the paste
}
void CopyCommand::execute ()
{
// do the copy
}
void MenuItem::clicked ()
{
command->execute();
}
64
User Operations (cont’d)
List of Commands = Execution
History
unexecute() unexecute()
execute()
Undo Redo:
:
cmd cmd
Structur
e
66
User Operations (cont’d)
COMMAND (cont’d) object
behavioral
Consequences
+ abstracts executor of a service
+ supports arbitrary-level undo-redo
+ composition yields macro-commands
– might result in lots of trivial command subclasses
Implementation
copying a command before putting it on a history list
handling hysteresis
supporting transactions
Known Uses
InterViews Actions
MacApp, Unidraw Commands
JDK’s UndoableEdit, AccessibleAction
Emacs
67
Spelling Checking &
Hyphenation
Goals:
analyze text for spelling errors
introduce potential hyphenation sites
Constraints/forces:
support multiple algorithms
don’t tightly couple algorithms with
document structure
68
Spelling Checking & Hyphenation (cont’d)
Solution: Encapsulate Traversal
Iterator
encapsulates a
traversal algorithm
without exposing
representation details
to callers
uses Glyph’s child
enumeration operation
This is an example of a
“preorder iterator”
69
Spelling Checking & Hyphenation (cont’d)
ITERATOR object
behavioral
Intent
access elements of a container without exposing its representation
Applicability
require multiple traversal algorithms over a container
require a uniform traversal interface over different containers
when container classes & traversal algorithm must vary
independently
Structure
70
Spelling Checking & Hyphenation (cont’d)
ITERATOR (cont’d) object
behavioral
Iterators are used heavily in the C++ Standard
Template Library (STL)
int main (int argc, char *argv[]) {
vector<string> args;
for (int i = 0; i < argc; i++)
args.push_back (string (argv[i]));
for (vector<string>::iterator i (args.begin ());
i != args.end ();
i++)
cout << *i;
cout << endl; The same iterator pattern
return 0; can be applied to any STL
} container!
for (Glyph::iterator i = glyphs.begin ();
i != glyphs.end ();
i++)
... 71
Spelling Checking & Hyphenation (cont’d)
ITERATOR (cont’d) object
behavioral
Consequences
+ flexibility: aggregate & traversal are independent
+ multiple iterators & multiple traversal algorithms
– additional communication overhead between iterator & aggregate
Implementation
internal versus external iterators
violating the object structure’s encapsulation
robust iterators
synchronization overhead in multi-threaded programs
batching in distributed & concurrent programs
Known Uses
C++ STL iterators
JDK Enumeration, Iterator
Unidraw Iterator
72
Spelling Checking & Hyphenation (cont’d)
Visitor
• defines action(s) at each step of traversal
• avoids wiring action(s) into Glyphs
• iterator calls glyph’s accept(Visitor) at each node
• accept() calls back on visitor (a form of “static polymorphism”
based on method overloading by type)
class Visitor {
public:
virtual void visit (Character &);
virtual void visit (Rectangle &);
virtual void visit (Row &);
// etc. for all relevant Glyph subclasses
73
};
Spelling Checking & Hyphenation (cont’d)
SpellingCheckerVisitor
• gets character code from each character glyph
Can define getCharCode() operation just on
Character() class
• checks words accumulated from character
glyphs
•class
combine with PreorderIterator
SpellCheckerVisitor : public Visitor {
public:
virtual void visit (Character &);
virtual void visit (Rectangle &);
virtual void visit (Row &);
// etc. for all relevant Glyph
subclasses
Private:
74
std::string accumulator_;
Spelling Checking & Hyphenation (cont’d)
Accumulating Words
Spelling check
performed when a
nonalphabetic
character it
reached 75
Spelling Checking & Hyphenation (cont’d)
Interaction Diagram
• The iterator controls the order in which accept() is called on
each glyph in the composition
• accept() then “visits” the glyph to perform the desired
action
• The Visitor can be subclassed to implement various desired
actions
76
Spelling Checking & Hyphenation (cont’d)
HyphenationVisitor
• gets character code from each character glyph
• examines words accumulated from character glyphs
• at potential hyphenation point, inserts a...
78
Spelling Checking & Hyphenation (cont’d)
VISITOR object
behavioral
Intent
centralize operations on an object structure so that they can
vary independently but still behave polymorphically
Applicability
when classes define many unrelated operations
class relationships of objects in the structure rarely change,
but the operations on them change often
algorithms keep state that’s updated during traversal
Structur
e
79
Spelling Checking & Hyphenation (cont’d)
VISITOR (cont’d) object
behavioral
SpellCheckerVisitor spell_check_visitor;
HyphenationVisitor hyphenation_visitor;
Consequences
+ flexibility: visitor & object structure are independent
+ localized functionality
– circular dependency between Visitor & Element interfaces
– Visitor brittle to new ConcreteElement classes
Implementation
double dispatch
general interface to elements of object structure
Known Uses
ProgramNodeEnumerator in Smalltalk-80 compiler
IRIS Inventor scene rendering
TAO IDL compiler to handle different backends
81
Part III: Wrap-Up
Observations
Patterns are applicable in all stages of the OO lifecycle
analysis, design, & reviews
realization & documentation
reuse & refactoring
Variation-oriented design
consider what design aspects are variable
identify applicable pattern(s)
vary patterns to evaluate tradeoffs
repeat
82
Part III: Wrap-Up (cont’d)
But…
• design reuse
• uniform design vocabulary
• understanding, restructuring, &
team communication
• provides the basis for automation
• a “new” way to think about design
84
Pattern References
Books
Timeless Way of Building, Alexander, ISBN 0-19-502402-8
A Pattern Language, Alexander, 0-19-501-919-9
Design Patterns, Gamma, et al., 0-201-63361-2 CD version 0-201-63498-8
Pattern-Oriented Software Architecture, Vol. 1, Buschmann, et al.,
0-471-95869-7
Pattern-Oriented Software Architecture, Vol. 2, Schmidt, et al.,
0-471-60695-2
Pattern-Oriented Software Architecture, Vol. 3, Jain & Kircher,
0-470-84525-2
Pattern-Oriented Software Architecture, Vol. 4, Buschmann, et al.,
0-470-05902-8
Pattern-Oriented Software Architecture, Vol. 5, Buschmann, et al.,
0-471-48648-5
85
Pattern References (cont’d)
More Books
Analysis Patterns, Fowler; 0-201-89542-0
Concurrent Programming in Java, 2nd ed., Lea, 0-201-31009-0
Pattern Languages of Program Design
Vol. 1, Coplien, et al., eds., ISBN 0-201-60734-4
Vol. 2, Vlissides, et al., eds., 0-201-89527-7
Vol. 3, Martin, et al., eds., 0-201-31011-2
Vol. 4, Harrison, et al., eds., 0-201-43304-4
Vol. 5, Manolescu, et al., eds., 0-321-32194-4
AntiPatterns, Brown, et al., 0-471-19713-0
Applying UML & Patterns, 2nd ed., Larman, 0-13-092569-1
Pattern Hatching, Vlissides, 0-201-43293-5
The Pattern Almanac 2000, Rising, 0-201-61567-3 86
Pattern References (cont’d)
Even More Books
Small Memory Software, Noble & Weir, 0-201-59607-5
Microsoft Visual Basic Design Patterns, Stamatakis, 1-572-
31957-7
Smalltalk Best Practice Patterns, Beck; 0-13-476904-X
The Design Patterns Smalltalk Companion, Alpert, et al.,
0-201-18462-1
Modern C++ Design, Alexandrescu, ISBN 0-201-70431-5
Building Parsers with Java, Metsker, 0-201-71962-2
Core J2EE Patterns, Alur, et al., 0-130-64884-1
Design Patterns Explained, Shalloway & Trott, 0-201-71594-5
The Joy of Patterns, Goldfedder, 0-201-65759-7
The Manager Pool, Olson & Stimmel, 0-201-72583-5
87
Pattern References (cont’d)
Early Papers
“Object-Oriented Patterns,” P. Coad; Comm. of the ACM,
9/92
“Documenting Frameworks using Patterns,” R. Johnson;
OOPSLA ’92
“Design Patterns: Abstraction & Reuse of Object-Oriented
Design,” Gamma, Helm, Johnson, Vlissides, ECOOP ’93
Articles
Java Report, Java Pro, JOOP, Dr. Dobb’s Journal,
Java Developers Journal, C++ Report
88
Pattern-Oriented Conferences
PLoP 2007: Pattern Languages of
Programs
October 2007, Collocated with OOPSLA
EuroPLoP 2007, July 2007, Kloster Irsee,
Germany
…
89
Mailing Lists
[email protected]: present & refine patterns
[email protected]: general discussion
[email protected]: discussion on Design
Patterns
[email protected]: discussion on
Pattern-Oriented Software Architecture
[email protected]: discussion on user interface patterns
[email protected]: discussion on patterns for
business processes
[email protected]: discussion on patterns for
distributed systems
90