Prototype pattern
The prototype pattern creates new objects by cloning existing ones, avoiding expensive construction when you need many similar instances with minor variations.
Introduction
The Prototype pattern creates new objects by copying a configured object, then lets the caller customize the copy. It is useful when many instances share an expensive-to-build baseline or a complex object graph.
TL;DR / mental model: Pay the setup cost once for each baseline, clone that baseline for each new instance, deep-copy mutable state, share truly immutable state, and do not copy live resources blindly.
Problem and Context
You're building a game where enemies spawn from base configurations. Each enemy type (zombie, dragon, skeleton) requires loading stats from a database, parsing AI behavior trees from XML, and initializing a complex inventory. Creating one enemy takes 500ms of I/O.
Every enemy of the same type has the same base stats, AI, and starting inventory. You're paying the full construction cost 170 times for data you only need to load 3 times. The problem is not the complexity of construction; it is repeating that construction unnecessarily.
Here is what changes when you apply the Prototype pattern.
When It Helps
Use Prototype when construction is expensive or configuration is complex, many instances start from a small set of known baselines, and the object graph has an explicit copy policy. If each instance is unique or construction is cheap, a constructor or factory is usually easier to understand.
Participants and Structure
Prototype defines the clone() contract. EnemyConfig is the concrete prototype holding game stats, AI, and inventory. Item is a nested object that also implements clone() for deep copying. EnemyRegistry is the prototype factory: it stores pre-built prototypes and spawns new instances by cloning. The caller asks for a "zombie" and gets a fresh copy without any I/O.
Idiomatic Example and Implementation Notes
The critical decision in Prototype is the clone depth. Shallow copies share mutable references, which means modifying one clone's inventory affects every other clone. Prototype is a good fit when construction involves I/O and the resulting objects are used as starting points for variations.
Shallow vs deep: the clone trap
If you shallow-copy an object with mutable fields (lists, maps, nested objects), clones share those references. One clone adding a sword to its inventory gives every clone a sword. Deep copy mutable fields, share immutable ones.
Continue Reading with Premium
Unlock this article and every other in-depth system design guide on the platform with SDEpedia Premium.
Related Articles
The builder separates complex object construction from representation, replacing telescoping constructors with a readable, fluent API that validates before building.
The factory method replaces direct constructor calls with a method that subclasses can override to return different types. Callers depend on an abstraction, not a concrete class.
The flyweight pattern minimizes memory by sharing common state across thousands of objects, splitting data into intrinsic (shared) and extrinsic (unique) parts.