cse 332: design patterns review: design pattern structure a design pattern has a name –so when...

14
CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name So when someone says “Adapter” you know what they mean So you can communicate design ideas as a “vocabulary” A design pattern describes the core of a solution to a recurring design problem So you don’t have to reinvent known design techniques So you can benefit from others’ (and your) prior experience A design pattern is capable of generating many distinct design decisions in different circumstances So you can apply the pattern repeatedly as appropriate So you can work through different design problems using it

Upload: meredith-miles

Post on 05-Jan-2016

218 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Review: Design Pattern Structure

• A design pattern has a name– So when someone says “Adapter” you know what they mean– So you can communicate design ideas as a “vocabulary”

• A design pattern describes the core of a solution to a recurring design problem– So you don’t have to reinvent known design techniques– So you can benefit from others’ (and your) prior experience

• A design pattern is capable of generating many distinct design decisions in different circumstances– So you can apply the pattern repeatedly as appropriate– So you can work through different design problems using it

Page 2: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Three More Design Patterns

• Singleton (creational)– Provides access to a single (or indexed) instance

• Prototype (creational)– Polymorphic duplication of heterogeneous types

• Visitor (behavioral)– Allows interaction with heterogeneous collections– Compile time dispatching is standard, but can

emulate with dynamic type casting or RTTI

Page 3: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Creational Patterns

• Help define how objects are created/initialized

• May emphasize class or interaction diagrams

• Examples– Factory Method– Singleton– Prototype

Page 4: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Single Global Instance

• Challenges– Only one object of a type is needed or allowed in a program– Whether or not the object is needed at all may vary– Need to make sure the object is initialized before first use

• Motivates use of the Singleton pattern– Instantiates the object on-demand (if requested)

• If no request is made, the object is never created (efficient)

– Makes it easy to obtain an alias from anywhere in program• Don’t need to pass a reference/pointer up and down the call stack

– Initializes object before first alias to it is handed out• Lifetime of the object covers interval of its possible use

Page 5: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Singleton Pattern• Problem

– Want to ensure a single instance of a class, that’s shared by all uses throughout a program (e.g., the Portfolio, the Zoo)

• Context– Need to address ordering of initialization versus usage– E.g., usage from different source files than where the object is defined

• Solution core– Static pointer member variable is initialized to 0 (before main starts)– Provide a global access method (static member function)– First use of the access method instantiates object, updates pointer– Constructors for instance can be hidden (made private)– Can hide destructor too if a “fini” or “destroy” method is also provided

• Consequences– Object is never created if it’s never used– Object is shared efficiently among all uses

Page 6: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Basic Use of the Singleton Patternclass Portfolio {

public:

static Portfolio * instance();

static void fini(); 

// . . .

private: 

static Portfolio * instance_;

  Portfolio ();

virtual ~Portfolio ();

// . . .

};

Portfolio * Portfolio::instance_ = 0;

Portfolio * Portfolio::instance() {

if (instance_ == 0){

instance_ = new Portfolio;

}

return instance_;

}

void Portfolio::fini() {

delete instance_;

instance_ = 0;

}

int main (int, char * []) {  try {  Stock *s = new Stock ("Alice's Restaurant", 20, 7, 11, 13); Bond *b = new Bond ("City Infrastructure", 10, 2, 3, 5); Portfolio::instance()->add (s); Portfolio::instance()->add (b); Portfolio::instance()->print (); Portfolio::fini(); } catch (Portfolio::error_condition &e) { cout << "Portfolio error: " << e << endl; return -1; } catch (...) { cout << "unknown error" << endl; return -2; }  return 0;}

Page 7: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

An Indexed Variation of the Singleton Patternclass Portfolio {

public:

static Portfolio * instance(Agent *);

static void fini(Agent *);

...

private: 

static map<Agent *, Portfolio *> instances_;

Portfolio ();

virtual ~Portfolio ();

...

};

map<Agent *, Portfolio *> Portfolio::instances_;

Portfolio * Portfolio::instance(Agent *a) {

Portfolio * p = 0;

map<Agent *, Portfolio *>::iterator i =

instances_.find(a);

if (i == instances_.end()) {

p = new Portfolio;

instances_.insert(make_pair(a,p));

} else { p = i->second; }

return p;

}

void Portfolio::fini(Agent *a) { map<Agent*,Portfolio*>:: iterator i = instances_.find(a); if (i != instances_.end()) { Portfolio * p = i->second; instances_.erase(i); delete p; }}

