22

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?

Sisir
  • 4,584
  • 4
  • 26
  • 37
Vladimir Tsyshnatiy
  • 989
  • 1
  • 10
  • 20

2 Answers2

28

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();.

Mateusz Kubuszok
  • 24,995
  • 4
  • 42
  • 64
  • Yeah, this is really great explanation. Thanks! – Vladimir Tsyshnatiy Mar 11 '16 at 12:06
  • This is very helpful while working with immutable types. Every time, you want to change a field you will have to create a new type cloning from the first type and then apply the change. – Sisir Oct 15 '18 at 06:07
9

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.

Example of Prototype design pattern

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.

Sisir
  • 4,584
  • 4
  • 26
  • 37
vcp
  • 962
  • 7
  • 15