You might think, "Why another creational pattern if we already have the factory patterns?" Well, the answer is simple: different patterns have different use cases. While factory patterns are used to create products at runtime, the prototype pattern is mainly focused on creating objects specified in runtime by avoiding the creation of subclasses in the client program itself.
The Prototype Pattern becomes really useful if you want to exact the same clone of an object without knowing its real implemented class. If we create an object without this pattern using a new keyword, we won't be able to copy the private fields of that object.
Not using this pattern will also make your code messy because we will depend on the concrete implementation of the original class when we have to know what the current cloned object is.
The design diagram of the prototype pattern is as follows:
How to Implement a Prototype Design Pattern?
Let's go through implementing such a design pattern with an example.
First, create an interface that has methods for cloning objects.
In my example below I have made 2 methods; one that provides a shallow clone – for which the reference type properties inside the cloned object will point to the same memory address as the original object – and another that provides a deep clone – for which the cloned object and original object's properties will point to completely different memory addresses.
For easy prototype implementation, you may add a factory method that stores frequently used prototypes in a pool and provides various configured prototypes based on the client's request.
We can now create a class that implements a prototype interface. This concrete class will then implement the cloning function and return a copy of itself. In my example, I have created a class Player that implements IPlayer. Playerthenreturns a cloned version of itself when using the GetShallowClone() and GetDeepClone() methods. I have created p1 as an original object and cloned it and assigned it to p2 and p3 in my example below.
Code and Execution
The prototype pattern is really helpful when we want to create a cloned object of an already present object. It helps in reducing repeated initialization of complex objects using a centralized clone system that clones all required properties.
That's all for today , I will be coming with more design patterns soon.