Think of an Interior decorator. He will be performing the below two steps to suggest the decoration of interior to any client:
For each client that comes to the designer, he will do the above two steps.
The second step (designing the hall) is customized according to requirements of the client, but first step (creating raw hall) is same for everyone. Hence it makes a perfect sense to have it ready as a prototype (i.e clone the same object of the class).
In the above example we will have a class for room which will have a clone function.
The designer will call this function to create the clone of a room and then will use that room to ocreate customized design.
This is nothing but the Prototype design pattern.
The prototype pattern is a Creational design pattern used when the type of objects to create is determined by a prototypical instance, that is cloned to produce new objects.
Class diagram:
Main classes:
Example:
The ImageHandler class manages the images and copy of Images. User can either create a clone of HomeImage or OfficeImage. It keeps a registry of already created objects of which clone function will be called to create a copy.
Code:
// Prototype Class class Prototype { public: // Virtual destructor should always be defined in a base class virtual ~Prototype() { } virtual Prototype* clone() const = 0; }; // Concrete prototype class class ConcretePrototype : public Prototype { private: int data; public: // Default Constructor ConcretePrototype(int x) : data(x) { } // Copy constructor ConcretePrototype(const ConcretePrototype& p) : data(p.data) { } // Implementing the clone function of Base class. virtual Prototype* clone() const { // since we are copying we need to define Copy Constructor. return new ConcretePrototype(*this); } void setData(int x) { data = x; } int getData() const { return data; } void printData() const { std::cout << "Value :" << data << std::endl; } }; // Client code int main() { // Creating the main Product (which will be cloned) Prototype* prototype = new ConcretePrototype(1000); for (int i = 1; i < 10; i++) { ConcretePrototype* obj = dynamic_cast<ConcretePrototype*>(prototype->clone()); obj->setData( obj->getData() * i); obj->printData(); delete obj; } delete prototype; }
When to use Prototype pattern:
Whenever you see yourself creating object and then initializing it in similar way think of using the same configuration as Base configuration and use Prototype Pattern.