CODESAMPLE
Prototype - Python
The Prototype pattern is a creational design pattern that specifies the kinds of objects to create using an instance of a prototype and creates new objects by cloning this prototype. It’s useful when creating objects is complex or costly, and you want to avoid repetitive creation of similar objects.
The Python implementation uses the copy module’s deepcopy() function to create independent copies of prototype objects. An abstract base class Shape defines a clone method, implemented in concrete classes like Rectangle and Circle. A ShapeStore acts as a registry holding prototypes for different shapes. Clients request new shapes by cloning existing prototypes from the store, rather than instantiating concrete classes directly. This fits Python’s dynamic nature and reliance on duck typing, demonstrating flexibility and avoiding tight coupling to specific classes. Using deepcopy ensures that changes to the cloned object don’t affect the original prototype.
import copy
class Shape:
def clone(self):
raise NotImplementedError
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def __str__(self):
return f"Rectangle(width={self.width}, height={self.height})"
def clone(self):
return copy.deepcopy(self)
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def __str__(self):
return f"Circle(radius={self.radius})"
def clone(self):
return copy.deepcopy(self)
class ShapeStore:
def __init__(self):
self.shapes = {}
def add_shape(self, key, shape):
self.shapes[key] = shape
def get_shape(self, key):
return self.shapes[key].clone()
if __name__ == "__main__":
shape_store = ShapeStore()
rectangle = Rectangle(10, 20)
shape_store.add_shape("rectangle", rectangle)
circle = Circle(5)
shape_store.add_shape("circle", circle)
clone_rectangle = shape_store.get_shape("rectangle")
clone_circle = shape_store.get_shape("circle")
print(f"Original Rectangle: {rectangle}")
print(f"Cloned Rectangle: {clone_rectangle}")
clone_rectangle.width = 15
print(f"Changed Cloned Rectangle width: {clone_rectangle}")
print(f"Original Rectangle after clone change: {rectangle}") # unaffected
print(f"Original Circle: {circle}")
print(f"Cloned Circle: {clone_circle}")