void Agent::buy (Security *s) { int cost = s->shares_ * s->current_value_; if (cost > reserve_) { throw cannot_afford; }Portfolio::instance(this)-> add(s); reserve_ -= cost; }

Agent::~Agent () { Portfolio::fini(this);}

Page 8: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Polymorphic (Deep) Copying

• Challenges– C++ does not have a virtual copy constructor– However, may need to duplicate polymorphic collections

• All the securities in a portfolio (which are actually stocks or bonds)• All the animals in a zoo (which are actually Giraffes or Ostriches)

– Copy construction depends on the concrete types involved

• Motivates use of the Prototype pattern– Wraps copy construction within a common virtual method– Each subclass overrides that method: uses its specific copy

constructor with dynamic allocation to “clone” itself

Page 9: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Prototype Pattern• Problem

– Need to duplicate objects with different dynamic types

• Context– Virtual constructors are not available (e.g., in C++)– However, polymorphic method invocations are supported

• Solution core– Provide a polymorphic method that returns an instance of

the same type as the object on which the method is called– Polymorphic method calls copy constructor, returns base

class pointer or reference to concrete derived type

• Consequences– Emulates virtual copy construction behavior– Allows anonymous duplication of heterogeneous types

Page 10: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Use of the Prototype Pattern

struct Security {

public:

virtual Security * clone () = 0;

...

};

Security * Stock::clone () {

return new Stock(*this);

}

Security * Bond::clone () {

return new Bond(*this);

}

Security * Agent::sell (Security *s) {

Security * current = Portfolio::instance(this)->find(s);

if (current ==0) { throw cannot_provide; }

Security * copy = current->clone();

Portfolio::instance(this)->remove(current);

reserve_ += copy->shares_ * copy->current_value_;

return copy;}

Page 11: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Interacting with Heterogeneous Collections

• Challenges– Polymorphism lets you aggregate different types together– However, how to interact depends on the specific types

• Motivates use of the Visitor pattern– Lets the program discover how to interact with each

concrete type through an initial “handshake” with it– Dispatches that interaction directly through a method call

Page 12: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Visitor Pattern• Problem

– We have a heterogeneous collection of objects over which we need to perform type-specific operations

• Context– Run-time type identification (if available) adds overhead– Want to avoid unnecessary interactions among types – Types in collection change less frequently than the set of operations that

are to be performed over them

• Solution core– Modify types in the collection to support double dispatch– If you cannot, RTTI / dynamic casting can be used similarly (a variant?)

• Consequences– Once modified in this way, any of the types can handshake with arbitrary

“visitors” to give correct behavior

Page 13: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Basic Use of the Visitor Patternstruct SecurityVisitor {

virtual ~SecurityVisitor();

virtual void

visit_stock (Stock *) = 0;

virtual void

visit_bond (Bond *) = 0;

};

struct Security {

… 

virtual void

accept (SecurityVisitor * sv) = 0;

};

void

Stock::accept (SecurityVisitor * sv) {

if (sv) {sv->visit_stock(this);}

}

void

Bond::accept (SecurityVisitor * sv) {

if (sv) {sv->visit_bond(this);}

}

struct ProjectedValueFunctor : public SecurityVisitor { int & value_; ProjectedValueFunctor (int & value); virtual ~ProjectedValueFunctor (); void operator () (Security * s) { s->accept(this); } virtual void visit_stock (Stock * s) { if (s) {value_ += s->shares_ * (s->projected_value_ + s->dividend_);} } virtual void visit_bond (Bond * b) { if (b) {value_ += b->shares_ * (b->projected_value_ + b->interest_);} }};

int Portfolio::projected_value () { int value = 0; for_each (securities_.begin(), securities_.end(), ProjectedValueFunctor(value)); return value;}

Page 14: CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can

CSE 332: Design Patterns

Design Patterns Summary• We’ve looked at a number of patterns this semester

– Iterator: access elements sequentially no matter how stored– Factory method: create a related type polymorphically– Adapter: converts an interface you have into one you want– Memento: packages up object state without violating encapsulation– Observer: tell registered observers when state changes

– Singleton: provides access to a single instance (possibly per index)– Prototype: allows polymorphic duplication of heterogeneous types– Visitor: allows interaction with heterogeneous collections

• Think about how patterns can drive design– From basic abstractions towards a working program with refinements– Lab 5 will involve the Singleton and Memento patterns– CSE 432 focuses on combining patterns of this sort (design)– CSE 532 focuses on other kinds of patterns (architectural)