05.12.2012 Views

Kevlin Henney Frank Buschmann - HSR-Wiki

Kevlin Henney Frank Buschmann - HSR-Wiki

Kevlin Henney Frank Buschmann - HSR-Wiki

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!