Prototype Design Pattern allows us to copy or clone the existing objects of an interface to fully initialize a new object.
Prototype Pattern suggests creating an interface that creates a clone of the existing object. An object that any client can feed upon.
The Prototype Pattern is used when the object creation is costly and requires a lot of time and resources. So Prototype Pattern provides a mechanism to copy the original object to a new object and then modifies it according to our needs.
Components of Prototype Pattern
Prototype Class: A Superclass that will contain all the necessary attributes and methods that the clones of objects will have. Also, the Prototype has an abstract clone() method, which has to be implemented by all subclasses.
Concrete Class(es): Once we have created the Prototype-Superclass, we can start defining the concrete classes based on the superclass. Concrete Classes are optional to defined in an application.
The concrete classes can have their own attributes and methods but they’ll always have the original prototype attributes and an overwritten version of the clone()
.
Example
Consider creating a Prototype for Car object. Let us create an interface for the car.
class Car:
def __init__(self, engine="1500cc", color="D-white", seats=7):
self.engine = engine
self.color = color
self.seats = seats
def __str__(self):
return f'{self.engine} | {self.color} | {self.seats}'
The Prototype Class:
Walkthrough Prototype interface(i.e. class).
- Prototype interface has a dictionary data structure to store all the cloned objects.
- RegisterObject method to add element in dictionary, taking name of new object as key and extising object as value.
- DeregisterObject method to delete an entry from the dictionary.
- And, finally Clone method to copy the existing object. Clone method uses deepcopy() method from Copy module inorder to clone the object.
import copy
class Prototype:
def __init__(self):
'''Dictionary that will stores cloned objects.'''
self._ClonedObjects = {}
def RegisterObject(self, name, obj):
'''Method to store all clones of the existion objects.'''
self._ClonedObjects[name] = obj
def DeregisterObject(self, name):
'''Method to delete the cloned object from the dictionary.'''
del self._ClonedObjects[name]
def Clone(self, name, **kwargs):
"""Method to clone the object."""
clonedObject = copy.deepcopy(self._ClonedObjects.get(name))
clonedObject.__dict__.update(kwargs)
return clonedObject
- Finally the driver code
if __name__ == "__main__":
"""The object that will be cloned."""
defaultCar = Car()
prototype = Prototype()
"""The object that will be cloned."""
CarType1 = Car("1000cc", "Red", 4)
"""Registering the defaultCar in dictionary with its key as 'basicCar'"""
prototype.RegisterObject('BasicCar', defaultCar)
prototype.RegisterObject('Type-1', CarType1)
carOne = prototype.Clone('BasicCar', color = "Lake side brown")
carTwo = prototype.Clone('Type-1',color = "Red")
carThree = prototype.Clone('Type-1', color = "Moon Dust Silver")
print("Details of the default-car:", defaultCar)
print("Details of car-One:", carOne)
print("Details of car-Two:", carTwo)
print("Details of car-Three:", carThree)
Output
Details of the default-car: 1500cc | D-white | 7
Details of car-One: 1500cc | Lake side brown | 7
Details of car-Two: 1000cc | Red | 4
Details of car-Three: 1000cc | Moon Dust Silver | 4
The Prototype Pattern is a Creational Design Pattern used to clone an Object.
Prototype Pattern reduces the number of Sub-classes, hides the complexities in creating the objects, and facilitates adding or remove objects at runtime.