0% found this document useful (0 votes)
15 views90 pages

Douglas C. Schmidt: Vanderbilt University

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views90 pages

Douglas C. Schmidt: Vanderbilt University

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 90

An Introduction to Design

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)

Part II: Application


 use patterns to design a document
editor
 demonstrate usage & benefits

Part III: Wrap-Up


 observations, caveats, & conclusion

3
Part I: Motivation &
Concept
OOD methods emphasize design notations
Fine for specification, documentation

But OOD is more than just drawing diagrams


Good draftsmen  good designers

Good OO designers rely on lots of experience


At least as important as syntax

Most powerful reuse is design reuse


Match problem to design experience

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

Language- & implementation-independent


A “micro-architecture”
Adjunct to existing methodologies (RUP, Fusion,
SCRUM, etc.)
7
Part I: Motivation & Concept (cont’d)
Example: OBSERVER

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

Scope: domain over which a pattern applies


Purpose: reflects what a pattern does
10
Design Pattern Template (1st
half)
NAME scope
purpose
Intent
short description of the pattern & its purpose
Also Known As
Any aliases this pattern is known by
Motivation
motivating scenario demonstrating pattern’s use
Applicability
circumstances in which pattern applies
Structure
graphical representation of the pattern using modified UML
notation
Participants
participating classes and/or objects & their responsibilities 11
Part I: Motivation & Concept (cont’d)
Design Pattern Template (2nd
half)
...

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);
}

class MyPushConsumer : public // ….


virtual void push
(const CORBA::Any &event) { /* consume the 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 void insert(Glyph)


void remove(Glyph)
Glyph child(int n)
Glyph parent()

Subclasses: Character, Image, Space, Row,


Column 23
Document Structure (cont’d)
Glyph Hierarchy

Note the inherent recursion in this hierarchy


 i.e., a Row is a Glyph & a Row also has Glyphs!
24
Document Structure (cont’d)
COMPOSITE object
structural
Intent
treat individual objects & multiple, recursively-composed
objects uniformly
Applicability
objects must be composed recursively,
and no distinction between individual & composed elements,
and objects in structure can be treated uniformly

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

class Character : public Glyph { class Row : public Glyph {


public: public:
Character Row (std::vector<Glyph*> children);
(const std::string &name); // ...
// ... virtual void
virtual void draw (const Drawing_Region &c){
draw (const Drawing_Region &c) for
{ c.draw_text (x_, y_, name_); } (std::vector<Glyph*>::iterator
private: i (children_);
std::string name_; i != children_.end ();
}; i++)
(*i)->draw (c);
}
Leaf // ...
private:
std::vector<Glyph*> children_;
// ...
27
};
Document Structure (cont’d)
COMPOSITE object
structural
void list_context (CosNaming::NamingContext_ptr nc) {
CosNaming::BindingIterator_var it; // Iterator reference
CosNaming::BindingList_var bl; // Binding list
const CORBA::ULong CHUNK = 100; // Chunk size

nc->list (CHUNK, bl, it); // Get first chunk


show_chunk (bl, nc); // Print first chunk
if (!CORBA::is_nil(it)) { // More bindings?
while (it->next_n(CHUNK, bl)) // Get next chunk
show_chunk (bl, nc); // Print chunk
it->destroy(); // Clean up
}
}
void show_chunk (const CosNaming::BindingList_ptr &bl, // Helper function
CosNaming::NamingContext_ptr nc) {
for (CORBA::ULong i = 0; i < bl.length (); ++i) {
cout << bl[i].binding_name[0].id << "." << bl[i].binding_name[0].kind;

if (bl[i].binding_type == CosNaming::ncontext) { Handle


cout << ": context" << endl; Composi
CORBA::Object_var obj = nc->resolve (bl[i].binding_name); te Node
list_context (CosNaming::NamingContext::_narrow (obj));
}
else cout << ": reference" << endl; Handle
} Leaf
28
} Node
Document Structure (cont’d)
COMPOSITE (cont’d) object
structural
Consequences
+ uniformity: treat components the same regardless of complexity
+ extensibility: new Component subclasses work wherever old ones do
– overhead: might need prohibitive numbers of objects
Implementation
 do Components know their parents?
 uniform interface for both leaves & composites?
 don’t allocate storage for children in Component base class
 responsibility for deleting children
Known Uses
 ET++ Vobjects
 InterViews Glyphs, Styles
 Unidraw Components, MacroCommands
 Directory structures on UNIX & Windows
 Naming Contexts in CORBA
 MIME types in SOAP
29
Formatting
Goals:
 automatic linebreaking, justification

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

Hook for the


Hook for the
connection
concurrency
management
strategy
strategy

Hook for the


underlying
transport
strategy

Strategy can also be applied in distributed systems (e.g.,35


Formatting (cont’d)
STRATEGY (cont’d) object
behavioral
Consequences
+ greater flexibility, reuse
+ can change algorithms dynamically
– strategy creation & communication overhead
– inflexible Strategy interface
– semantic incompatibility of multiple strategies used together
Implementation
 exchanging information between a Strategy & its context
 static strategy selection via parameterized types
Known Uses
 InterViews text formatting
 RTL register allocation & scheduling strategies
 ET++SwapsManager calculation engines
 The ACE ORB (TAO) Real-time CORBA middleware
See Also
 Bridge pattern (object structural)
36
Formatting (cont’d)
Template Method (cont’d) class
behavioral
Intent
 Provide a skeleton of an algorithm in a method, deferring some
steps to subclasses
class Composition : public Glyph {
public:
// Template Method.
void perform_composition (const std::vector<Glyphs*> &leaf_glyphs) {
set_context (*this);
for (std::vector<Glyph*>::iterator i (leaf_glyphs);
i != leaf_glyphs.end (); i++) {
insert (*i);
compose ();
}
}
virtual void compose () = 0; // Hook Method.
};

class Simple_Composition : public Composition {


virtual void compose () { /* ... */ }
};

