Wednesday, July 2, 2014

Design Patterns C++

Singleton Pattern
  1. Singleton is a creational design pattern.
  2. A design pattern to provide one and only instance of an object.
  3. Make the constructors of the class private.
  4. Store the object created privately.
  5. Provide access to get the instance through a public method.
  6. Can be extended to create a pool of objects.Program

#include <iostream>
using namespace std;
// Singleton class
class MySingleton {
public:
static MySingleton* iInstance;
public:
static MySingleton* GetInstance();

private:
// private constructor
MySingleton();
};

MySingleton* MySingleton::iInstance = NULL;

MySingleton::MySingleton()
{
   cout << "In construtor ..." << endl;
}
MySingleton* MySingleton::GetInstance()
{
    if ( iInstance == NULL ) {
    iInstance = new MySingleton();
}
  return iInstance;

}

void main()
{
    MySingleton* obj;
    obj = MySingleton::GetInstance();
}
OUTPUT:
In construtor ... (displayed only once)


Factory Pattern
  1. Factory pattern is a creational design pattern.
  2. Idea of the factory patterns is to localize the object creation code.
  3. This prevents disturbing the entire system for a new type introduction.
  4. Typically when a new type is introduced in the system, change is at one place only where the object is created to decide which constructor to use.
  5. Simplest of the factory is introduction of a static method in the base class itself, which creates the required object based on the type.
  6. Other variant is Abstract Factory.
  7. Concrete classes are isolated.
  8. Client need not event know which class is implementing its need.
  9. Static factory - Sample Program
Example:

#include <iostream>
#include <string>

using namespace std;

// Abstract Base Class
class Shape {
public:
virtual void Draw() = 0;
// Static class to create objects
// Change is required only in this function to create a new object type
static Shape* Create(string type);
};

class Circle : public Shape {
public:
void Draw() { cout << "I am circle" << endl; }
friend class Shape;
};


class Square : public Shape {
public:
void Draw() { cout << "I am square" << endl; }
friend class Shape;
};


Shape* Shape::Create(string type) {
if ( type == "circle" ) return new Circle();
if ( type == "square" ) return new Square();
return NULL;
}


void main()
{
// Give me a circle
Shape* obj1 = Shape::Create("circle");


// Give me a square
Shape* obj2 = Shape::Create("square");


obj1->Draw();
obj2->Draw();
}


OUTPUT:
I am circle
I am square

What is Observer Pattern?
  1. Observer pattern is a behavioral design pattern.
  2. Observer pattern is used to solve the problem of notifying multiple objects of a change to keep them in sync like the Model-View-Controller (MVC) concept.
  3. Useful for event management kind of scenarios.
  4. Two classes are involved.
  5. The Observable class is where the actual data change is occuring. It has information about all the interested objects that need to be notified.
  6. The Observer is typically an abstract class providing the interface to which concrete classes interested in the events need to be compliant to.
Sample Program

#include <iostream>
#include <set>

using namespace std;

// ---------------- Observer interface -----------------
class MyObserver {
    public:
        virtual void Notify() = 0;
};

// ---------------- Observable object -------------------
class MyObservable {
        static MyObservable* instance;
        set<MyObserver*> observers;
        MyObservable() { };
    public:
       static MyObservable* GetInstance();
       void AddObserver(MyObserver& o);
       void RemoveObserver(MyObserver& o);
       void NotifyObservers();
       void Trigger();
};

MyObservable* MyObservable::instance = NULL;

MyObservable* MyObservable::GetInstance()
{
    if ( instance == NULL ) {
       instance = new MyObservable();
    }

    return instance;
}

void MyObservable::AddObserver(MyObserver& o)
{
    observers.insert(&o);
}

void MyObservable::RemoveObserver(MyObserver& o)
{
    observers.erase(&o);
}

void MyObservable::NotifyObservers()
{
    set<MyObserver*>::iterator itr;
    for ( itr = observers.begin();
          itr != observers.end(); itr++ )
    (*itr)->Notify();
}

// TEST METHOD TO TRIGGER
// IN THE REAL SCENARIO THIS IS NOT REQUIRED
void MyObservable::Trigger()
{
    NotifyObservers();
}

// ------ Concrete class interested in notifications ---
class MyClass : public MyObserver {

        MyObservable* observable;

    public:
       MyClass() {
          observable = MyObservable::GetInstance();
          observable->AddObserver(*this);
       }

       ~MyClass() {
          observable->RemoveObserver(*this);
       }

       void Notify() {
            cout << "Received a change event" << endl;
       }
};

void main()
{
    MyObservable* observable = MyObservable::GetInstance();
    MyClass* obj = new MyClass();
    observable->Trigger();
}

OUTPUT: 
Received a change event

1 comment: