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


LD_PRELOAD Tutorial

Dynamic linker will load the all the shared library one bye one in any order. LD_PRELOAD  is a environment variable containing libraries that the dynamic linker will load before loading any other libraries.

By using this we can override the function available in the later libraries. Even we can over ride the functions available in C programs libc libraries. Here i demonstrate the usage of LD_PRELOAD with simple example.

Simple C program named as ldmain.c 
#include <stdio.h>
int main()
{
        printf("PID = %d\n", getpid());
        return 0;
}

Above program will print the process id of the current process using libc function getpid.

Compile the above program using gcc compiler and run the program, it will print the process id.
sujinsr@fedo:~/workspace/c $ gcc -o main ldmain.c 

sujinsr@fedo:~/workspace/c $ ./main 
PID = 1082

Now you see how we can override the libc's getpid with our own. Write our own version of the getpid function. Here i named the file as ldpid.c
#include <stdio.h>
int getpid()
{
        printf("My own version of getpid() for testing it will return always 99999\n");
        return 99999;
}

Create the shared object of that function using gcc
sujinsr@fedo:~/workspace/c $ gcc -o ldpid.so ldpid.c -fPIC -shared 

Set the LD_PRELOAD envirnonment as new shared library we created before.
sujinsr@fedo:~/workspace/c $ export LD_PRELOAD=./ldpid.so

Run the program and see our own version of getpid called instead of libc's function.
sujinsr@fedo:~/workspace/c $ ./main 
My own version of getpid() for testing it will return always 99999
PID = 99999

If you want to remove shared library configured to LD_PRELOAD just unset the environment variable like below.
sujinsr@fedo:~/workspace/c $ unset LD_PRELOAD

sujinsr@fedo:~/workspace/c $ ./main
PID = 1638

Cheers !!!!!