Beruflich Dokumente
Kultur Dokumente
Objective
5. 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.
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
Functor (function object) contains a method specified by the generic algorithm. An instance of the class is passed to the algorithm
Even we define operator< for shapes based on area, or perimeter, we are stuck with it. What if we want to have findMax work with several different comparison alternatives. 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<. Now the main issue is how to pass the comparison function. use a function object
It solves the problem of the comparison of the data type lacking of the definition of operator<, and provides multiple comparison alternatives. It can be passed to a function as a parameter, which in turn calls the single method of the function object. Function object is usually used as a replacement for a comparison operator (<, !=,etc.).
template <class Object, class Comparator> const Object & findMax (const vector<Object>& a, Comparator comp){ int maxIndex = 0; for(int i = 1; i < a.size(); i++) if(comp.isLessThan(a[maxIndex], a[i]) ) // if(a[maxIndex] < a[i]) maxIndex = i; return a[maxIndex]; } class LessThanByWidth{ public: bool isLessThan(const Rectangle & lhs, const Rectangle & rhs) const {return lhs.getWidth() < rhs.getWidth();} }; int main(){ vector<Rectangle> a; cout<<findMax(a,LessThanByWidth()); }
A wrapper class stores a primitive type and adds operations that the primitive type does not support or supports incorrectly. An adapter class is used when the interface of a class is not exactly what is needed. Sometimes, it is used to provide a simpler interface. At other times it is used simply to change some method names. In either case, the implementation technique is similar.
New standard C++ pointers call auto_ptr which wraps a pointer in an object, and its destructor calls delete.
It helps automatically delete dynamically allocated object. So auto_ptr frees programmers from writing code to keep track and delete memory returned from a new operator.
Auto-pointers
Basic property: It wraps the pointer variable. It also indicates whether it is the owner of the pointer. If it is the owner, then when its destructor is called it must apply the delete operator to the pointer. When a copy is performed, ownership is transferred (-- only one of them can be the owner, therefore, it is safe to delete the pointer without ownership.
Auto-Pointer: Scenario 3
void func(Object *obj){ ... delete obj; } void func1(){ Object *obj1 = new Object(); ... func(obj1); ... }
Adapters
The adapter pattern is used to change the interface of an existing class to conform another. Needs for adapter arise when the implementation of an existing class fits some application but its interface is not, or some of the existing class functions need to be disabled for new applications.
template <class Object> class StorageCell : private MemoryCell<Object>{ public: explicit StorageCell(const Object & initialValue = Object()) : MemoryCell<Object>(inititalValue){} const Object & get() const { return read();} void put(const Object & x) { write(x);} };// 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;} void write(const Object & x) {storedValue = x;} private: Object storedValue; }; // figure 3.8
5.4 Iterators
Example: for(int i=0; i<v.size(); i++) cout<< v[i] << endl; //i is an iterator
Iterators Cont..
The index in an array is an iterator, but it works only in an arraylike structure. Iterators provide an abstract mechanism for iterating a collection of objects. The code that performs access of the container should be independent of the type of the container as possible.
Iterators Cont..
int main() { MyVector<int> v; v.push_back(3); v.push_back(2); cout<< Vector Contents <<endl; VectorIterator<int> itr = v.getIterator(); while(itr.hasNext()) cout<<itr.next()<<endl; return 0; }// illustration of Design 1
5.6 Observer
Observer patterns involve a subject and a set of observers. 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)