Explanation of Prototype Design Pattern in C++

Explanation of Prototype Design Pattern in C++

Hello everyone, in this article we are going to talk about Prototype Design Pattern within Creational Design Patterns. We are going to make an example with C++ and Qt.

Let's get started.

Firstly What is Prototype Design Pattern

Sometimes we may need different components which based on same things. For example: All of us are using button in our projects. But we also see ImageButtons that just have a few changings from standart button.
Prototype Design pattern helps us to copy or clone a prototype class and produce new classes on this cloned class.

In our projects using the prototypes to produce somethings are making tasks flexible and easier. Because We have a component and just clone it and add the behaviours you want. So system is getting simplified and we write less code. Also we can build more dynamic systems with less complexilibity. Prototype Design Pattern is very helpful in all Object Oriented Programming Languages.

Below image you can see the schematic of our example: Prototype Design Pattern Example Schematic

Now lets write some code :)

ALL CODES WILL BE IN MAIN.C FILE. SO DO NOT NEED TO CREATE ANY HEADER FILES FOR THIS EXAMPLE.

First include some required libraries:

#include <iostream>

using namespace std;

//Some QT Libraries
#include <QString>
#include <QStringList>
  • First We have to create a Prototype class to build other classes. This class have all common specifications Other classes will clone this class and make some addings
  • In constructor og the base class, I have added some specifications which essential for this type of component
  • Then I have created required other properties and some important methods. Also I have declared some override method which must call in the derived classes.

class Vehicle
{
public:
    Vehicle(){
        parts.append("Engine");
        parts.append("FuelTanks");
    }
    QString name = "Default" ;
    QStringList parts;
    virtual Vehicle* clone() const = 0;
    virtual void listAllParts() const = 0;
    virtual void setVehicleName(QString name){ this->name = name; }
    virtual void addParts(QString part) { parts.append(part); }

    virtual ~Vehicle() { cout << "Vehicle Class has been destroyed and memory released...\n\n";  }
};

Here we create our concrete prototype classes which derived from above base class. This classes are going to be cloned according to user requirements via Prototype Factory Class.


class Aircraft : public Vehicle
{
public:
    Aircraft(){
        addParts("IFE");
        addParts("Passenger Seats");
    }
    Aircraft*   clone() const { return new Aircraft; }
    void listAllParts() const {
        cout << "Vehicle Type : Aircraft\n";
        cout << "Vehicle Name : " << name.toLocal8Bit().constData() << endl;
        for(int i =0; i< parts.length(); i++){
            cout << "Part: " << parts.at(i).toLocal8Bit().constData() << endl;
        }
        cout << "------------------------------\n";
    }
};

class Car : public Vehicle
{
public:
    Car(){
        addParts("Mirrors");
        addParts("Shift Gear");
    }
    Vehicle* clone() const { return new Car; }
    void listAllParts() const {
        cout << "Vehicle Type : Car\n";
        cout << "Vehicle Name : " << name.toLocal8Bit().constData() << endl;
        for(int i =0; i< parts.length(); i++){
            cout << "Part:" << parts.at(i).toLocal8Bit().constData() << endl;
        }
        cout << "------------------------------\n";
    }
};
  • With clone method we are not creating a new structure,// we are returning the prepared class with a pointer. So we are avoiding to use extra memory and preventing memory leaks.
  • Below factory class will produce the prototypes from above declared classes with specified indexes

class PrototypeFactory {
public:
    ~PrototypeFactory(){ cout << "Prototype Factory Has been destroyed and memory released\n\n"; }

    Vehicle* vehicle_prototypes[2]{
        new Aircraft, new Car
    };

    Vehicle* preparePrototype( int prototypeIndex ){
        return vehicle_prototypes[prototypeIndex]->clone();
    }

};

static int INDEX_AIRCRAFT = 0;
static int INDEX_CAR = 1;
  • In main function we are going to create prototypes and use them. In here we are going to create prototypes from both different classes then call some functions in them and show what do they have inside arrays of them
  • At the end of process do not forget the delete variables which are not need to prevent the memory leaks.

int main() {
    Vehicle *vec;
    PrototypeFactory *pFactory = new PrototypeFactory();
    vec = pFactory->preparePrototype(INDEX_AIRCRAFT);

    vec->setVehicleName("Boeing... ");
    vec->addParts("MCAS");
    vec->addParts("EICAS");
    vec->listAllParts();

    //Created another type of same component
    vec = pFactory->preparePrototype(INDEX_AIRCRAFT);
    vec->setVehicleName("Airbus... ");
    vec->addParts("ECAM");
    vec->listAllParts();

    //Created another type of same component
    vec = pFactory->preparePrototype(INDEX_CAR);
    vec->setVehicleName("MURAT124... ");
    vec->addParts("SALLOW DOG");
    vec->addParts("DISCO BALL");
    vec->addParts("SUBWOOFERS");
    vec->listAllParts();

    delete pFactory;
    delete vec;

    return 0;
}
Below image you can see the output of the example: Prototype Design Pattern Example Output

That is all in this article.

Burak Hamdi TUFAN


Tags


Share this Post

Send with Whatsapp

Post a Comment

Success! Your comment sent to post. It will be showed after confirmation.
Error! There was an error sending your comment.

Comments

  • There is no comment. Be the owner of first comment...