Prototype Pattern

The Prototype is a creational design pattern that allows creating new objects by cloning existing ones, avoiding explicit constructors for complex initialization. It is ideal when object creation is expensive or when you want to copy pre-configured instances.

Key Principles

Structure

Python Example: Shape Prototypes

import copy
from typing import List

class Shape:
    def __init__(self, color: str, thickness: int):
        self.color = color
        self.thickness = thickness
        self.position = (0, 0)

    def clone(self):
        return copy.deepcopy(self)  # Deep copy

    def move(self, x: int, y: int):
        self.position = (x, y)

    def __str__(self):
        return f"Shape(color={self.color}, thickness={self.thickness}, pos={self.position})"

# Concrete Prototypes
class Circle(Shape):
    def __init__(self, radius: float, color: str = "black", thickness: int = 1):
        super().__init__(color, thickness)
        self.radius = radius

    def clone(self):
        return copy.deepcopy(self)

class Rectangle(Shape):
    def __init__(self, width: float, height: float, color: str = "black", thickness: int = 1):
        super().__init__(color, thickness)
        self.width = width
        self.height = height

    def clone(self):
        return copy.deepcopy(self)

# Prototype Registry
class ShapeRegistry:
    def __init__(self):
        self.prototypes = {}

    def register(self, name: str, prototype: Shape):
        self.prototypes[name] = prototype

    def create(self, name: str) -> Shape:
        if name in self.prototypes:
            return self.prototypes[name].clone()
        raise ValueError(f"No prototype registered for {name}")

# Usage (Client Code)
if __name__ == "__main__":
    registry = ShapeRegistry()

    # Register prototypes
    registry.register("circle", Circle(radius=5, color="red"))
    registry.register("rectangle", Rectangle(width=10, height=5, color="blue"))

    # Create clones
    cloned_circle = registry.create("circle")
    cloned_circle.move(10, 20)
    print(cloned_circle)  # Shape(color=red, thickness=1, pos=(10, 20))

    cloned_rect = registry.create("rectangle")
    cloned_rect.move(5, 15)
    print(cloned_rect)  # Shape(color=blue, thickness=1, pos=(5, 15))

    print(f"Original vs Clone: {registry.create('circle') is cloned_circle}")  # False (new instance)

Output:

Shape(color=red, thickness=1, pos=(10, 20))
Shape(color=blue, thickness=1, pos=(5, 15))
Original vs Clone: False

When to Use Prototype

Summary: Prototype enables efficient object duplication by cloning pre-made instances, reducing creation overhead while maintaining flexibility.