Documente Academic
Documente Profesional
Documente Cultură
Douglas C. Schmidt
The following slides describe several case studies using C++ and
patterns to build highly extensible software
Douglas C. Schmidt
Professor
d.schmidt@vanderbilt.edu
www.cs.wustl.edu/schmidt/
Department of EECS
Vanderbilt University
(615) 343-8197
Vanderbilt University
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Douglas C. Schmidt
It sorts lines of text from standard input and writes the result to
standard output
e.g., the UNIX system sort
In the following, well examine the primary forces that shape the
design of this application
Vanderbilt University
Note, our program need not sort files larger than main memory
Vanderbilt University
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
High-level Forces
Douglas C. Schmidt
// Reusable function:
// template <class ARRAY> void sort (ARRAY &a);
int main (int argc, char *argv[])
{
parse_args (argc, argv);
Input_Array input;
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
Vanderbilt University
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
System
Sort
Options
GLOBAL
Sort
Line_Ptrs
Sort_AT
Adapter
ARRAY
Sort
TYPE
Access
Table
TACTICAL
COMPONENTS
TYPE
Stack
Tactical components
Stack
Used by non-recursive quick sort
Array
Stores/sorts pointers to lines and fields
Access Table
Used to store input
Input
Efficiently reads arbitrary sized input using only 1 dynamic
allocation and 1 copy
Sort_AT
Adapter
STRATEGIC
COMPONENTS
TYPE
Input
Array
Vanderbilt University
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
Douglas C. Schmidt
Strategic components
System Sort
integrates everything . . .
Sort AT Adapter
integrates the Array and the Access Table
Options
Manages globally visible options
Sort
e.g., both quicksort and insertion sort
Vanderbilt University
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
11
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Douglas C. Schmidt
ACCESS BUFFER
The input to the system sort can be arbitrarily large (e.g., up to 1/2
size of main memory)
Forces
ACCESS ARRAY
Solution
Create an Input class that reads arbitrary input efficiently
Vanderbilt University
12
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
13
14
// Size of buffer.
size_t size () const;
private:
// Recursive helper method.
char *recursive_read ();
// . . .
};
Vanderbilt University
15
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Facade
OO Pattern Examples
16
Douglas C. Schmidt
Bridge
Decouple an abstraction from its implementation so that the two
can vary independently
e.g., comparing two lines to determine ordering
Factory
Centralize the assembly of resources necessary to create an
object
e.g., decouple initialization of Line Ptrs used by Access Table
from their subsequent use
Vanderbilt University
OO Pattern Examples
Strategy
Singleton
Douglas C. Schmidt
18
Ensure a class has only one instance, and provide a global point
of access to it
e.g., provides a single point of access for the system sort facade
and for program options
Vanderbilt University
17
Douglas C. Schmidt
Iterator
Provide a way to access the elements of an aggregate object
sequentially without exposing its underlying representation
e.g., provides a way to print out the sorted lines without exposing
representation or initialization
Vanderbilt University
19
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Sort Algorithm
1. Non-recursive
Vanderbilt University
20
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
Problem
Forces
Solution
Use the Strategy pattern to select the pivot selection algorithm
Vanderbilt University
Intent
Define a family of algorithms, encapsulate each one, and make
them interchangeable
Strategy lets the algorithm vary independently from clients that
use it
Douglas C. Schmidt
21
OO Pattern Examples
Douglas C. Schmidt
Quicksort Optimizations
22
Vanderbilt University
23
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Context
Strategy
P i vot
Strategy
quick_sort
algorithm_interface()
context_interface()
Douglas C. Schmidt
get_pivot()
Concrete
Strategy A
Concrete
Strategy C
algorithm_interface()
algorithm_interface()
Select
First
Concrete
Strategy B
Random
Median
of
Three
algorithm_interface()
Vanderbilt University
OO Pattern Examples
24
Douglas C. Schmidt
Vanderbilt University
OO Pattern Examples
25
Douglas C. Schmidt
Vanderbilt University
26
Vanderbilt University
27
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Douglas C. Schmidt
Facade Pattern
Problem
Although the implementation of the sort function is complex, the
interface should be simple to use
Solution
Intent
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
Key forces
Complex interface are hard to use, error prone, and discourage
extensibility and reuse
Conceptually, sorting only makes a few assumptions about the
array it sorts
e.g., supports operator[] methods, size, and trait TYPE
We dont want to arbitrarily limit types of arrays we can sort
Use the Facade and Adapter patterns to simplify the sort program
Vanderbilt University
28
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
OO Pattern Examples
Douglas C. Schmidt
29
EXTERNALLY
VISIBLE
Facade
HIDDEN
ARRAY
Sort
HIDDEN
ARRAY
TYPE
Stack
Quick
Sort
ARRAY
Insert
Sort
Vanderbilt University
30
Vanderbilt University
31
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Intent
1: request ()
Douglas C. Schmidt
Target
client
request()
Vanderbilt University
32
OO Pattern Examples
Douglas C. Schmidt
Adapter
request()
Adaptee
2: specific_request()
Vanderbilt University
sort
ARRAY
"conforms to"
Line_P trs
Sort_AT_Adapter
typedef Line_P trs TYP E
make_table()
operator[]
size()
Vanderbilt University
ARRAY::
ARRAY::TYP
TYP E
operator[]
size()
1: ARRAY::TYPE t
= array[i]
Douglas C. Schmidt
Dynamic Array
"conforms to"
33
OO Pattern Examples
ARRAY
specific_request()
TYP E
Access_Table
make_table()
length()
element()
34
Vanderbilt University
35
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Vanderbilt University
36
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
37
OO Pattern Examples
Douglas C. Schmidt
Douglas C. Schmidt
struct Line_Ptrs {
// Comparison operator used by sort().
int operator< (const Line_Ptrs &) const;
class Sort_AT_Adapter :
// Note the use of the class form of the Adapter
private Access_Table<Line_Ptrs> {
public:
virtual int make_table (size_t num_lines, char *buffer);
typedef Line_Ptrs TYPE; // Type trait.
};
38
Vanderbilt University
39
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Problem
Key forces
Solution
Use the Singleton pattern to centralize option processing
Vanderbilt University
OO Pattern Examples
40
Douglas C. Schmidt
Intent
Ensure a class has only one instance, and provide a global point
of access to it
Vanderbilt University
41
OO Pattern Examples
Douglas C. Schmidt
if (unique_instance_ == 0)
unique_instance_ = new Singleton;
return unique_instance_;
Options
Singleton
static instance()
bool enabled()
field_offset()
static unique_instance_
options_
static instance()
singleton_operation()
get_singleton_data()
static unique_instance_
singleton_data_
Vanderbilt University
Douglas C. Schmidt
Singleton Pattern
42
Vanderbilt University
43
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Options Class
class Options
{
public:
static Options *instance ();
void parse_args (int argc, char *argv[]);
protected:
Options (); // Ensure Singleton.
Vanderbilt University
44
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
OO Pattern Examples
45
Douglas C. Schmidt
Problem
A multi-threaded program might have execute multiple copies of
sort in different threads
Key forces
Subtle race conditions can cause Singletons to be created multiple
times
Locking every access to a Singleton can be too costly
Solution
Use the Double-Checked Locking Optimization pattern to
efficiently avoid race conditions when initialization Singletons
}
Vanderbilt University
Douglas C. Schmidt
Options Class
46
Vanderbilt University
47
OO Pattern Examples
Douglas C. Schmidt
Douglas C. Schmidt
Intent
Ensures atomic initialization or access to objects and eliminates
unnecessary locking overhead
OO Pattern Examples
if (unique_instance_ == NULL) {
mutex_.acquire ();
if (unique_instance_ == NULL)
unique_instance_ = new Singleton;
mutex_.release ();
}
return unique_instance_;
Singleton
static instance()
static unique_instance_
Mutex
Vanderbilt University
OO Pattern Examples
48
Douglas C. Schmidt
OO Pattern Examples
49
Douglas C. Schmidt
Vanderbilt University
Vanderbilt University
50
Vanderbilt University
51
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Problem
Forces
Its better to determine the type of comparison operation during the
initialization phase
But the interface shouldnt change
Solution
Use the Bridge pattern to separate interface from implementation
Vanderbilt University
52
OO Pattern Examples
Intent
Decouple an abstraction from its implementation so that the two
can vary independently
Douglas C. Schmidt
This pattern resolves the following forces that arise when building
extensible software
1. How to provide a stable, uniform interface that is both closed and
open, i.e.,
Closed to prevent direct code changes
Open to allow extensibility
2. How to simplify the Line_Ptrs::operator< implementation
Vanderbilt University
Douglas C. Schmidt
1: method_impl()
Line_P trs
Implementor
1: compare()
Options
compare()
operator<
method_impl()
method()
53
OO Pattern Examples
Abstraction
Douglas C. Schmidt
Simplifying Comparisons
Concrete
ImplementorA
method_impl()
Concrete
ImplementorB
strcmp()
method_impl()
Vanderbilt University
54
Vanderbilt University
numcmp()
strcasecmp()
55
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Douglas C. Schmidt
Problem
How does the compare pointer-to-method get assigned?
int (*compare) (const char *left, const char *right);
Forces
There are many different choices for compare, depending on
which options are enabled
We only want to worry about initialization details in one place
Initialization details may change over time
Wed like to do as much work up front to reduce overhead later on
Solution
Use a Factory pattern to initialize the comparison operator
Vanderbilt University
56
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
OO Pattern Examples
Intent
Factory
make_product()
creates
Vanderbilt University
Douglas C. Schmidt
57
58
P roduct
Vanderbilt University
59
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Options
parse_args()
creates
initialize compare
Compare
Function
Vanderbilt University
OO Pattern Examples
Douglas C. Schmidt
60
Douglas C. Schmidt
Vanderbilt University
61
OO Pattern Examples
Douglas C. Schmidt
Problem
One of the nastiest parts of the whole system sort program is
initializing the Access Table
Key forces
We dont want initialization details to affect subsequent processing
Makes it easier to change initialization policies later on
e.g., using the Access Table in non-sort applications
Solution
Use the Factory Method pattern to initialize the Access Table
Vanderbilt University
62
Vanderbilt University
63
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Intent
Creator
Douglas C. Schmidt
factory_method() = 0
make_product()
P roduct
Vanderbilt University
64
OO Pattern Examples
Douglas C. Schmidt
Concrete
Creator
factory_method()
Concrete
P roduct
CREATES
Vanderbilt University
OO Pattern Examples
65
Douglas C. Schmidt
TYP E
Access Table
make_table() = 0
Sort AT
Adapter
Line P trs
make_table()
Vanderbilt University
}
66
Vanderbilt University
67
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Douglas C. Schmidt
The Access Table Factory class has a Factory Method that initializes
Sort AT Adapter
// Factory Method initializes Access_Table.
int Sort_AT_Adapter::make_table (size_t num_lines,
char *buffer)
{
// Array assignment op.
this->access_array_.resize (num_lines);
this->buffer_ = buffer; // Obtain ownership.
size_t count = 0;
Vanderbilt University
OO Pattern Examples
68
Douglas C. Schmidt
Vanderbilt University
OO Pattern Examples
Problem
Intent
Provide a way to access the elements of an aggregate object
sequentially without exposing its underlying representation
Wed like to initialize the Access Table without having to know the
input buffer is represented
Douglas C. Schmidt
Iterator Pattern
69
Key force
Solution
Line_Ptrs_Iter::Line_Ptrs_Iter
(char *buffer, size_t num_lines);
Vanderbilt University
70
Vanderbilt University
71
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Douglas C. Schmidt
Line_Ptrs Line_Ptrs_Iter::current_element () {
Line_Ptrs lp;
The Iterator pattern also provides a way to print out the sorted lines
without exposing representation
Vanderbilt University
OO Pattern Examples
72
Douglas C. Schmidt
Vanderbilt University
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
73
74
As before, well examine the key forces and discuss design patterns
that resolve the forces
Vanderbilt University
75
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Douglas C. Schmidt
Input_Array input;
Input_Array potential_sort;
Vanderbilt University
76
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
OO Pattern Examples
unsorted
13
15
18
13
sorted, but
not permuted
permuted, but
not sorted
sorted and
permuted
13
18
15
13
13
13
15
18
Vanderbilt University
Douglas C. Schmidt
Forces
Common Problems
77
78
Vanderbilt University
79
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Forces (contd)
Vanderbilt University
80
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
OO Pattern Examples
Vanderbilt University
81
Douglas C. Schmidt
Douglas C. Schmidt
Strategies
82
Vanderbilt University
83
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
High-level Algorithm
Douglas C. Schmidt
}
Vanderbilt University
84
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
OO Pattern Examples
Search
Struct
Hash
Table
TYPE
Binary
Search
Nodups
Vanderbilt University
TYPE
Range
Vector
Douglas C. Schmidt
TYPE
LONG
85
TYPE
Binary
Search
Dups
86
Vanderbilt University
87
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Strategy subclasses
// Note the template specialization
class Range_Vector :
public Search_Strategy<long>
{ typedef long TYPE; /* . . . */ };
// Factory Method
virtual Search_Strategy<typename ARRAY::TYPE> *
make_strategy (const ARRAY &);
};
Vanderbilt University
88
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
89
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
Douglas C. Schmidt
90
Factory Method
Vanderbilt University
91
Intent
Define an interface for creating an object, but let subclasses decide
which class to instantiate
Factory Method lets a class defer instantiation to subclasses
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
93
OO Pattern Examples
Douglas C. Schmidt
Search
Strategy
Creator
factory_method() = 0
make_product()
P roduct
Douglas C. Schmidt
Vanderbilt University
TYPE
Range
Vector
Binary
Search
Dups
Binary
Search
Nodups
Hash
Table
long
check_sort
TYPE
TYPE
Search
Struct
Strategy
TYPE
Do
OO Pattern Examples
OO Pattern Examples
make_strategy()
Search
Struct
New Search
Strategy
Concrete
Creator
factory_method()
Concrete
P roduct
New Search
Struct
CREATES
Vanderbilt University
make_strategy()
CREATES
94
Vanderbilt University
95
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Vanderbilt University
96
OO Pattern Examples
Douglas C. Schmidt
return 0;
// auto_ptrs destructor deletes the memory . . .
}
Vanderbilt University
OO Pattern Examples
97
Douglas C. Schmidt
Factory Method
Vanderbilt University
Douglas C. Schmidt
98
Vanderbilt University
99
OO Pattern Examples
Douglas C. Schmidt
OO Pattern Examples
Douglas C. Schmidt
Vanderbilt University
OO Pattern Examples
100
Douglas C. Schmidt
Vanderbilt University
102
Vanderbilt University
101