Download presentation
Presentation is loading. Please wait.
Published byMaryann Russell Modified over 9 years ago
1
Design Patterns Behavioral Patterns
2
Chain of Responsibility Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it Use When: –more than on object may handle a request, and the handler isn't known a priori –When you want to issue a request to one of several objects without specifying the receiver explicitly –When the set of objects that can handle a request should be specified dynamically Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it Use When: –more than on object may handle a request, and the handler isn't known a priori –When you want to issue a request to one of several objects without specifying the receiver explicitly –When the set of objects that can handle a request should be specified dynamically
3
Chain of Responsibility
4
Command Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations Use When you need an action as a parameter Commands replace callback functions When you need to specify, queue, and execute requests at different times When you need to support undo When you need to support logging changes Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations Use When you need an action as a parameter Commands replace callback functions When you need to specify, queue, and execute requests at different times When you need to support undo When you need to support logging changes
5
Command
6
Interpreter Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language you create a class for each rule The classes can be used to construct a tree that represents elements of the language Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language you create a class for each rule The classes can be used to construct a tree that represents elements of the language
7
Interpreter
8
Iterator Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation methods: –movenext() –getcur() –eof() Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation methods: –movenext() –getcur() –eof()
9
Iterator
10
The Abstract Node of the List Key is a type which the list is orderd by In most cases its a unique member of the data class type In spit of that Key type can also be more than one member of the data class type ( don’t forget to overload operator > or operator = = ) Data is a poiner to the real object i.e we have here a list of poinetrs to our objects Key is a type which the list is orderd by In most cases its a unique member of the data class type In spit of that Key type can also be more than one member of the data class type ( don’t forget to overload operator > or operator = = ) Data is a poiner to the real object i.e we have here a list of poinetrs to our objects struct Record { Key key; Data data; Record *next; }; struct Record { Key key; Data data; Record *next; };
11
More Private Members bool find_record(const Key& ); Record *first; Record *precedingRecord *candidate Using these three
12
Public Members bool get_data(const Key &,Data &) bool add_data(const Key &,Data &) bool remove_data(const key &) void operator &) bool get_data(const Key &,Data &) bool add_data(const Key &,Data &) bool remove_data(const key &) void operator &)
13
template class List { struct Record { // The abstract node of the list Key key; Data data; Record *next; }; Record *first; // head of the list Record *candidate, *preceding; // for find bool find_record(const Key& ); public: List () : first(NULL) {} ~List() ; bool get_data(const Key&,Data &); bool add_data(const Key&,const Data& ); bool remove_data(const Key& ); friend ostream& operator & ); template class List { struct Record { // The abstract node of the list Key key; Data data; Record *next; }; Record *first; // head of the list Record *candidate, *preceding; // for find bool find_record(const Key& ); public: List () : first(NULL) {} ~List() ; bool get_data(const Key&,Data &); bool add_data(const Key&,const Data& ); bool remove_data(const Key& ); friend ostream& operator & );
14
Get Data template inline bool List ::get_data(const Key& key,Data &data) { if( find_record(key) == true){ data = candidate->data; return true; } return false; } template inline bool List ::get_data(const Key& key,Data &data) { if( find_record(key) == true){ data = candidate->data; return true; } return false; }
15
Add Data template inline bool List ::add_data(const Key& key,const Data& data) { Record *pt; if( (find_record(key) == true)) return false; pt = new Record; assert(pt != NULL); pt->key = key; pt->data = data; if(preceding == NULL){ pt->next = first; first = pt; return true; } pt->next = preceding->next; preceding->next = pt; return true; } template inline bool List ::add_data(const Key& key,const Data& data) { Record *pt; if( (find_record(key) == true)) return false; pt = new Record; assert(pt != NULL); pt->key = key; pt->data = data; if(preceding == NULL){ pt->next = first; first = pt; return true; } pt->next = preceding->next; preceding->next = pt; return true; }
16
Remove Data template inline bool List ::remove_data(const Key& key) { Record *free_me; if( find_record(key) == false ) return false; free_me = candidate; if(preceding == NULL) first = candidate->next; else preceding->next = candidate->next; delete free_me->data; delete free_me; return true; } template inline bool List ::remove_data(const Key& key) { Record *free_me; if( find_record(key) == false ) return false; free_me = candidate; if(preceding == NULL) first = candidate->next; else preceding->next = candidate->next; delete free_me->data; delete free_me; return true; }
17
Find Record template bool List :: find_record(const Key& search_key) { preceding = candidate = NULL; if(first == NULL) return false; // list is empty for(candidate = first; ; ){ if(candidate->key == search_key) return true; if(candidate->key > search_key) return false; if(candidate->next == NULL) { preceding = candidate; return false; } preceding = candidate; candidate = candidate->next; } template bool List :: find_record(const Key& search_key) { preceding = candidate = NULL; if(first == NULL) return false; // list is empty for(candidate = first; ; ){ if(candidate->key == search_key) return true; if(candidate->key > search_key) return false; if(candidate->next == NULL) { preceding = candidate; return false; } preceding = candidate; candidate = candidate->next; }
18
Print All Data template ostream& operator & l) { for(List ::ConstIterator i(l); i ; i++) out << *(*i); return out; } template ostream& operator & l) { for(List ::ConstIterator i(l); i ; i++) out << *(*i); return out; }
19
Delete All Data template List ::~List() { Record *curr,*free_me; if (first == NULL) return; for(curr = first; ; ){ free_me = curr; curr = curr->next; delete free_me; if(curr == NULL) break; } first = NULL; } template List ::~List() { Record *curr,*free_me; if (first == NULL) return; for(curr = first; ; ){ free_me = curr; curr = curr->next; delete free_me; if(curr == NULL) break; } first = NULL; }
20
List::Iterator class ConstIterator { private: const List& m_list; Record *m_current; public: ConstIterator(const List& list) : m_list(list),m_current(NULL) {m_current = m_list.first;} ConstIterator& operator++() { assert(m_current!= NULL); m_current = m_current->next; return *this; } class ConstIterator { private: const List& m_list; Record *m_current; public: ConstIterator(const List& list) : m_list(list),m_current(NULL) {m_current = m_list.first;} ConstIterator& operator++() { assert(m_current!= NULL); m_current = m_current->next; return *this; }
21
const ConstIterator operator++(int) { assert(m_current!= NULL); ConstIterator i(*this); m_current = m_current->next; return i; } operator int() const {return m_current != NULL;} const Data& operator *() { return m_current->data;} const Data& data() {return m_current->data;} const Key& key() {return m_current->key;} }; const ConstIterator operator++(int) { assert(m_current!= NULL); ConstIterator i(*this); m_current = m_current->next; return i; } operator int() const {return m_current != NULL;} const Data& operator *() { return m_current->data;} const Data& data() {return m_current->data;} const Key& key() {return m_current->key;} };
22
The following operators must be defined for the Key type: =(assignment) // This means also copy-constructor = =(equality) >(greater than) The following operators must be defined for the Data type: << (output) The following operators must be defined for the Key type: =(assignment) // This means also copy-constructor = =(equality) >(greater than) The following operators must be defined for the Data type: << (output) Attention !! Can you Tell Why ?
23
Using example class Car{ String name; int eng; int price; public: Car(String s="",int e=0,int p=0):name(s),eng(e),price(p){} friend ostream& operator<<(ostream& out,const Car& c) { return out << "Car Name: "<< c.name << endl << "Eng : " << c.eng << " cc" << endl << "Value : " << c.price << " nis."<< endl; } String get_name() {return name;} }; class Car{ String name; int eng; int price; public: Car(String s="",int e=0,int p=0):name(s),eng(e),price(p){} friend ostream& operator<<(ostream& out,const Car& c) { return out << "Car Name: "<< c.name << endl << "Eng : " << c.eng << " cc" << endl << "Value : " << c.price << " nis."<< endl; } String get_name() {return name;} };
24
class Student{ int id; String name; public: Student(int i=0,String str=""):id(i),name(str) { } Student(istream& std); friend ostream& operator<<(ostream& out,const Student& st) { return out << "Student id : " << st.id << endl << "Student name : " << st.name <<endl; } int get_id() {return id;} }; class Student{ int id; String name; public: Student(int i=0,String str=""):id(i),name(str) { } Student(istream& std); friend ostream& operator<<(ostream& out,const Student& st) { return out << "Student id : " << st.id << endl << "Student name : " << st.name <<endl; } int get_id() {return id;} }; List students; List cars; List students; List cars; Declartion Of Lists
25
Using The Iterator for(List ::ConstIterator it1(students); it1 ; it1++) delete(*it1); for(List ::ConstIterator it2(cars); it2 ; it2++) delete(*it2); for(List ::ConstIterator it1(students); it1 ; it1++) delete(*it1); for(List ::ConstIterator it2(cars); it2 ; it2++) delete(*it2);
26
Mediator Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently Defines an interface for communicating with Colleague objects Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently Defines an interface for communicating with Colleague objects
27
Mediator
28
Memento Without violating encapsulation, capture and externalize an object's internal state so that the object can be returned to this state later Allow undos, rollbacks, etc. But we have Command and Clone, why do we need another pattern for undo? –Clone can be more expensive than we need Only part of the state of an object may change, cloning will copy all the state Cloning can be hard to implement Replacing an object with a clone does not work when other objects have references to the object to rollback Without violating encapsulation, capture and externalize an object's internal state so that the object can be returned to this state later Allow undos, rollbacks, etc. But we have Command and Clone, why do we need another pattern for undo? –Clone can be more expensive than we need Only part of the state of an object may change, cloning will copy all the state Cloning can be hard to implement Replacing an object with a clone does not work when other objects have references to the object to rollback
29
Memento
30
Observer Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. Use the Observer pattern: –When an abstraction has two aspects, one dependent on the other. –When a change to one object requires changing others, and you don't how many objects need to be changed –When an object should be able to notify other objects without making assumptions about who these objects are. Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. Use the Observer pattern: –When an abstraction has two aspects, one dependent on the other. –When a change to one object requires changing others, and you don't how many objects need to be changed –When an object should be able to notify other objects without making assumptions about who these objects are.
31
Observer
32
State Allow an object to alter its behavior when its internal state changes. The object will appear to change its class Use the State pattern in either of the following cases: –An object's behavior depends on its state, and it must change its behavior at run-time depending on that state. –Operations have large, multipart conditional statements that depend on the object's state. Often, several operations will contain this same conditional structure Allow an object to alter its behavior when its internal state changes. The object will appear to change its class Use the State pattern in either of the following cases: –An object's behavior depends on its state, and it must change its behavior at run-time depending on that state. –Operations have large, multipart conditional statements that depend on the object's state. Often, several operations will contain this same conditional structure
33
State
34
Strategy Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from the clients that use it The Strategy pattern should only be used when the variation in behavior is relevant to clients. If this criteria is not satisfied, the additional abstraction and effort necessary to implement the Strategy pattern is not justified Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from the clients that use it The Strategy pattern should only be used when the variation in behavior is relevant to clients. If this criteria is not satisfied, the additional abstraction and effort necessary to implement the Strategy pattern is not justified
35
Strategy
36
Template Method Define the skeleton of an algorithm in an operation, deferring some steps to client subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure. Define the skeleton of an algorithm in an operation, deferring some steps to client subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
37
Template Method
38
Visitor Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates Use When an object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that depend on their concrete classes Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates Use When an object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that depend on their concrete classes
39
The Problem We have a set of Objects. We are writing several algorithms working with these objects. We don’t want the objects to be responsible for their part in the algorithm –It does not look good –Several teams are developing with these classes and we can’t change them easily. We have a set of Objects. We are writing several algorithms working with these objects. We don’t want the objects to be responsible for their part in the algorithm –It does not look good –Several teams are developing with these classes and we can’t change them easily.
40
Example - Animal hospital We have many animals We want to create a dentist class that can treat any animal’s tooth ache Addition of new animals is not so probable Addition of new types of doctors is probable. We have many animals We want to create a dentist class that can treat any animal’s tooth ache Addition of new animals is not so probable Addition of new types of doctors is probable.
41
Solution - 1 Let the damn horse treat itself …. class Horse : public Animal { public: void CureTeeth() { } class Animal { public: void CureTeeth()=0; } Looks ugly !
42
Problems It does not make any sense. –Heeling teeth is not one of the things horses (or any animals) do to themselves. Maybe we can’t change the animal classes –Other groups might be working on it simultaneously. It does not make any sense. –Heeling teeth is not one of the things horses (or any animals) do to themselves. Maybe we can’t change the animal classes –Other groups might be working on it simultaneously.
43
Solution - 2 Void foo(Animal x) { if (x instanceof Horse) { //give a horse teeth treatment } else if (x instanceof Mouse) { //give a mouse teeth treatment } … }
44
Problems Looks bad! Slow RTTI usage is not recommended in good design. Looks bad! Slow RTTI usage is not recommended in good design.
45
A Better Idea - Use Visitor
46
How does it work ?
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.