Post on 17-Jan-2016
Design PatternsDesign Patterns
Solving problems with already Solving problems with already known solutionsknown solutions
Unit - 13Unit - 13
Unit IntroductionUnit Introduction
This unit covers design patterns This unit covers design patterns using C++using C++
Unit ObjectivesUnit Objectives
After covering this unit you will After covering this unit you will understand…understand…
What are design patternsWhat are design patterns Singleton design patternSingleton design pattern Factory design patternFactory design pattern Proxy design patternProxy design pattern Facade design patternFacade design pattern
Design PatternsDesign Patterns
A design pattern is a special way of A design pattern is a special way of solving a particular class of problemssolving a particular class of problems
A design pattern has four essential A design pattern has four essential elementselements The The Pattern NamePattern Name is a handle, which is is a handle, which is
used to describe a design problem, its used to describe a design problem, its solution and consequences.solution and consequences.
The The Problem Problem describes, when to apply describes, when to apply the pattern the pattern
Design Patterns (contd.)Design Patterns (contd.)
The The Solution Solution describes the elements describes the elements the makeup the design, their the makeup the design, their responsibilities, and collaborationsresponsibilities, and collaborations
The The ConsequencesConsequences are the results and are the results and trade off of applying the patterntrade off of applying the pattern
SingletonSingleton
This pattern is a way to provide, one This pattern is a way to provide, one and only one instance of an objectand only one instance of an object
Prevent from having any way to Prevent from having any way to create an object except the provided create an object except the provided wayway
Declare all constructors as private, Declare all constructors as private, and create at least one constructor to and create at least one constructor to prevent the compiler from prevent the compiler from synthesizing a default constructorsynthesizing a default constructor
Example: SingletonExample: Singleton#include <iostream>#include <iostream>
class Singleton class Singleton
{{
private: private:
static Singleton sm_s;static Singleton sm_s;
int m_i;int m_i;
Singleton(int x) : m_i(x) { }Singleton(int x) : m_i(x) { }
public:public:
static Singleton& GetHandle() { return sm_s;static Singleton& GetHandle() { return sm_s; }}
int GetValue() { return m_i; }int GetValue() { return m_i; }
void SetValue(int x) { m_i = x; }void SetValue(int x) { m_i = x; }
};};
Singleton Singleton::sm_s(47); Singleton Singleton::sm_s(47); // initialize static member// initialize static member
// variable// variable
Example: Singleton Example: Singleton (contd.)(contd.)
void main() void main()
{{
Singleton& sObj = Singleton::GetHandle();Singleton& sObj = Singleton::GetHandle();
cout << sObj.GetValue() << endl; cout << sObj.GetValue() << endl; // prints 47// prints 47
Singleton& sObj2 = Singleton::GetHandle();Singleton& sObj2 = Singleton::GetHandle();
sObj2.SetValue(9);sObj2.SetValue(9);
cout << sObj.GetValue() << endl; cout << sObj.GetValue() << endl; // prints 9// prints 9
}}
FactoryFactory
Encapsulate object creationEncapsulate object creation Create objects through a common Create objects through a common
interface rather than to allow the interface rather than to allow the creation code to be spread throughout creation code to be spread throughout programprogram
All the code in a program must go All the code in a program must go through factory whenever it needs to through factory whenever it needs to create one of objectscreate one of objects
Adding a new object modifies factoryAdding a new object modifies factory
Example: FactoryExample: Factory#include <iostream>#include <iostream>
#include <string>#include <string>
#include <exception>#include <exception>
#include <vector>#include <vector>
class Shape class Shape
{{
public:public:
virtual void Draw() = 0;virtual void Draw() = 0;
virtual void Erase() = 0;virtual void Erase() = 0;
virtual ~Shape() {}virtual ~Shape() {}
class BadShapeCreation : public exception class BadShapeCreation : public exception
{{
string m_reason;string m_reason;
public:public:
BadShapeCreation(string type) BadShapeCreation(string type)
{{
Example: Factory Example: Factory (contd.)(contd.)
m_reason = "Cannot create type "+ m_reason = "Cannot create type "+ type;type;
}}
~BadShapeCreation() throw() {}~BadShapeCreation() throw() {}
const char *what() const throw() const char *what() const throw()
{ {
return m_reason; return m_reason;
}}
};};
static Shape* Factory(string type) static Shape* Factory(string type) // exception // exception handlehandle
throw(BadShapeCreation);throw(BadShapeCreation);
}; }; // declaration of Shape class ends here// declaration of Shape class ends here
class Circle : public Shape class Circle : public Shape
{{
Circle() {} Circle() {} // Private constructor// Private constructor
friend class Shape;friend class Shape;
Example: Factory Example: Factory (contd.)(contd.) public:public:
void Draw() { cout << "Circle::draw\n"; }void Draw() { cout << "Circle::draw\n"; }
void Erase() { cout << "Circle::erase\n"; }void Erase() { cout << "Circle::erase\n"; }
~Circle() { cout << "Circle::~Circle\n"; }~Circle() { cout << "Circle::~Circle\n"; }
};};
class Square : public Shape class Square : public Shape
{{
Square() {}Square() {}
friend class Shape;friend class Shape;
public:public:
void Draw() { cout << "Square::draw\n"; }void Draw() { cout << "Square::draw\n"; }
void Erase() { cout << "Square::erase\n"; }void Erase() { cout << "Square::erase\n"; }
~Square() { cout << "Square::~Square\n"; }~Square() { cout << "Square::~Square\n"; }
};};
Shape* Shape::Factory(string type) Shape* Shape::Factory(string type) // exception handle// exception handle
throw(Shape::BadShapeCreation) throw(Shape::BadShapeCreation)
Example: Factory Example: Factory (contd.)(contd.)
{{
if(type == "Circle") return new Circle;if(type == "Circle") return new Circle;
if(type == "Square") return new Square;if(type == "Square") return new Square;
throw BadShapeCreation(type);throw BadShapeCreation(type);
}}
char* p_Shlist[] = { "Circle", "Square", "Square",char* p_Shlist[] = { "Circle", "Square", "Square",
"Circle", "Circle", "Circle", "Square", "Circle", "Circle", "Circle", "Square", "" };"" };
void main() void main()
{{
vector<Shape*> shapes;vector<Shape*> shapes;
try try
{{
for(char** cp = p_Shlist; **cp; cp++)for(char** cp = p_Shlist; **cp; cp++)
shapes.push_back(Shape::Factory(**cp));shapes.push_back(Shape::Factory(**cp));
} }
Example: Factory Example: Factory (contd.)(contd.)
catch(Shape::BadShapeCreation e) catch(Shape::BadShapeCreation e)
{{
cout << e.what() << endl;cout << e.what() << endl;
return 1;return 1;
}}
for(int i = 0; i < shapes.size(); i++) for(int i = 0; i < shapes.size(); i++)
{{
shapes[i]->Draw();shapes[i]->Draw();
shapes[i]->Erase();shapes[i]->Erase();
}}
} }
ProxyProxy
Proxy pattern is used to control Proxy pattern is used to control access to the actual implementationaccess to the actual implementation
Proxy is a surrogate class that hides Proxy is a surrogate class that hides the implementation classthe implementation class
A call made to proxy class is A call made to proxy class is delegated to the implementation delegated to the implementation classclass
Example: ProxyExample: Proxy#include <iostream>#include <iostream>
class Graphicclass Graphic
{{
public:public:
virtual ~Graphic();virtual ~Graphic();
virtual void Draw (const Point& at) = 0;virtual void Draw (const Point& at) = 0;
virtual const Point& GetExtent() = 0;virtual const Point& GetExtent() = 0;
virtual void Load (istream& from) = 0;virtual void Load (istream& from) = 0;
protected:protected:
Graphic();Graphic();
};};
class Image : public Graphic class Image : public Graphic
{{
Example: Proxy (contd.)Example: Proxy (contd.) public:public:
Image(const char* p_File);Image(const char* p_File); // Load Image from File// Load Image from File
virtual ~Image();virtual ~Image();
virtual void Draw (const Point& at);virtual void Draw (const Point& at);
virtual const Point& GetExtent();virtual const Point& GetExtent();
virtual void Load (istream& from);virtual void Load (istream& from);
private:private:
// own private data// own private data
};};
class ImageProxy : public Graphic class ImageProxy : public Graphic
{{
public:public:
ImageProxy(const char* p_File);ImageProxy(const char* p_File);// Load Image from File// Load Image from File
virtual ~ImageProxy();virtual ~ImageProxy();
virtual void Draw (const Point& at);virtual void Draw (const Point& at);
Example: Proxy (contd.)Example: Proxy (contd.)virtual const Point& GetExtent();virtual const Point& GetExtent();
virtual void Save (ostream& to);virtual void Save (ostream& to);
protected:protected:
Image* GetImage();Image* GetImage();
private:private:
// own private data// own private data
Image* m_pImage;Image* m_pImage;
Point m_Extent;Point m_Extent;
char* m_pFileName;char* m_pFileName;
};};
ImageProxy::ImageProxy(const char* p_FileName)ImageProxy::ImageProxy(const char* p_FileName)
{{
m_pFileName = strdup(p_Filename);m_pFileName = strdup(p_Filename);
m_Extent = Point::Zero;m_Extent = Point::Zero; // Don’t know extent yet// Don’t know extent yet
m_pImage = new Image(m_pFileName);m_pImage = new Image(m_pFileName);
}}
Example: Proxy (contd.)Example: Proxy (contd.)const Point& ImageProxy::GetExtent()const Point& ImageProxy::GetExtent()
{{
if (m_Extent == Point::Zero)if (m_Extent == Point::Zero)
{{
m_Extent = GetImage()->GetExtent();m_Extent = GetImage()->GetExtent();
}}
return m_Extent;return m_Extent;
}}
void ImageProxy::Draw(const Point& at)void ImageProxy::Draw(const Point& at)
{{
GetImage()->Draw(at);GetImage()->Draw(at);
}}
Example: Proxy (contd.)Example: Proxy (contd.)void ImageProxy::Load (istream& from)void ImageProxy::Load (istream& from)
{{
from >> m_Extent >> m_pFileName;from >> m_Extent >> m_pFileName;
}}
class TextDocument class TextDocument
{{
public:public:
TextDocument();TextDocument();
void Insert(Graphic*);void Insert(Graphic*);
//… more functions//… more functions
};};
void main()void main()
{{
TextDocument* p_Text = new TextDocument;TextDocument* p_Text = new TextDocument;
p_Text->Inert(new ImageProxy(“AnImageFile.jpg”));p_Text->Inert(new ImageProxy(“AnImageFile.jpg”));
}}
FacadeFacade
Provide a unified interface to a set of Provide a unified interface to a set of interfaces in a subsysteminterfaces in a subsystem
Defines a higher level interface the Defines a higher level interface the makes the sub systems easier to usemakes the sub systems easier to use
Facade reduces the complexityFacade reduces the complexity Minimise communication and Minimise communication and
dependencies among sub systemsdependencies among sub systems Useful when layering sub systemsUseful when layering sub systems
Example: FacadeExample: Facadeinclude <iostream>include <iostream>
// following classes perform different functions required for// following classes perform different functions required for
// compiling a program// compiling a program
class Scannerclass Scanner // Reads input// Reads input
{{
};};
class Parser class Parser // Parse input// Parse input
{{
};};
class ProgramNodeBuilder class ProgramNodeBuilder // Build Nodes// Build Nodes
{{
};};
class CodeGenerator class CodeGenerator // Generates code// Generates code
{{
};};
Example: Facade (contd.)Example: Facade (contd.)class Compilerclass Compiler
{{
public:public:
Compiler();Compiler();
virtual void Compile(istream&, BytecodeStream&);virtual void Compile(istream&, BytecodeStream&);
};};
// Facade implementation// Facade implementation
void Compiler::Compile(istream& input, BytecodeStream outp)void Compiler::Compile(istream& input, BytecodeStream outp)
{{
Scanner scanner(input); Scanner scanner(input);
ProgramNodeBuilder builder;ProgramNodeBuilder builder;
Parser parser;Parser parser;
parser.Parse(scanner, builder);parser.Parse(scanner, builder);
RISCCodeGenerator generator(outp);RISCCodeGenerator generator(outp);
}}
Unit SummaryUnit Summary
In this unit you have covered …In this unit you have covered … What are design patternsWhat are design patterns Singleton, Factory, Proxy and Singleton, Factory, Proxy and
Facade design patterns using C++ Facade design patterns using C++