class Tex_Composition : public Composition {


virtual void compose () { /* ... */ }
}; 37
Formatting (cont’d)
Template Method (cont’d) class
behavioral
Intent
 Provide a skeleton of an algorithm in a method, deferring some
steps to subclasses
class Base_Class {
public:
// Template Method.
void template_method (void) {
hook_method_1 ();
hook_method_2 ();
// ...
}
virtual void hook_method_1 () = 0;
virtual void hook_method_2 () = 0;
};

class Derived_Class_1 : public Base_Class {


virtual void hook_method_2 () { /* ... */ }
};

class Derived_Class_2 : public Base_Class {


virtual void hook_method_1 () { /* ... */ }
virtual void hook_method_2 () { /* ... */ }
};
38
Embellishment
Goals:
 add a frame around text composition
 add scrolling capability

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

void Frame::draw (Window &w) {


// Order may be important!
void MonoGlyph::draw (Window &w) { MonoGlyph::draw (w);
component->draw (w); drawFrame (w);
} } 41
Embellishment (cont’d)
New Object Structure

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 ();

// ... process the request


}

ACE_Thread_Mutex m;
size_t request_count;

void *worker_task (void *) {


{
ACE_Guard <ACE_Thread_Mutex> g (m);
request_count++;
}

// ... process the request


}

44
Embellishment (cont’d)
DECORATOR object
structural
Atomic_Op<size_t, ACE_Thread_Mutex> request_count;

void *worker_task (void *) {


request_count++;

// ... process the request


}

template <typename T, typename LOCK>


class Atomic_Op {
public:
void operator++ () {
ACE_Guard <LOCK> g (m_);
count_++;
// ...
}
private:
T count_;
LOCK m_;
};

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();

where factory is an instance of MotifFactory


• BTW, this begs the question of who created the
factory!

48
Multiple Look & Feels (cont’d)
Factory Interface
• defines “manufacturing interface”
• subclasses produce specific products
• subclass instance chosen at run-time

// This class is essentially a Java interface


class GUIFactory {
public:
virtual Scrollbar *createScrollbar() = 0;
virtual Menu *createMenu() = 0;
...
}; 49
Multiple Look & Feels (cont’d)
Factory Structure

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

Concrete factories create groups of strategies


52
Multiple Look & Feels (cont’d)
ABSTRACT FACTORY (cont’d) object
creational
Consequences
+ flexibility: removes type (i.e., subclass) dependencies from
clients
+ abstraction & semantic checking: hides product’s composition
– hard to extend factory interface to create new products
Implementation
 parameterization as a way of controlling interface size
 configuration with Prototypes, i.e., determines who creates the
factories
 abstract factories are essentially groups of factory methods
Known Uses
 InterViews Kits
 ET++ WindowSystem
 AWT Toolkit
 The ACE ORB (TAO) 53
Multiple Window Systems
Goals:
 make composition appear in a window
 support multiple window systems

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)

An Abstract Factory can


produce the right
WindowRep!
57
Multiple Window Systems (cont’d)
Window/WindowRep
Structure

void Character::draw (Window &w) {


w.drawText(...);
}
void Window::drawText (...) {
rep->deviceText(...);
}
void XWindowRep::deviceText (...) {
XText(...);
} 58
Multiple Window Systems (cont’d)
New Object Structure

Note the decoupling


between the logical
structure of the
contents in a window
from the physical
rendering of the
contents in the
window

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

past futur past future 65


e
User Operations (cont’d)
COMMAND object
behavioral
Intent
encapsulate the request for a service
Applicability
 to parameterize objects with an action to perform
 to specify, queue, & execute requests at different times
 for multilevel undo/redo

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)

void Character::accept (Visitor &v) { v.visit (*this); }

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...

class HyphenationVisitor : public Visitor {


public:
void visit (Character &);
void visit (Rectangle &);
void visit (Row &);
// etc. for all relevant Glyph
subclasses
};
77
Spelling Checking & Hyphenation (cont’d)
Discretionary Glyph
• looks like a hyphen when at end of a line
• has no appearance otherwise
• Compositor considers its presence when determining linebreaks

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;

for (Glyph::iterator i = glyphs.begin ();


i != glyphs.end ();
i++) {
(*i)->accept (spell_check_visitor);
}

HyphenationVisitor hyphenation_visitor;

for (Glyph::iterator i = glyphs.begin ();


i != glyphs.end ();
i++) {
(*i)->accept (hyphenation_visitor);
} 80
Spelling Checking & Hyphenation (cont’d)
VISITOR (cont’d) object
behavioral

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

Patterns permit design at a more abstract level


 treat many class/object interactions as a unit
 often beneficial after initial design
 targets for class refactorings

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…

Don’t apply them blindly


Added indirection can yield increased
complexity, cost

Resist branding everything a pattern


Articulate specific benefits
Demonstrate wide applicability
Find at least three existing examples from
code other than your own!

Pattern design even harder than OO design!


83
Part III: Wrap-Up (cont’d)
Concluding Remarks

• 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

See hillside.net/conferences/ for


up-to-the-minute info.

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

See http://hillside.net/patterns/mailing.htm for an up-to-date list.

90

You might also like