Prototype Pattern — Core Concepts

What the Prototype Pattern does

The Prototype Pattern creates new objects by cloning an existing instance rather than calling a constructor. The original object serves as a template — a prototype — that you duplicate and then customize.

This is a creational pattern, meaning it’s about how objects come into existence. While Factory picks which class to instantiate and Builder controls multi-step construction, Prototype skips construction entirely by copying something that already exists.

Why cloning beats constructing

Object creation isn’t always cheap. Consider these scenarios:

  • Database-backed objects that load configuration from a remote source during __init__
  • Machine learning models with expensive initialization (loading weights, compiling graphs)
  • Game entities that share 90% of their attributes with only minor variations
  • Test fixtures where you need many similar objects with small differences

In each case, building from scratch is wasteful. Cloning a prototype and modifying a few fields is faster and less error-prone.

Python’s built-in cloning

Python provides the copy module with two functions:

  • copy.copy(obj) — shallow copy. The new object is independent, but its contents (lists, dicts, nested objects) are shared references.
  • copy.deepcopy(obj) — deep copy. Everything is recursively duplicated. The clone is fully independent.

Classes can customize this behavior by implementing __copy__() and __deepcopy__() methods.

Shallow vs deep — when it matters

ScenarioUse
Object contains only immutable fields (strings, numbers, tuples)Shallow copy is safe
Object has mutable containers (lists, dicts) that clones should shareShallow copy
Each clone must be fully independentDeep copy
Object has circular referencesDeep copy handles this automatically

The most common bug: shallow-copying an object with a list attribute, modifying the list in the clone, and discovering the original changed too.

Prototype registry

A useful extension is a prototype registry — a dictionary of named prototypes that serves as a catalogue:

  1. Register pre-configured prototypes under descriptive names
  2. When you need a new object, look up the closest prototype
  3. Clone it, customize it, use it

This avoids scattering construction logic across the codebase. Configuration lives in one place (the registry), and consumers just pick and tweak.

Common misconception

“Prototype is just assignment.” No — b = a in Python doesn’t create a copy. Both variables point to the same object. Changes through b affect a. Prototype requires actual duplication of the object’s state, which is what copy and deepcopy provide.

The one thing to remember: Use the Prototype Pattern when creating an object from scratch is expensive or complex — clone a ready-made template and adjust what’s different.

pythondesign-patternsoop

See Also

  • Python Adapter Pattern How Python's Adapter Pattern works like a travel power plug — making incompatible things work together.
  • Python Bridge Pattern Why separating what something does from how it does it keeps your Python code from becoming a tangled mess.
  • Python Builder Pattern Why building complex Python objects step by step beats cramming everything into one giant constructor.
  • Python Composite Pattern How the Composite Pattern lets you treat a group of things the same way you'd treat a single thing in Python.
  • Python Facade Pattern How the Facade Pattern gives you one simple button instead of a confusing control panel in Python.