Chapter 5 Design Patterns

Bernard Chen Spring 2006

Objective
  


 

What is Design Pattern Functor Wrapper Adapter Iterator Observer

1 What is a pattern?  A design pattern   describes a problem that occurs over and over in software engineering and then describes the solution in a sufficiently generic manner as to be applicable in a wide variety of contexts. .5.

Typical pattern format     The pattern name The problem  Specification of  Explanation why it is important  Applications  Examples of known uses The solution  A description of classes possibly with a structure diagram  A language independent implementation. with language-specific issues as appropriate  Sample code Consequences  Results  Trade-offs of using the pattern  A discussion of related patterns .

5. An instance of the class is passed to the algorithm .2 The Functor (function object)  Functor (function object) contains a method specified by the generic algorithm.

i++) { if(a[maxIndex] < a[i]) { //undefined for uncomparable maxIndex = i.size().5. for(int i=1. } // a generic findMax algorithm. //objects such as shape.2 The Functor (function object) template <class Comparable> const Comparable & findMax(const vector<Comparable> & a) { int maxIndex = 0. i< a. which works only for // Comparable objects and uses their natural order. } } return a[maxIndex]. .

2 The Functor (function object)    Even we define operator< for shapes based on area. Now the main issue is how to pass the comparison function.5. we are stuck with it. or perimeter. The solution is to pass the comparison function as a parameter to findMax and have findMax use the comparison function instead of assuming the existence of an opearator<.– use a function object . What if we want to have findMax work with several different comparison alternatives.

5. Function object is usually used as a replacement for a comparison operator (<.etc. It can be passed to a function as a parameter.).2 The Functor (function object)    It solves the problem of the comparison of the data type lacking of the definition of operator<. !=. . which in turn calls the single method of the function object. and provides multiple comparison alternatives.

int main(){ vector<Rectangle> a. i < a. return a[maxIndex]. Comparator comp){ int maxIndex = 0. } class LessThanByWidth{ public: bool isLessThan(const Rectangle & lhs. … } .getWidth(). a[i]) ) // if(a[maxIndex] < a[i]) maxIndex = i. … cout<<findMax(a. const Rectangle & rhs) const {return lhs. i++) if(comp. for(int i = 1.size().template <class Object.} }.isLessThan(a[maxIndex]. class Comparator> const Object & findMax (const vector<Object>& a.getWidth() < rhs.LessThanByWidth()).

Sometimes. it is used to provide a simpler interface.3 Adapters and Wrappers   A wrapper class stores a primitive type and adds operations that the primitive type does not support or supports incorrectly. . the implementation technique is similar. At other times it is used simply to change some method names. An adapter class is used when the interface of a class is not exactly what is needed. In either case.5.

}. template<class Comparable> class MyPointer{ public: explicit MyPointer(Comparable *rhs = NULL) : pointee(rhs) {} bool operator< (const MyPointer & rhs) const {return *pointee < *rhs. .Example of Wrapper: Smart Pointer • Smart pointer class: encapsulates the behavior of a pointer. which automatically initializes itself to NULL if no initial value is provided.} private: Comparable *pointee.pointee.

So auto_ptr frees programmers from writing code to keep track and delete memory returned from a new operator. .  It helps automatically delete dynamically allocated object.Example of Wrapper: Auto-pointers  New standard C++ pointers call auto_ptr which wraps a pointer in an object. and its destructor calls delete.

If it is the owner. . When a copy is performed. It also indicates whether it is the owner of the pointer. therefore. it is safe to delete the pointer without ownership. ownership is transferred (-. then when its destructor is called it must apply the delete operator to the pointer.Auto-pointers  Basic property: It wraps the pointer variable.only one of them can be the owner.

. . .. // whoever call this function must //delete the return pointer } void func(){ Object *obj = func1().. . // avoid memory leakage } . } // must delete pointer before return Scenario 2: We need to delete an object created and returned from a completed function call Object *func1(){ Object *obj = new Object(…).Auto-Pointer: Scenario 1 & 2 Scenario 1: We need to delete a local dynamically allocated object void func() { Object *obj = new Object(…).. delete obj.. delete obj.. return obj. return.

delete obj. .Auto-Pointer: Scenario 3  We need to delete a dynamically allocated object created by the calling function void func(Object *obj){ ... . func(obj1).. } ... } void func1(){ Object *obj1 = new Object(…)..

or some of the existing class functions need to be disabled for new applications. . Needs for adapter arise when the implementation of an existing class fits some application but its interface is not.Adapters   The adapter pattern is used to change the interface of an existing class to conform another.

// An adapter class that changes the MemoryCell interface to use get and put template <class Object> class MemoryCell{ public: explicit MemoryCell(const Object & initVal = Object()) :storedValue(initVal){} const Object & read() const {return storedValue.template <class Object> class StorageCell : private MemoryCell<Object>{ public: explicit StorageCell(const Object & initialValue = Object()) : MemoryCell<Object>(inititalValue){} const Object & get() const { return read().} }.} private: Object storedValue.} void put(const Object & x) { write(x).8 . // figure 3.} void write(const Object & x) {storedValue = x. }.

4 Iterators  An object that controls iteration of a collection. i<v.5.size(). i++) cout<< v[i] << endl. Example: for(int i=0. //i is an iterator .

   The index in an array is an iterator. Iterators provide an abstract mechanism for iterating a collection of objects.. but it works only in an arraylike structure.Iterators Cont. . The code that performs access of the container should be independent of the type of the container as possible.

push_back(3). v. v.getIterator().push_back(2). return 0..next()<<endl.hasNext()) cout<<itr. int main() { MyVector<int> v.Iterators Cont. while(itr. }// illustration of Design 1 . cout<< “Vector Contents ”<<endl. VectorIterator<int> itr = v.

The observers are informed when something interesting happens to the subject (ex: a click on the close button in a window triggers the previous hidden window to be redrawn) .6 Observer  Observer patterns involve a subject and a set of observers.5.

Sign up to vote on this title
UsefulNot useful