Skip to content

Prototype Pattern — Clone Existing Objects

DodaTech Updated 2026-06-24 4 min read

What You'll Learn

You will learn how the Prototype pattern uses cloning to create new objects without coupling to their concrete classes, and how shallow versus deep copying affects your design. You will also see how a Prototype registry can replace Factory hierarchies.

Why It Matters

Creating objects from scratch can be expensive — think database queries, network calls, or complex initialisation. Prototype lets you clone a pre-configured instance, paying the setup cost once and reusing it many times. It also sidesteps constructor constraints when object configuration is complex. Consider a report template with dozens of configuration options: building each instance from a constructor would require passing all those options every time. With Prototype, you create one fully-configured template and clone it, customising only the fields that differ.

Real-World Use

Game engines clone enemy sprites and weapon objects from a few archetypes rather than constructing each from a Factory — this is why loading a level spawns hundreds of enemies from a handful of Prototype definitions. DodaTech's template engine uses Prototype-based instantiation to stamp out report configurations from a master template, allowing users to define a base report layout once and clone it for different departments with minor tweaks.

The Pattern

A Prototype interface declares a clone method. Concrete prototypes implement cloning to return a copy of themselves. The client clones a Prototype instead of calling a constructor.

import copy
from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def clone(self) -> "Shape":
        pass

    @abstractmethod
    def area(self) -> float:
        pass

class Rectangle(Shape):
    def __init__(self, width: float, height: float, color: str = "red"):
        self.width = width
        self.height = height
        self.color = color

    def clone(self) -> "Rectangle":
        return copy.deepcopy(self)

    def area(self) -> float:
        return self.width * self.height

class Circle(Shape):
    def __init__(self, radius: float, color: str = "blue"):
        self.radius = radius
        self.color = color

    def clone(self) -> "Circle":
        return copy.deepcopy(self)

    def area(self) -> float:
        return 3.14159 * self.radius ** 2
prototypes = {
    "big_rect": Rectangle(100, 50, "green"),
    "small_circle": Circle(10, "yellow"),
}
r = prototypes["big_rect"].clone()
r.color = "purple"
c = prototypes["small_circle"].clone()
print(r.area(), r.color)
print(c.area(), c.color)
5000 purple
314.159 yellow

Structure

classDiagram
    class Prototype {
        <>
        +clone(): Prototype
    }
    class ConcretePrototype1 {
        +clone(): Prototype
    }
    class ConcretePrototype2 {
        +clone(): Prototype
    }
    class Client {
        +operation(prototype: Prototype)
    }
    ConcretePrototype1 ..|> Prototype
    ConcretePrototype2 ..|> Prototype
    Client --> Prototype : clones

Real-World Usage

  • Java Object.clone() — all Java objects inherit a clone() method for field-by-field copying.
  • JavaScript Object.create(proto) — prototypal inheritance is a language-native implementation of this pattern.
  • Python copy.copy() and copy.deepcopy() — the language's standard library implements the Prototype pattern generically.
  • Godot Engine scenes — scenes are prototypes instantiated throughout a game world.
  • Factory Method is an alternative to Prototype for object creation.
  • Abstract Factory can store a registry of prototypes to clone.
  • Composite objects often implement cloning to duplicate entire tree structures.
  • Memento uses a similar mechanism to capture and restore object state.

Pros and Cons

Pros Cons
Reduces subclassing for creation Deep cloning can be complex with circular references
Hides concrete product classes Cloning methods may need special handling for singletons or file handles
Performance gain for expensive construction Not all objects are trivially cloneable
Lets you add/remove prototypes at runtime Shallow copy bugs are subtle and hard to debug

The code demonstrates deepcopy — essential here because Rectangle and Circle are simple data objects without external resources. The Prototype registry (prototypes dictionary) stores pre-configured instances and clients clone from it rather than calling constructors directly. Notice that modifying the cloned instance's color does not affect the original Prototype.

Practice Questions

  1. What is the difference between shallow copy and deep copy, and when would each be appropriate?
  2. Implement a Prototype registry that returns the correct clone based on a string key, registering new prototypes dynamically.
  3. How would you handle cloning an object that holds a network connection or file handle?
  4. Compare Prototype with Builder — in what scenarios is each superior?

Challenge

Implement a Prototype registry that supports both cloning and Prototype initialisation callbacks. When a Prototype is cloned, the callback should allow the cloned instance to establish new connections or allocate fresh resources that should not be shared.

Real-World Task

Profile your application with DodaTech's memory profiler to identify objects that are re-created frequently with identical initialisation. Refactor those creation sites to use the Prototype pattern and measure the performance improvement.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro