I am trying to understand when I should use Prototype design pattern. Here is example of Prototype as I understand it:
class Prototype
{
public:
virtual Prototype* clone() = 0;
...
};
class ConcretePrototype : public Prototype
{
public:
Prototype* clone() override { ... }
};
// Usage:
ConcretePrototype proto;
auto protPtr = proto.clone();
Where is a question: Why this better than:
class Obj
{
public:
Obj();
Obj(const Obj&);
Obj& operator = (const Obj& other);
};
Obj o;
Obj o2 = o;
So when should I actually use Prototype?
Constructor: It is a method which has the same name as the class which is used to create an instance of the class. Copy Constructor: Used to create an object by copying variables from another object of the same class. The main purpose is to create a new object from an existing one by copying variables.
Prototype pattern refers to creating duplicate object while keeping performance in mind. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.
Factory pattern is used to introduce loose coupling between objects as the factory will take care of all the instantiation logic hiding it from the clients. Prototype pattern on the other hand is used when the cost of creating an object is large and it is ok to copy an existing instance than creating a new instance.
Applying the pattern lets you clone complex structures instead of re-constructing them from scratch. Prototype isn't based on inheritance, so it doesn't have its drawbacks. On the other hand, Prototype requires a complicated initialization of the cloned object.
Copy constructor is an element of the language.
Prototype is a design pattern used to spawn (polymorphic) objects basing on some existing instance.
It would be difficult to use the former to implement the latter as copy constructor is intended to be used when knowing exact instance of the object, while prototype is used when there could be any possible implementation of some interface and you just want to obtain new object of exactly the same implementation, without resorting to some weird casting and checking methods.
Lets assume that you have Interface I
and implementations A
and B
. At some point you are given object i
implementing I
. Perhaps you would not want to modify it, instead you would prefer to obtain new instance and then introduce some modification to it. How could that be achieved, when you don't know exact class of i
? Prototype pattern is one solution to that problem: I* i2 = i.clone();
.
Here is a reference from GoF book:
clients that clone the prototype don't have to know about their concrete subclasses. Clients should never need to downcast the return value of Clone to the desired type.
From your example, the client is NOT aware of (or cannot access) ConcretePrototype
.
// Usage:
SomeMethod(PrototypeInterface iproto) // Thanks Prototype pattern
{
// ConcretePrototype proto;
auto protPtr = iproto.clone(); // Gets correct object without calling concrete object's constructor explicitly.
}
Hope you understood the situation when this pattern is useful. Also Remember, there is no virtual constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With