Kevlin Henney Frank Buschmann - HSR-Wiki
Kevlin Henney Frank Buschmann - HSR-Wiki
Kevlin Henney Frank Buschmann - HSR-Wiki
Transform your PDFs into Flipbooks and boost your revenue!
Leverage SEO-optimized Flipbooks, powerful backlinks, and multimedia content to professionally showcase your products and significantly increase your reach.
Beyond the<br />
Gang of Four<br />
<strong>Kevlin</strong> <strong>Henney</strong><br />
Curbralan Limited<br />
kevlin@curbralan.com<br />
<strong>Frank</strong> <strong>Buschmann</strong><br />
Siemens AG<br />
frank.buschmann@siemens.com
Agenda<br />
• Objectives<br />
�� Consider the pattern concept beyond the Gang of Four<br />
• Contents<br />
�� Introduction<br />
�� Missing ingredients<br />
�� Alternative solutions<br />
�� Scope and granularity<br />
�� Singleton<br />
�� Outroduction<br />
2
Introduction<br />
• Intent<br />
�� Outline the goal of this tutorial<br />
• Content<br />
�� The Gang of Four<br />
�� Our goal<br />
�� Misconceptions about the Gang of Four<br />
�� Issues in the Gang of Four<br />
�� Confusing map and territory<br />
3
The Gang of Four<br />
• Design Patterns has had a profound effect on what<br />
is considered to be design<br />
�� Highly influential and a useful starting point<br />
• But it has also restricted the expectations and<br />
design vocabulary of many programmers<br />
The The enormous success of of design patterns is is a testimonial to to the the commonality<br />
seen seen by by object object programmers. The The success of of the the book book Design Patterns,<br />
however, has has stifled stifled any any diversity in in expressing these these patterns.<br />
Kent Kent Beck<br />
Beck<br />
4
Our Goal<br />
• Place Design Patterns into perspective<br />
�� Historical, social and technical<br />
• Recognise its strengths; appreciate its limitations<br />
�� Nothing is perfect and everything has limitations, but in<br />
some cases more problems are caused than in others<br />
• Deconstruct and reconstruct good — and better —<br />
design practices associated with the GoF catalogue<br />
�� Place the individual patterns into a broader and more<br />
pattern-oriented pattern oriented context<br />
5
Twenty-Three Twenty Three Patterns in View<br />
• For some programmers, there are only twenty-<br />
three patterns<br />
�� This tutorial is as much about the magic number 23 as it<br />
is about the content of that 23<br />
• The aim is to open up some of the 23 to show that,<br />
in many cases, they hide more than they reveal<br />
�� Patterns that are missing by implication or<br />
by experience<br />
�� Patterns hiding within patterns<br />
6
Gang-of Gang of-Four Four Design Style<br />
• Programming to an interface not an<br />
implementation<br />
�� Inheritance is used primarily for establishing interfaces<br />
rather than for subclassing of implementation<br />
• Extensive use of forwarding ('delegation') in<br />
preference to inheritance of implementation<br />
• Emphasis on localised, general framework design<br />
above the level of the individual class<br />
�� Programming in the large is not really addressed, and<br />
idiomatic practices are seen as peripheral<br />
7
Misconceptions about GoF<br />
• Misconceptions are about individual patterns as<br />
well as about the catalogue as a whole<br />
�� The motivating example is the pattern<br />
�� The diagram is the pattern<br />
�� The source code is the pattern<br />
�� Copy-and Copy and-paste paste solutions<br />
�� Patterns are applicable only to OO design<br />
�� There are only 23 patterns<br />
23 23 patterns you you can can cut cut and and paste into into your your own own design documents.<br />
Blurb Blurb on on back back cover cover of of Design Design Patterns CD<br />
CD<br />
8
References and Blueprints?<br />
• A motivating example is sometimes taken to be<br />
the reference implementation for the pattern<br />
�� Also, the distilled essence outlined as the general<br />
solution is not a reference implementation<br />
• The mistaken idea that a pattern is a blueprint or<br />
simply parameterizable design is also common<br />
blueprint as as a metaphor for for a design or or plan is is much overworked. If If<br />
the the temptation to to use use it it is is irresistible, at at least remember that thata a<br />
blueprint is is a completed plan, not not a preliminary one. one.<br />
Bill Bill Bryson<br />
Bryson<br />
9
Pattern Structure Issues<br />
• If a pattern is a solution to a problem, where's the<br />
problem statement and solution description?<br />
�� The intent of the intent is unclear — sometimes it<br />
describes problem, sometimes solution, sometimes both<br />
�� The role of applicability is vague — sometimes it plays<br />
the role of context and forces... sometimes not<br />
�� The solution structure is not just the structure section,<br />
and there is no clear statement of what the solution is<br />
�� Sometimes the example and sample code carry the<br />
weight of the pattern<br />
10
Catalogue Issues<br />
• Of course, there is the effect of time<br />
�� The 23 patterns identified are not the ones we would<br />
necessarily consider the most important today<br />
• How useful or meaningful is the object- object and class-<br />
scope classification?<br />
�� What does it mean and how can Adapter be both?<br />
�� Seems to offer more interference than reference<br />
• The notion of pattern purpose is not always clear<br />
�� Creational seems obvious, but what about structural?<br />
structural<br />
11
Confusing Map and Territory?<br />
• What is the GoF catalogue map about?<br />
�� It's not about uses relationships... except when it is<br />
�� The uses shown are not often the useful uses<br />
• Many of the important relationships mentioned in<br />
the patterns are not included<br />
�� Many of the unimportant ones are<br />
• The emphasis of the map is sometimes misleading<br />
�� Which is the most important pattern?<br />
�� Which are the most isolated patterns?<br />
12
A Map... of What?<br />
So lonely?<br />
Connection not<br />
mentioned in Composite<br />
Most important pattern?<br />
What is the starting point<br />
here?<br />
No relationship with<br />
Builder is acknowledged<br />
A generative statement!<br />
13
Into the Gang of Four<br />
• The aim is to pin down...<br />
�� Missing ingredients in some existing GoF<br />
patterns, which would make the patterns<br />
richer and more complete<br />
�� Alternative solutions that complement GoF<br />
patterns, that will make our design vocabulary<br />
richer and more complete<br />
�� The proper scope and granularity for many<br />
of the patterns, so that they do one thing well<br />
�� Singleton, which is (in) a class of its own<br />
14
Missing Ingredients<br />
• Intent<br />
�� Discover what is missing from some common patterns<br />
and complete them<br />
• Content<br />
�� History and hindsight<br />
�� Command and Command Processor<br />
�� Factory Method and Disposal<br />
Method<br />
�� Completing factories<br />
�� Linking Iterator with Disposal Method<br />
15
History and Hindsight<br />
• Experience is often responsible for letting us spot<br />
certain omissions<br />
�� Whether omissions in individual patterns or from<br />
related groups of patterns<br />
• An eye for cohesion lets us spot other omissions<br />
�� What do we repeatedly include when applying a<br />
pattern, i.e. what additional patterns are there?<br />
History rarely happens in in the the right order or or at at the the right time,<br />
but but the the job job of of a historian is is to to make it it appear as as if if it it did. did.<br />
James James Burke<br />
Burke<br />
16
The Command Pattern<br />
• The reification of a method call, with context, into<br />
an object that can be passed around by reference<br />
�� Decoupling the decision of what to execute from the<br />
decision of when to execute<br />
• Based on inversion of control flow and encourages<br />
decoupling in both time and space<br />
Command<br />
Encapsulate a request as as an an object, thereby letting you you parameterize<br />
clients with with different requests, queue or or log log requests, and and support<br />
undoable operations.<br />
17
Much Undo about Something<br />
• Taking the common example of supporting undo<br />
in a GUI application...<br />
�� And remembering that there is quite a bit more to<br />
Command than 'undo' :-) :<br />
• How do we support multiple undo?<br />
�� Does the additional code find its way into the<br />
Command objects, or into the<br />
Command user, or...?<br />
�� How is history policy handled?<br />
18
Introducing a Processor<br />
• A separate processor object can handle the<br />
responsibility for multiple Command objects<br />
�� This responsibility should clutter neither the Command<br />
hierarchy nor the client code<br />
Client Command<br />
Processor<br />
doCommand<br />
undoLast<br />
*<br />
Command<br />
19
Implementation Detail?<br />
• Is it the case that introducing a processor object is<br />
simply a detail of the implementation?<br />
�� The resulting design is not sufficiently different from<br />
the single undo to warrant noting the design variation<br />
�� Or, although different, the difference is not important<br />
enough to note, i.e. it's a minor detail<br />
�� Or, you would always use this approach, regardless, so<br />
the design technique is already a part of Command<br />
�� Or, this design is specific to 'undo' rather than being a<br />
common use within Command<br />
20
Or Pattern?<br />
• Or is it the case that the use of a processor is a<br />
recurring design that addresses specific forces?<br />
�� The resulting design has a sufficiently different<br />
architecture and properties to the single undo variant<br />
�� The applicability of this design technique is contingent<br />
on requirements, so not all uses of Command need to or<br />
should employ it<br />
�� It has broader scope than just being applied in<br />
the context of Command 'undo'<br />
21
The Command Processor Pattern<br />
• Command Processor complements Command by<br />
handling responsibility for execution policy<br />
�� It is an additional and complementary microarchitecture<br />
for Command<br />
�� It recurs in many situations beyond the 'undo' example<br />
Command Processor<br />
Separate the the request for for a service from from its its execution. A command<br />
processor component manages requests as as separate objects, schedules<br />
their their execution, and and provides additional services such such as as the the storing of of<br />
request objects for for later later undo.<br />
22
The Factory Method Pattern<br />
• Factory Method is itself balanced and contained<br />
with respect to its goal<br />
�� This is true in both the specific GoF view of Factory<br />
Method and also more generalised views of the pattern<br />
• The question of completeness arises when a<br />
Factory Method is used as part of another pattern<br />
Factory Method<br />
Define an an interface for for creating an an object, but but let let subclasses decide<br />
which class class to to instantiate. Factory Method lets lets a class class defer instantiation<br />
to to subclasses.<br />
23
Factory Method Sketch<br />
• Mirroring the hierarchy of what is created...<br />
�� An interface for creation is provided<br />
�� The responsibility for creation is deferred to an<br />
implementing subclass<br />
Client<br />
Creator<br />
factoryMethod<br />
Concrete<br />
Creator<br />
factoryMethod<br />
«create»<br />
Product<br />
Concrete<br />
Product<br />
24
The Abstract Factory Pattern<br />
• There is a meaningful and generative relationship<br />
between Abstract Factory and Factory Method<br />
�� Scaling from the creation of individual objects to the<br />
creation of whole families of objects<br />
• A concrete factory implements a number of<br />
related Factory Methods according to an interface<br />
Abstract Factory<br />
Provide an an interface for for creating families of of related or or dependent objects<br />
without specifying their their concrete classes.<br />
25
The Disposal Method Pattern<br />
• Factories can leave unresolved lifetime and<br />
resource management issues<br />
�� Who cleans up factory products after use?<br />
�� How can you reduce dynamic memory usage?<br />
• A Disposal Method can provide an answer<br />
Disposal Method<br />
Encapsulate the the concrete details of of object disposal by by providing an an<br />
explicit method for for clean up up instead of of letting object users either<br />
abandon objects to to the the tender mercies of of the the garbage collector or or<br />
terminate them them with with extreme prejudice and and delete.<br />
26
Disposal Method Sketch<br />
• Reflecting the application of Factory Method...<br />
�� The responsibility for disposal — whether destruction<br />
or recycling — is collocated with the creation<br />
Client<br />
Creator<br />
factoryMethod<br />
disposalMethod<br />
Concrete<br />
Creator<br />
factoryMethod<br />
disposalMethod<br />
«create»<br />
«destroy»<br />
Product<br />
Concrete<br />
Product<br />
27
Linking Factory and Disposal<br />
• Factory Method and Disposal Method are<br />
complementary with respect to local symmetry<br />
�� One completes the other by addressing unresolved<br />
questions in the lifecycle of an object<br />
• Together they form a generative phrase<br />
�� Where one pattern strongly suggests the application of<br />
the next as part of its structure<br />
Factory<br />
Method<br />
Disposal<br />
Method<br />
28
Completing Other Factories<br />
• Consideration of disposal becomes a natural<br />
consequence of considering creation<br />
�� Any creational pattern becomes more complete and<br />
more useful by raising the question of disposal<br />
Abstract<br />
Factory<br />
Prototype<br />
Builder<br />
Factory<br />
Method<br />
Disposal<br />
Method<br />
29
Iterators and Disposal<br />
• Iterator embodies a fine-grained fine grained commodity<br />
�� If usage is decoupled dynamically from the concrete<br />
type, a Factory Method resolves the creational tension<br />
�� In unmanaged resource situations a Disposal Method<br />
addresses lifetime completion<br />
• However, this design phrase is context specific<br />
�� It makes little sense outside its intended scope<br />
Iterator<br />
Factory<br />
Method<br />
Disposal<br />
Method<br />
30
Alternative Solutions<br />
• Intent<br />
�� Identify the complements of some common patterns<br />
• Content<br />
�� A one-way one way system?<br />
�� Proxy and Half-Object Half Object + Protocol<br />
�� Iterator<br />
�� Combined Method, Batch Method<br />
and Enumeration Method<br />
�� Objects for States, Collections for<br />
States and Methods for States<br />
31
A One-Way One Way System?<br />
• With the exception of the creational patterns, each<br />
problem type has only one GoF pattern against it<br />
�� Some people see this as a strength, reducing their<br />
design options instead of creating a design dialogue<br />
�� Gives the impression that there is only one solution per<br />
general problem, and the one in the book is that one<br />
• Good design involves making informed choices<br />
�� Patterns should communicate those choices<br />
�� Arbitrarily reducing the available degrees of freedom at<br />
the expense of suitability is not a sound approach<br />
32
The Proxy Pattern<br />
• A Proxy controls and manages access to a target<br />
object, forwarding requests to it<br />
• The pattern has many applications and variations<br />
�� E.g. remote access transparency in a distributed object<br />
system, smart pointers for memory management in C++<br />
Proxy<br />
The The Proxy design pattern makes the the clients of of a component communicate<br />
with with a representative rather than than to to the the component itself. Introducing<br />
such such a placeholder can can serve many purposes, including enhanced<br />
efficiency, easier access and and protection from from unauthorized access.<br />
33
Typical Proxy Sketch<br />
• The role of the interface is central and the roles in<br />
the communication are static<br />
�� Each object or role is a whole, and not subdivided<br />
client<br />
implementor<br />
operation<br />
«interface»<br />
interface<br />
operation<br />
target<br />
«implements»<br />
proxy<br />
operation<br />
Signature and<br />
contract placeholder<br />
Forward operation<br />
request to target<br />
Actual implementation<br />
of operation<br />
34
Partitioning Issues<br />
• For Proxy to be effective a clear separation is<br />
needed between the role of target and user<br />
�� These two roles must be physically and functionally<br />
cohesive, otherwise the boundary cuts across roles<br />
• However, sometimes an object needs to appear to<br />
be in multiple address spaces simultaneously<br />
�� And the implementation of its behaviours must also be<br />
physically distributed...<br />
�� But yet it must appear as a single whole<br />
35
Half-Object Half Object + Protocol (HOPP)<br />
• Divide the physical object across address spaces<br />
�� But retain and manage the conceptual object as a whole<br />
Objects in first<br />
address space<br />
Synchronisation<br />
Protocol<br />
Half Object Half Object<br />
Object<br />
Objects in second<br />
address space<br />
36
The Iterator Pattern<br />
• Classically defined in terms of separating the<br />
responsibility for iteration from its target<br />
�� The knowledge for iteration is encapsulated in a<br />
separate object from the target<br />
�� Rendered idiomatically in different languages, e.g. STL<br />
in C++ and (more than once) in Java's standard library<br />
Iterator<br />
Provide a way way to to access the the elements of of an an aggregate object sequentially<br />
without exposing its its underlying representation.<br />
37
Iterator Configuration Sketch<br />
• There are four essential, elementary operations<br />
associated with an Iterator's behaviour<br />
�� Initialising an iteration<br />
�� Checking a completion condition<br />
�� Accessing a current target value<br />
�� Moving to the next target value<br />
Collection<br />
createIterator() : Iterator<br />
Type<br />
1<br />
«create»<br />
*<br />
Iterator<br />
Type<br />
finished() : Boolean {query}<br />
value() : Type {query}<br />
next()<br />
38
Concurrency Issues<br />
• Synchronisation is required to ensure consistent<br />
and coherent state<br />
�� This cannot be handled adequately by the Iterator client<br />
• Property-style Property style programming is inappropriate<br />
�� There is a mismatch in granularity and coherence<br />
client 1 servant<br />
client 2<br />
39
The Combined Method Pattern<br />
• Applying it gives slightly coarser granularity than<br />
the separated methods of a sequential Iterator<br />
�� Aligns and groups the unit of failure, synchronisation<br />
and common use<br />
�� Improves the encapsulation of collection use, isolating<br />
the client from unnecessary details<br />
Combined Method<br />
Combine methods that that are are commonly used used together to to guarantee<br />
correctness and and improve efficiency in in threaded and and distributed<br />
environments.<br />
40
Distribution Issues<br />
• Concurrency is implicit<br />
• Operation invocations are no longer trivial<br />
�� Communication can dominate computation<br />
�� Partial failure is almost inevitable<br />
client<br />
servant<br />
Cost of communication<br />
41
The Batch Method Pattern<br />
• Iterated simple methods use up bandwidth<br />
�� Spending far more time in communication than in<br />
computation<br />
• Provide the repetition in a data structure<br />
�� More appropriate granularity that reduces<br />
communication and synchronisation costs<br />
Batch Method<br />
Group multiple collection accesses together to to reduce the the cost cost of of multiple<br />
individual accesses in in a distributed environment.<br />
42
Batched (or Chunky) Iterators<br />
• A combination of these patterns recurs in<br />
distribution and component-based component based design<br />
�� A compound design that addresses many requirements<br />
Batch<br />
Method<br />
Iterator<br />
Combined<br />
Method<br />
Factory<br />
Method<br />
Disposal<br />
Method<br />
43
The Enumeration Method Pattern<br />
• An inversion of the basic Iterator design<br />
�� Iteration is encapsulated within the collection<br />
�� Collection stateless with respect to iteration<br />
• A method on the collection that receives a<br />
Command, which it then applies to its elements<br />
�� Idiomatic iteration in Smalltalk based on block objects<br />
Enumeration Method<br />
Support encapsulated iteration over over a collection by by placing responsibility<br />
for for iteration in in a method on on the the collection. The The method takes a Command<br />
object that that is is applied to to the the elements of of the the collection.<br />
44
Enumeration Method Sketch<br />
• Has very different trade-offs trade offs when compared to<br />
the Iterator approach<br />
�� Client is not responsible for loop housekeeping details<br />
�� Synchronisation can be provided at the level of the<br />
whole traversal rather than for each element access<br />
Collection<br />
Type<br />
enumerationMethod(Command)<br />
Loop administration is handled in<br />
the implementation of the<br />
enumerationMethod<br />
Command<br />
executeOn(Type)<br />
Type<br />
Loop body is now provided<br />
as the implementation of the<br />
executeOn method<br />
45
The State Pattern<br />
• Also known as the Objects for States pattern<br />
�� A name that better reflects the reification that occurs in<br />
the design<br />
• It can lead to a proliferation of classes and a<br />
complex design if applied carelessly<br />
�� Not inappropriate in all cases, but in many situations<br />
the design can be overly complex<br />
State<br />
Allow an an object to to alter alter its its behavior when its its internal state state changes. The The<br />
object will will appear to to change its its class.<br />
46
What is the Real Intent?<br />
• The documented intent can be considered vague<br />
and a little misleading<br />
�� An object changing its behaviour in response to an<br />
internal state change is hardly news<br />
�� Is the emulation of dynamic inheritance really the best<br />
way to motivate the pattern?<br />
• As a result, many programmers ignore either the<br />
intent or the pattern as a whole<br />
�� Now is the winter of our missed intent... :-)<br />
:<br />
47
Complexity and Overkill<br />
• The pattern is complex, but the detail offered does<br />
not adequately cover that complexity<br />
�� The implementation is incomplete and, therefore,<br />
unclear and unmotivating for many programmers<br />
• In many cases the pattern is overkill<br />
�� Sometimes a flag or table really<br />
is the simplest, clearest and<br />
most elegant thing that<br />
could possibly work<br />
48
The Other State Patterns<br />
• However, in spite of its common name, the State<br />
pattern is not the only game in town<br />
�� A common misconception is that any problem<br />
associated with a state model should<br />
necessarily be realised using Objects for States<br />
�� The name suggests the problem domain rather<br />
the solution, and as such appears to address<br />
all variations<br />
49
A Note on Naming<br />
• As with variables, naming is important<br />
�� Should be memorable, usable and distinct<br />
�� Should be based on something that characterises the<br />
proposed solution rather than the problem<br />
• The GoF naming style is based on choosing<br />
the name of a class role in the solution<br />
�� The name State is taken from the root of the<br />
(often stateless!) class hierarchy that<br />
defines modal behaviour<br />
50
The Methods for States Pattern<br />
• Methods for States represents each state as a table<br />
or record of method references<br />
�� The methods referenced are on<br />
the context object<br />
Context<br />
object<br />
Current<br />
state<br />
Tables (e.g. struct) struct)<br />
of<br />
method references<br />
Methods on the<br />
context object<br />
a(...) { ... ... }<br />
b(...) { ... ... }<br />
c(...) { ... ... }<br />
d(...) { ... ... }<br />
e(...) { ... ... }<br />
51
The Collections for States Pattern<br />
• How should state be represented for objects that<br />
are managed collectively?<br />
�� Partition objects into collections with respect to state,<br />
so that state is represented by collection membership<br />
Common operations on objects in the same state<br />
Transition of objects<br />
between states<br />
Collection representing state<br />
Managed object<br />
52
The State of the Union<br />
• There are many other successful recurring<br />
solutions for expressing modal behaviour<br />
�� And many of these are also complementary in the sense<br />
that they can also be used together<br />
• These patterns focus mainly on the representation<br />
of modal state, less on the mechanics of transition<br />
Objects for<br />
States<br />
Methods for<br />
States<br />
Collections<br />
for States<br />
53
Scope and Granularity<br />
• Intent<br />
�� Nail down the proper scope and granularity for some<br />
common patterns, so that they do one thing well<br />
• Content<br />
�� Overworked and underpaid<br />
�� Iterator reiterated<br />
�� Bridge<br />
�� Flyweight and friends<br />
�� Dividing between Template Method<br />
and Strategy<br />
54
Overworked and Underpaid<br />
• Some patterns just seem to be too busy solving<br />
everyone's problems to be cohesive<br />
�� Adapter is expressed as two fundamentally different<br />
solutions... so isn't that two patterns?<br />
�� Bridge seems to span more water than the Øresund resund, ,<br />
addressing multiple problems with multiple solutions<br />
�� Must Iterator necessarily be the design solution for all<br />
iteration requirements?<br />
�� Objects for States covers intent but is short on detail<br />
�� And what is the Flyweight pattern?<br />
55
Problem–Solution Problem Solution Multiplicity<br />
• Some common patterns seem to identify<br />
themselves with the solution structure<br />
�� And therefore do not have clear problem requirements<br />
• Other common patterns seem to identify with the<br />
general theme of the problem<br />
�� And therefore do not have distinct solutions<br />
• Many common patterns appear to hide or act as<br />
the gateway to a small community of patterns<br />
�� Inspection reveals another level of design consideration<br />
56
Iterator Reiterated<br />
• GoF tries to accommodate both C++-like C++ like and<br />
Smalltalk-style Smalltalk style iteration in one pattern<br />
�� The external and internal variants of Iterator<br />
�� However, most developers equate Iterator with the<br />
external variant, and do not consider the internal one<br />
• The problem solved, the solution structure and the<br />
consequences are totally different<br />
�� Hence, two quite distinct patterns —<br />
Iterator and Enumeration Method —<br />
not one pattern with two variations<br />
57
The Bridge Pattern<br />
• The metaphor of a bridge between abstraction and<br />
internal implementation is compelling<br />
�� But the motivation seems to be disconnected from<br />
many of the uses and the discussion of consequences<br />
• Bridge appears to be many things to many people<br />
�� As in other aspects of life, not always a good thing<br />
Bridge<br />
Decouple an an abstraction from from its its implementation so so that that the the two two can can vary vary<br />
independently.<br />
58
The Problems Listed<br />
• The original list plus recent additions...<br />
�� Loosen permanence of implementation binding<br />
�� Independent implementation and abstraction extension<br />
�� Reducing compilation ripple effect<br />
�� Data hiding in C++<br />
�� Elimination of multiple inheritance<br />
�� Representation sharing<br />
�� Reduction of stack footprint<br />
�� Exception safety in C++<br />
59
The Solutions Offered<br />
• The stable theme is that there is a handle–body<br />
handle body<br />
separation introduced into the structure<br />
�� But handle–body handle body on its own is structure without intent<br />
• The variations, however, are less easily fixed...<br />
�� No class hierarchies, abstraction class hierarchy,<br />
implementation class hierarchy, or hierarchies for both<br />
�� The abstraction is either a handle or a proper entity<br />
�� No sharing of representation or sharing, optionally with<br />
reference counting<br />
�� Optionally hide the representation class definition<br />
60
Bridge Configuration Sketch<br />
• This seems like a number of different patterns that<br />
are largely unrelated in the problem solved<br />
�� Their only common feature is a handle–body handle body separation<br />
in the solution... which is true of most GoF patterns!<br />
Handle<br />
N may be 1 (exclusive) or<br />
1..* (shared, with counting)<br />
N<br />
Optional<br />
hierarchy<br />
Body<br />
Optional<br />
hierarchy<br />
61
Different Problem or Solution?<br />
• Diversity in pattern expression is good... but there<br />
is such a thing as too much of a good thing...<br />
�� The pattern becomes all things to all people, each<br />
person with their own different (incompatible) view<br />
�� Dilutes the notion of patterns as design vocabulary<br />
• A pattern solves a general problem with a general<br />
but coherent solution<br />
�� It does not solve many general problems with many<br />
general solutions<br />
62
The Flyweight Pattern<br />
• What is the defining characteristic of Flyweight?<br />
�� Is it creation?<br />
�� Is it sharing?<br />
�� Is it the use of extrinsic state?<br />
�� Is it immutability?<br />
• Is it all or some of these?<br />
�� Or is it something else?<br />
Flyweight<br />
Use Use sharing to to support large numbers of of fine-grained objects efficiently.<br />
63
Underweight or Overweight?<br />
• It is something to do sharing, but is this a<br />
structural or creational issue?<br />
�� It is not classified as creational, but that is a key feature<br />
• Are we solving all problems of sharing?<br />
�� Or are these separate patterns?<br />
• Is Flyweight actually a solution?<br />
�� The intent is noble, but the solution is<br />
uncohesive... uncohesive...<br />
it is either many solutions<br />
or not a solution<br />
64
The Solutions Inside Flyweight<br />
• Within what appears to be Flyweight there are a<br />
number of more concrete patterns at work<br />
�� And some that should be at work<br />
• It appears that Flyweight is actually the wrong<br />
cross-section cross section of the problem space<br />
�� Immutable Value, with some variant<br />
of Factory Method plus Pooling<br />
would appear clearer base ingredients<br />
65
The Immutable Value Pattern<br />
• How can you share fine-grained fine grained objects, such as<br />
values, without side-effect side effect problems?<br />
�� If not designed for (or around), reference-based<br />
reference based<br />
semantics can undermine encapsulation, via aliasing<br />
• Define a type whose instances are immutable<br />
�� The internal state of the object is set at<br />
construction<br />
�� Value change is effected through creation<br />
of or binding to another object<br />
66
More Than One Factory Method<br />
• Factory Method can be seen as a general pattern<br />
that has specific, named variations<br />
�� Plain Factory Method, which supports encapsulated but<br />
not polymorphic creation<br />
�� Class Factory Method at class level, i.e. static<br />
�� Polymorphic Factory Method, which is the classic<br />
Factory Method<br />
�� Cloning Method, which is different in intent to<br />
Prototype but may be employed by Prototype<br />
• Plus domain-specific domain specific variations of each of these<br />
67
The Pooling Pattern<br />
• Can reduce creation and GC recycling costs by<br />
explicitly pooling objects<br />
�� Populate (or depopulate) pool on demand<br />
�� Retain recycled pool objects<br />
• The pool implements...<br />
�� Factory and disposal roles<br />
�� Pool clearing and other<br />
management<br />
68
The Counting Handle Pattern<br />
• In the context of a language such as C++, a handle<br />
object can be used to track pool object usage<br />
�� Reference counting allows the pool to know when an<br />
object is no longer in use, should it wish to discard it<br />
�� In Java, weak references can be used to achieve a<br />
similar effect<br />
Counting Handle<br />
Simplify the the lifetime management of of shared heap heap objects by by introducing<br />
handle objects that that act act as as the the references to to the the heap heap object, tracking its its<br />
usage.<br />
69
Flyweight Reconstructed<br />
• Flyweight is better considered a community of<br />
patterns than an individual pattern<br />
�� It is a connected collection of patterns that has no<br />
obvious root pattern that can be named Flyweight<br />
Immutable<br />
Value<br />
Factory<br />
Method<br />
Pooling<br />
Disposal<br />
Method<br />
Counting<br />
Handle<br />
Proxy<br />
70
The Template Method Pattern<br />
• A pattern that captures control-flow control flow commonality<br />
and separates it from variability of detail<br />
�� Commonality is captured in a class and variability is<br />
deferred to methods overridden in subclasses<br />
• As an aside, the name of the pattern also has an<br />
unfortunate clash with an unrelated feature of C++<br />
Template Method<br />
Define the the skeleton of of an an algorithm in in an an operation, deferring some steps steps<br />
to to subclasses. Template Method lets lets subclasses redefine certain steps steps of of<br />
an an algorithm without changing the the algorithm's structure.<br />
71
Template Method Sketch<br />
• Control flow is specified in superclass and the<br />
details are filled out in the subclass<br />
�� Can provide default<br />
implementation in<br />
the superclass... superclass...<br />
�� But excessive use of<br />
this capability makes<br />
class hierarchies<br />
hard to understand<br />
and change rather<br />
than more convenient<br />
Algorithm<br />
Sketch<br />
templateMethod<br />
hookMethod1<br />
hookMethod2<br />
Algorithm<br />
Detail<br />
hookMethod2<br />
...<br />
hookMethod1(...)<br />
...<br />
hookMethod2(...)<br />
...<br />
Note the use of self-<br />
delegation, with<br />
variation through<br />
inheritance<br />
72
Two Much<br />
• Template Method seems to include too much<br />
�� First, the solution that factors out common control flow<br />
�� Second, the solution that chooses to delegate<br />
responsibility for detail to subclasses<br />
• For some developers it represents one or the other<br />
rather than both, which can lead to confusion<br />
�� However, both the control flow skeleton and use of<br />
overridden methods are tightly bound to the description<br />
of the pattern, so the pattern solution is definitely both<br />
73
The Strategy Pattern<br />
• Offers a delegation-based delegation based alternative to<br />
subclassing the class that defines the algorithm<br />
�� Often too narrowly described in terms of expressing<br />
just a family of algorithms through an interface: related<br />
parts of an algorithm may also be expressed<br />
�� Some relationship between Template Method and<br />
Strategy is alluded to but not explored in GoF<br />
Strategy<br />
Define a family of of algorithms, encapsulate each each one, one, and and make them them<br />
interchangeable. Strategy lets lets the the algorithm vary vary independently from from<br />
clients that that use use it.<br />
it.<br />
74
Strategy Configuration Sketches<br />
• Applies to both inheritance and template-based<br />
template based<br />
approaches, where it is better known as Policy<br />
�� Runtime versus compile-time compile time binding of the policy<br />
usage<br />
Client<br />
Client<br />
usage<br />
Policy ><br />
PolicySpec<br />
strategy<br />
Strategy<br />
operation<br />
PolicySpec<br />
operation<br />
...<br />
strategy.operation(...)<br />
...<br />
...<br />
Policy.operation(...)<br />
...<br />
75
A Clearer Separation<br />
• Template Method can be seen as a compound<br />
pattern of Method Skeleton and Hook Method<br />
�� The common algorithm structure is expressed in the<br />
Method Skeleton, and variation is expressed either<br />
through Hook Methods or via a Strategy<br />
Template<br />
Method<br />
Hook<br />
Method<br />
Method<br />
Skeleton<br />
Strategy<br />
76
A Deconstructed Variation<br />
• The idea of non-virtual non virtual public interface (NVI) has<br />
been proposed as a guideline for C++ interfaces<br />
• Although it looks a bit like Template Method, and<br />
has sometimes been labelled as such, it is not<br />
�� It is not motivated by the same<br />
problem and has a quite distinct<br />
solution structure<br />
Interface<br />
+ operation<br />
– doOperation<br />
Implementation<br />
– doOperation<br />
77
Dysfunctional Patterns<br />
• A dysfunctional pattern is a design that recurs but<br />
whose forces and consequences are out of balance<br />
�� E.g. the so-called so called Getters and Setters pattern<br />
• In this case, NVI fails to adequately offer the<br />
benefits that are advertised as its motivation<br />
�� Code simplification, extensibility, decoupling, thread<br />
safety, instrumentation, assertion checking, etc<br />
�� It has the plausible appeal of a solution, but one that is<br />
in search of a problem — it is in need of a problem that<br />
is not already better addressed by other patterns<br />
78
Singleton<br />
• Intent<br />
�� Understand the pattern that describes an object in a<br />
class of its own<br />
• Content<br />
�� Singleton<br />
�� Global domination<br />
�� Demotivating examples<br />
�� Solving the solution<br />
�� Parameterize from Above<br />
79
The Singleton Pattern<br />
• Singleton is both a whisky and a pattern<br />
�� But the former is often better for design than the latter<br />
• Half of its problems are the misconceptions<br />
developers hold about it<br />
�� The other half is the publicity it receives in terms of<br />
how to apply and fix it<br />
�� And the remaining half are in the book<br />
Singleton<br />
Ensure a class class only only has has one one instance, and and provide a global point of of<br />
access to to it.<br />
it.<br />
80
Global Domination<br />
• Apparently, Singleton is the most important<br />
pattern in the book<br />
�� Just try googling for it<br />
�� Apparently, many 'experts' say so<br />
• It now seems to appear — at least twice :-) : ) — in<br />
almost every OO system<br />
How do do you you provide global variables in in languages without global<br />
variables? Don't. Your programs will will thank you you for for taking the the<br />
time to to think about design instead.<br />
Kent Kent Beck<br />
Beck<br />
81
What the Gang of Four Say...<br />
• It is taught to novices, sometimes as a first pattern,<br />
but it was never intended that way<br />
�� And Erich has also since said that "we should never<br />
have put it in the book"<br />
If If you you aren't aren't an an experienced object-oriented designer, then then start start with with the the simplest simplest<br />
and and most most common patterns: Abstract Factory, Adapter, Composite,<br />
Decorator, Factory Factory Method, Observer, Strategy, Template Method. It's It's hard hard to to<br />
find find an an object-oriented system system that that doesn't doesn't use use at at least least a couple couple of of these these patterns,<br />
and and large large systems systems use use nearly nearly all all of of them. them. This This subset subset will will help help you you understand<br />
design design patterns in in particular and and good good object-oriented design design in in general.<br />
Gamma, Helm, Helm, Johnson and and Vlissides<br />
82
Demotivating Examples<br />
• No concrete example is used to illustrate the<br />
pattern, and the cited examples are not motivating<br />
�� Only one print spooler in a system<br />
�� Only one file system in a system<br />
�� Only one window manager in a system<br />
�� Only one A/D converter in a digital filter<br />
�� Only one company served by an accounting system<br />
• The uniqueness constraint is either (co)incidental<br />
( co)incidental<br />
or not actually a constraint<br />
83
The Simplest Class Diagram?<br />
• There are no users<br />
�� Perhaps this is how it should be ;-) ;<br />
• The simplicity of the diagram is simplistic<br />
�� Which misleads a number of developers to apply it as<br />
an apparently simple pattern<br />
• The pattern is also applied unnecessarily in GoF<br />
�� For example, it is used in Objects for States to share<br />
single instances of 'state' objects where there is no<br />
relevant uniqueness constraint<br />
84
Only Good Things<br />
• Five consequences are listed for the pattern, all of<br />
them benefits<br />
�� What, no liabilities?<br />
• This seems too good to be true!<br />
�� The nature of design involves decisions, implicit or<br />
explicit, and decisions involve trade-offs trade offs<br />
• And in the context of Singleton, the<br />
absence of liabilities is clearly not<br />
quite right<br />
85
Secondary Industries<br />
• A whole industry in print and online seems to<br />
have sprung up around Singleton implementation<br />
�� How to delete a Singleton<br />
�� How to make a Singleton thread safe<br />
�� How to customise Singleton behaviour<br />
�� How to exchange a Singleton (can you get a refund?)<br />
�� How to refactor away from Singleton<br />
• Deconstruction suggests that perhaps Singleton is<br />
a problem, not a solution<br />
86
Dysfunctional Alternatives<br />
• The Monostate pattern is sometimes put forward<br />
as an alternative to Singleton<br />
�� Define an ordinary instance interface to class-wide class wide<br />
state, so instances are created locally and all instances<br />
share the same state — hence its alias, the Borg pattern<br />
• Monostate seems to target the syntax overhead<br />
and burden of conscience of using Singleton<br />
�� But does not actually address any of the core issues<br />
�� Leads to implicitly aliased value objects that can<br />
acquire and change state automagically<br />
87
Solving the Solution<br />
• In most cases, instance control is a property of (a<br />
part of) an application, not of a type<br />
�� Therefore, the pattern's scope of<br />
applicability is significantly smaller<br />
than advertised<br />
• The pattern has...<br />
�� Missing ingredients<br />
�� Alternative solutions<br />
�� Scope and granularity issues<br />
88
Requirements and Analysis<br />
• A design that is so typically problematic or widely<br />
misunderstood cannot be considered successful<br />
�� Such failure is clearly the case with Singleton<br />
• What we need from a pattern...<br />
�� A clear motivation<br />
�� A concrete solution that addresses a real problem<br />
�� A solution that is consistent and complete<br />
�� A solution that is markedly better than any alternatives<br />
�� An honest understanding of the consequences<br />
89
Design Principles<br />
• High cohesion and loose coupling<br />
�� Testability, stability, evolvability and configurability<br />
• Program to an interface, not an instance<br />
�� Substitutability is an important guiding principle of<br />
decoupled design; globals are not<br />
• Economy and necessity of solution<br />
�� Solves the right problem sufficiently and in a way that<br />
answers more questions than it raises<br />
90
Granularity<br />
• Extracting an interface gives us an Explicit<br />
Interface to implement in the concrete Singleton<br />
�� We can program against it and configure behind it<br />
�� Singleton is the only creational pattern that does not<br />
decouple through an interface<br />
• Singleton is built on Lazy Evaluation<br />
�� Lazy Evaluation is a pattern in its own right, addressing<br />
forces at its own level<br />
�� It does not attempt to deal with issues of application<br />
intent, which is the domain of Singleton<br />
91
Concurrency<br />
• A great deal of design effort has been thrown at<br />
Singletons to make them threadsafe<br />
�� Lazy Evaluation needs careful consideration in the<br />
presence of threads<br />
• However, Double-Checked Double Checked Locking is highly<br />
platform dependent<br />
�� For instance, Java does not currently guarantee any of<br />
the properties that allow it to work<br />
�� Such fragility leads to unnecessary subtlety<br />
92
Reconstruction<br />
• A refactored Singleton...<br />
�� Is a community of patterns that<br />
covers the design space more<br />
thoroughly<br />
Explicit<br />
�� Has clear consequences<br />
Interface<br />
�� Enforces a genuine creation<br />
constraint<br />
�� Is not sold in terms of global access as its<br />
defining property<br />
Singleton<br />
Class Factory<br />
Method<br />
Lazy<br />
Evaluation<br />
Double-<br />
Checked<br />
Locking<br />
93
Genuine Constraint<br />
• A Singleton can be used where there is a genuine<br />
constraint that there can be only one instance<br />
�� In other words, where having more than one would<br />
cause incorrect behaviour in the system...<br />
�� Not just because there happens to be only one instance<br />
in a particular configuration<br />
• Wrapping up devices and stateful, procedural<br />
APIs are examples that offer real motivation<br />
�� But such uniqueness does not make them globals<br />
94
Parameterize from Above<br />
• We can go a step further and propose a design that<br />
has desirable architectural consequences<br />
�� Based on the Layers pattern and the layering metaphor<br />
�� Complementary to Singleton, but normally replaces it<br />
• Pass in configuration parameters and 'known'<br />
objects rather than having them global or pulled in<br />
�� Communicate through constructor arguments or<br />
template parameters, as appropriate<br />
�� E.g. the Mock Object unit testing technique, the<br />
application of Strategy/Policy, Context Object, etc<br />
95
Outroduction<br />
• Intent<br />
�� Review the opening position, draw some conclusions<br />
and then, in the spirit of this talk's title, move on<br />
• Content<br />
�� Twenty-three Twenty three patterns in review<br />
�� A process and a thing<br />
�� Pattern communities and generative<br />
phrases<br />
�� Pattern languages<br />
96
Twenty-Three Twenty Three Patterns in Review<br />
• Yes, there is good design thinking in Gang of Four<br />
�� But it gives insufficient coverage of the practices that<br />
are involved in successful real-world real world OO design<br />
• Yes, the naming of individual practices is useful<br />
�� But scope and applicability is often unclear or too broad<br />
• Yes, the catalogue was a good start<br />
�� But a starting point is just that: it is only one point on<br />
the whole line of development<br />
97
So, What Then is a Pattern?<br />
• A pattern considers and encapsulates a set of<br />
conflicting design forces<br />
• A pattern proposes a configuration to balance<br />
these forces<br />
�� Such a design decision has consequences<br />
A pattern is is a piece of of literature that describes a design<br />
problem and a general solution for for the problem in in a<br />
particular context.<br />
Jim Jim Coplien<br />
Coplien<br />
98
A Process and a Thing<br />
• A pattern is a thing, but it's not a component<br />
• A pattern is also a process: it is not just a static<br />
snapshot of design or design thinking<br />
�� A pattern must describe what to build, why and,<br />
importantly, how<br />
�� Each one is a highly specific mini-methodology<br />
mini methodology<br />
• Patterns are not rigid and automatic, and must be<br />
considered and adapted every time<br />
�� They inform a design rather than dictate it<br />
99
Pattern Communities<br />
• Patterns can be used in isolation with some degree<br />
of success<br />
�� Represent foci for discussion or point solutions<br />
• However, patterns are in truth gregarious<br />
�� They are rather fond of the company of other patterns<br />
�� To make practical sense as a design idea,<br />
patterns inevitably enlist other<br />
patterns for expression<br />
and variation<br />
100
Generative Phrases<br />
• Design is conversational in nature, an open-ended open ended<br />
dialogue with a context<br />
• In almost every case, a standalone pattern has been<br />
decomposed, added to or connected<br />
�� Richer, general design discussion for more specific<br />
solutions<br />
• This tendency is also visible in places in the Gang<br />
of Four book, but is not made explicit<br />
�� It appears as no more than a subplot<br />
101
Towards Pattern Languages<br />
• A pattern language connects patterns<br />
�� Consequences of one pattern may generate forces that<br />
must be resolved by another<br />
• Pattern languages are intentional, conversational<br />
and architectural<br />
A pattern language is is a collection of of patterns that that build on on each each other<br />
to to generate a system. A pattern in in isolation solves an an isolated design<br />
problem; a pattern language builds a system. It It is is through pattern<br />
languages that that patterns achieve their their fullest power.<br />
Jim Jim Coplien<br />
Coplien<br />
102
Tales of Software Design<br />
• A pattern is a study in design and a fragment of<br />
design vocabulary<br />
• It tells a "successful software engineering story"<br />
�� Albeit a short one<br />
• A pattern language is a framework that<br />
expands the range and scope of the<br />
stories than can be told<br />
103
In Closing<br />
• Patterns distil successful design experience<br />
�� This is the message; it should not be confused with or<br />
restricted to the medium<br />
• There is more to both OO design and patterns than<br />
is achieved or intended by the Gang of Four<br />
�� It was a good start, but it is a historical subset of the<br />
patterns we need to know for effective design<br />
There are more things in in heaven and earth, Horatio,<br />
than are dreamt of of in in your philosophy. William Shakespeare<br />
104
Bibliography<br />
GoF<br />
Design Patterns: Elements of Reusable Object-Oriented Object Oriented Software, Software,<br />
Erich Gamma, Richard<br />
Helm, Ralph Johnson and John Vlissides, Vlissides,<br />
Addison-Wesley, Addison Wesley, 1995<br />
Pattern Hatching: Design Patterns Applied, Applied,<br />
John Vlissides, Vlissides,<br />
Addison-Wesley, Addison Wesley, 1998<br />
The Design Patterns Smalltalk Companion, Companion,<br />
Sherman R Alpert, Kyle Brown and Bobby<br />
Woolf, Woolf,<br />
Addison-Wesley, Addison Wesley, 1998<br />
POSA<br />
Pattern-Oriented Pattern Oriented Software Architecture, Volume 1: A System of Patterns, Patterns,<br />
<strong>Frank</strong> <strong>Buschmann</strong>,<br />
Regine Meunier, Meunier,<br />
Hans Rohnert, Peter Sommerlad and Michael Stal, Stal,<br />
Wiley, 1996<br />
Pattern-Oriented Pattern Oriented Software Architecture, Volume 2: Patterns for Concurrent Concurrent<br />
and Networked<br />
Objects, Objects,<br />
Douglas Schmidt, Michael Stal, Stal,<br />
Hans Rohnert and <strong>Frank</strong> <strong>Buschmann</strong>, Wiley,<br />
2000<br />
Pattern-Oriented Pattern Oriented Software Architecture, Volume 3: Patterns for Resource Management,<br />
Management,<br />
Michael Kircher and Prashant Jain, Wiley, to be published 2004<br />
105
Bibliography<br />
Alexander<br />
A Pattern Language: Towns, Buildings, Construction, Construction,<br />
Christopher Alexander, Sara Ishikawa<br />
and Murray Silverstein, Oxford University Press, 1977<br />
The Timeless Way of Building, Building,<br />
Christopher Alexander, Oxford University Press, 1979<br />
Beck<br />
"Using Pattern Languages for Object-Oriented Object Oriented Programs", Kent Beck and Ward<br />
Cunningham, OOPSLA, OOPSLA,<br />
1987<br />
Smalltalk Best Practice Patterns, Patterns,<br />
Kent Beck, Prentice Hall, 1997<br />
Test-Driven Test Driven Development: By Example, Example,<br />
Kent Beck, Addison-Wesley, Addison Wesley, 2003<br />
Coplien<br />
Advanced C++ Programming Styles and Idioms, Idioms,<br />
James O Coplien, Coplien,<br />
Addison-Wesley, Addison Wesley, 1992<br />
Software Patterns, Patterns,<br />
James O Coplien, Coplien,<br />
SIGS, 1996<br />
Multi-Paradigm Multi Paradigm Design for C++, C++ , James O Coplien, Coplien,<br />
Addison-Wesley, Addison Wesley, 1999<br />
106
Bibliography<br />
<strong>Henney</strong><br />
"Collections for States", <strong>Kevlin</strong> <strong>Henney</strong>, EuroPLoP, EuroPLoP,<br />
1999<br />
"A Tale of Two Patterns", <strong>Kevlin</strong> <strong>Henney</strong>, Java Report, Report,<br />
December 2000<br />
"C++ Patterns: Reference Accounting", <strong>Kevlin</strong> <strong>Henney</strong>, EuroPLoP, EuroPLoP,<br />
2001<br />
"A Tale of Three Patterns", <strong>Kevlin</strong> <strong>Henney</strong>, Java Report, Report,<br />
October 2001<br />
"Methods for States", <strong>Kevlin</strong> <strong>Henney</strong>, VikingPLoP, VikingPLoP,<br />
2002<br />
"Explicit Interface and Object Manager", <strong>Frank</strong> <strong>Buschmann</strong> and <strong>Kevlin</strong> <strong>Kevlin</strong><br />
<strong>Henney</strong>, EuroPLoP, EuroPLoP,<br />
2003<br />
"The Good, the Bad, and the Koyaanisqatsi", Koyaanisqatsi",<br />
<strong>Kevlin</strong> <strong>Henney</strong>, VikingPLoP, VikingPLoP,<br />
2003<br />
"Factory and Disposal Methods", <strong>Kevlin</strong> <strong>Henney</strong>, VikingPLoP, VikingPLoP,<br />
2003<br />
107
Bibliography<br />
Others<br />
Core J2EE Patterns, Patterns,<br />
2 nd edition, Deepak Alur, Alur,<br />
John Crupi and Dan Malks, Malks,<br />
Prentice Hall,<br />
2003<br />
Modern C++ Design, Design,<br />
Andrei Alexandrescu, Alexandrescu,<br />
Addison-Wesley, Addison Wesley, 2001<br />
Object-Oriented Object Oriented Analysis and Design with Applications, Applications,<br />
2 nd edition, Grady Booch, Booch,<br />
Benjamin/Cummings, 1994<br />
Troublesome Words, Words,<br />
3 rd edition, Bill Bryson, 2001<br />
Generative Programming, Programming,<br />
Krzysztof Czarnecki and Ulrich W Eisenecker, Eisenecker,<br />
Addison-Wesley,<br />
Addison Wesley,<br />
2000<br />
"Endo-Testing: "Endo Testing: Unit Testing with Mock Objects", Tim Mackinnon, Steve Freeman Freeman<br />
and<br />
Philip Craig, XP, XP,<br />
2000<br />
Design Patterns for Object-Oriented Object Oriented Software Development, Development,<br />
Wolfgang Pree, Pree,<br />
Addison- Addison<br />
Wesley, 1995<br />
The Design and Evolution of C++, C++ , Bjarne Stroustrup, Stroustrup,<br />
Addison-Wesley, Addison Wesley, 1994<br />
Taligent's Guide to Designing Programs, Programs,<br />
Addison-Wesley, Addison Wesley, 1994<br />
108