Observer Pattern

Intent of Observer Design Pattern is to Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Observer pattern comes under Behavioral Pattern.

SAMPLE CODE:

#include <iostream>
#include <vector>
#include <unistd.h>
#include <time.h>

using namespace std;

class Subject;

class Observer {
public:
    string name;
    virtual void update() = 0;
};

class Subject {
private:
        vector <Observer*> observers;

public:
    void attach(Observer* obser)
    {
        observers.push_back(obser);
        cout << obser->name << " Suscribed To Get Notification" << endl << endl;
    }

    void detach(Observer* obser)
    {
        int observerCount = observers.size();
        for (int i = 0; i < observerCount; i++) {
            if (observers[i] == obser) {
                observers.erase(observers.begin() + i);
                cout << obser->name << " Unsuscribed From Receiving Notification" << endl;
                break;
            }
        }
    }

    void notify()
    {
        time_t now = time(NULL);
        struct tm * curtime = localtime(&now);
        cout << asctime(curtime);

        int observerCount = observers.size();
        for (int i = 0; i < observerCount; i++) {
            observers[i]->update();
        }
    }

};

class OfferPage : public Subject {
private:
    string  productName;
    double  actualPrice;
    double  offerPrice;

public:
    void setOffer(string product, int actual, int offer)
    {
        productName = product;
        actualPrice = actual;
        offerPrice = offer;
    }

    string getProduct()
    {
        return productName;
    }

    int getActualPrice()
    {
        return actualPrice;
    }

    int getOfferPrice()
    {
        return offerPrice;
    }
};

class GmailUsers : public Observer {
private:
    OfferPage* offerOfDay;

public:
    GmailUsers(OfferPage* offer)
    {
        name = "Gmailusers";
        offerOfDay = offer;
    }

    void update()
    {
        string product = offerOfDay->getProduct();
        double actPrice = offerOfDay->getActualPrice();
        double offPrice = offerOfDay->getOfferPrice();
        cout << "----> Sent TO Gmail Users" << endl;
        cout << "  Offer Of The Day - " << product << endl;
        cout << "    Actual Price   - " << actPrice << " USD" << endl;
        cout << "    Offer Price    - " << offPrice << " USD" << endl;
        cout << "    Savings        - " << (actPrice - offPrice) << " USD" << endl ;
    }
};

class YahooUsers : public Observer {
private:
    OfferPage* offerOfDay;
    
public:
    YahooUsers(OfferPage* offer)
    {
        name = "YahooUsers";
        offerOfDay = offer;
    }

    void update()
    {
        string product = offerOfDay->getProduct();
        double actPrice = offerOfDay->getActualPrice();
        double offPrice = offerOfDay->getOfferPrice();
        cout << "----> Sent TO Yahoo Users" << endl;
        cout << "  Offer Of The Day - " << product << endl;
        cout << "    Actual Price   - " << actPrice << " USD" << endl;
        cout << "    Offer Price    - " << offPrice << " USD" << endl;
        cout << "    Savings        - " << (actPrice - offPrice) << " USD" << endl << endl;
    }
};

int main()
{
    OfferPage todayOffer;
    todayOffer.setOffer("IPHONE 5S", 740, 725);

    Observer* gmailSuscriber = new GmailUsers(&todayOffer);
    todayOffer.attach(gmailSuscriber);
    Observer* yahooSuscriber = new YahooUsers(&todayOffer);
    todayOffer.attach(yahooSuscriber);

    todayOffer.notify();

    sleep(5);
    todayOffer.setOffer("Dell Laptop", 850, 839);
    todayOffer.notify();

    return 0;
}


OUTPUT:

Gmailusers Suscribed To Get Notification

YahooUsers Suscribed To Get Notification

Sun Oct  4 14:00:13 2015
----> Sent TO Gmail Users
  Offer Of The Day - IPHONE 5S
    Actual Price   - 740 USD
    Offer Price    - 725 USD
    Savings        - 15 USD
----> Sent TO Yahoo Users
  Offer Of The Day - IPHONE 5S
    Actual Price   - 740 USD
    Offer Price    - 725 USD
    Savings        - 15 USD

Sun Oct  4 14:00:18 2015
----> Sent TO Gmail Users
  Offer Of The Day - Dell Laptop
    Actual Price   - 850 USD
    Offer Price    - 839 USD
    Savings        - 11 USD
----> Sent TO Yahoo Users
  Offer Of The Day - Dell Laptop
    Actual Price   - 850 USD
    Offer Price    - 839 USD
    Savings        - 11 USD


                                               INDEX - OTHER DESIGN PATTERNS

Facade Pattern

According to Gang Of Four intent of Facade Design pattern is to Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.

SAMPLE CODE:

#include <iostream>

using namespace std;

class PreprocessorSystem {
public:
    void doPreprocess()
    {
        cout << "--->Program In Preprocessing Stage" << endl;
    }
};

class CompilerSystem {
public:
    void doCompile()
    {
        cout << "--->Program In Compile Stage" << endl;
    }
};

class AssemblerSystem {
public:
    void doAssembly()
    {
        cout << "--->Program in Assembling Stage" << endl;
    }
};

class LinkerSystem {
public:
    void doLinking()
    {
        cout << "--->Program In Linking Stage" << endl;
    }
};

class CompilerFacade {
private:
    PreprocessorSystem  preprocessor;
    CompilerSystem      compiler;
    AssemblerSystem     assembler;
    LinkerSystem        linker;

public:
    void Compile(string programName)
    {
        cout << programName << " Compliation Started" << endl;
        preprocessor.doPreprocess();
        compiler.doCompile();
        assembler.doAssembly();
        linker.doLinking();
        cout << programName << " Compilation Finished" << endl;
    }
};

int main()
{
    CompilerFacade clientCompiler;
    clientCompiler.Compile("MYPROGRAM.cpp");

    return 0;
}   


OUTPUT:

MYPROGRAM.cpp Compliation Started
--->Program In Preprocessing Stage
--->Program In Compile Stage
--->Program in Assembling Stage
--->Program In Linking Stage
MYPROGRAM.cpp Compilation Finished

                            INDEX - OTHER DESIGN PATTERNS

Abstract Factory Pattern

Abstract Factory Pattern is one of the creational design pattern.

According to Gang Of Four intent of Abstract Factory Pattern is to Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

SAMPLE CODE:

#include <iostream>

using namespace std;

enum DBType { MYSQL, ORACLE, REDIS, MANGODB };

class Database {
public:
    virtual void read() = 0;
    virtual void write() = 0;
};

class MysqlDB : public Database {
    void read() {
        cout << "Read data from MYSQL RDBMS Database" << endl;
    }
    void write() {
        cout << "Write data to MYSQL RDBMS Database" << endl;
    }
};

class OracleDB : public Database {
    void read() {
        cout << "Read data from ORACLE RDBMS Database" << endl;
    }
    void write() {
        cout << "Write data to ORACLE RDBMS Database" << endl;
    }
};

class RedisDB : public Database {
    void read() {
        cout << "Read data from REDIS NOSQL Database" << endl;
    }
    void write() {
        cout << "Write data to REDIS NOSQL Database" << endl;
    }
};

class MangoDB : public Database {
    void read() {
        cout << "Read data from MANGODB NOSQL Database" << endl;
    }
    void write() {
        cout << "Write data to MANGODB NOSQL Database" << endl;
    }
};

class DataBaseFactory {
public:
    virtual Database * getDatabase(DBType choice) = 0;
};

class RDBMSFactory : public DataBaseFactory {
    Database * getDatabase(DBType choice) {
        Database * DBObject;
        if (choice == MYSQL) {
            DBObject = new MysqlDB();
        }
        else if (choice == ORACLE) {
            DBObject = new OracleDB();
        }
        else {
            DBObject = NULL;
        }
        return DBObject;
    }
};

class NOSQLFactory : public DataBaseFactory {
    Database * getDatabase(DBType choice) {
        Database * DBObject;
        if (choice == REDIS) {
            DBObject = new RedisDB();
        }
        else if (choice == MANGODB) {
            DBObject = new MangoDB();
        }
        else {
            DBObject = NULL;
        }
        return DBObject;
    }
};

int main()
{
    DataBaseFactory * rdbmsObject, * nosqlObject;
    Database * databaseObject;

    rdbmsObject = new RDBMSFactory();
    databaseObject = rdbmsObject->getDatabase(ORACLE);
    databaseObject->read();
    databaseObject->write();
    cout << "-----------------------------------------" << endl;
    nosqlObject = new NOSQLFactory();
    databaseObject = nosqlObject->getDatabase(REDIS);
    databaseObject->read();
    databaseObject->write();

    return 0;
}


OUTPUT:

Read data from ORACLE RDBMS Database
Write data to ORACLE RDBMS Database
-----------------------------------------
Read data from REDIS NOSQL Database
Write data to REDIS NOSQL Database


Factory Method Pattern

Factory Method pattern comes under creational pattern.

According to Gang Of Four intent of Factory Method pattern is to Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

SAMPLE CODE:

#include <iostream>

using namespace std;

enum LaptopType { APPLE, DELL, HP };

class Laptop {
public:
    virtual void info() = 0;
};

class Apple : public Laptop {
    void info() {
        cout << "Apple Laptop Approved" << endl;
    }
};

class Dell : public Laptop {
    void info() {
        cout << "Dell Laptop Approved" << endl;
    }
};

class Hp : public Laptop {
    void info() {
        cout << "HP Laptop Approved" << endl;
    }
};

Laptop * getLaptopFactory(LaptopType choice)
{
    Laptop * laptopObj;
    if (choice == APPLE) {
        laptopObj = new Apple();
    }
    else if (choice == DELL) {
        laptopObj = new Dell();
    }
    else if (choice == HP) {
        laptopObj = new Hp();
    }
    else {
        laptopObj = NULL;
    }
    return laptopObj;
}

int main()
{
    Laptop * emp1Laptop;
    emp1Laptop = getLaptopFactory(DELL);
    emp1Laptop->info();

    Laptop * emp2Laptop;
    emp2Laptop =  getLaptopFactory(APPLE);
    emp2Laptop->info();
}

OUTPUT:

Dell Laptop Approved
Apple Laptop Approved

Singleton Design Pattern

Singleton pattern is one of the creational pattern.

According to GoF intent of Singleton pattern is to Ensure a class only has one instance, and provide a global point of access to it.


Code :

#include <iostream>

using namespace std;

class Logger {
public:
    static Logger* getInstance();

private:
    Logger(){}                   //Made private don't to create object via constructor
    Logger(Logger *);            //copy constructor is private so it can't be copied
    Logger* operator=(Logger *); //Assignment operator is private

    static Logger *instance;
};

Logger* Logger::instance = NULL;

Logger* Logger::getInstance() {
    if (instance == NULL) {
        instance = new Logger();
        cout << "Creating New Object "<< endl;
    } else {
        cout << "Utilizing Existing Object " << endl;
    }
    return instance;
}

int main()
{
    Logger *inst1 = Logger::getInstance();

    Logger *inst2 = Logger::getInstance();

    Logger *inst3 = Logger::getInstance();

    return 0;
}

Output:

Creating New Object
Utilizing Existing Object
Utilizing Existing Object