Prototype
Prototype creates objects by cloning existing instances instead of instantiating classes, helping when construction is expensive or types vary at runtime. Deep-copy correctness is its main challenge.
The Prototype pattern creates new objects by copying an existing instance — the prototype — instead of constructing them from scratch. It addresses cases where instantiating a class directly is expensive, where the concrete type is not known until runtime, or where many pre-configured variants are easier to clone than to rebuild.
How It Works
A Prototype declares a clone() operation. Concrete Prototypes implement it to return a copy of themselves. Client code holds a prototype and calls clone() to get a fresh, independent object with the same initial state, then customizes it as needed. A prototype registry often accompanies the pattern: a map of named, ready-made prototypes that clients look up and copy, turning object creation into a lookup-and-clone.
The critical implementation choice is shallow versus deep copy. A shallow clone duplicates the top-level object but shares referenced sub-objects; a deep clone recursively copies them. Mutable shared references after a shallow clone are a frequent source of bugs.
When to Use It
Use Prototype when object creation is costly — heavy initialization, database or network round-trips, expensive computation — and a similar object already exists to copy. It is also valuable when a system must be independent of how its products are created and you want to add and remove products at runtime by registering prototypes. It can replace a tall hierarchy of factory subclasses with a registry of configured instances.
Avoid it when objects are cheap to construct or when deep, cyclic object graphs make cloning fragile and hard to reason about.
Trade-offs
Cloning can be faster than constructing and hides concrete classes from the client, like other creational patterns. It lets you add or swap product variants at runtime and reduces subclassing. Preconfigured prototypes capture complex setup once.
The deep-copy problem is the main hazard: implementing correct cloning for objects with circular references, transient state, or external resources (open files, sockets) is subtle and language-specific. Some platforms supply built-in cloning (for example, JavaScript's structuredClone or prototypal inheritance, .NET's ICloneable) but the semantics vary and must be understood.
Related Patterns
Prototype is an alternative to Abstract Factory and Factory Method that uses copying rather than subclassing. A registry of prototypes acts much like a factory. Composite and Decorator structures are good prototype candidates because rebuilding their trees by hand is tedious. JavaScript's object model is itself prototype-based.
Example
A graphics editor lets users duplicate shapes. Each shape implements clone(). Copying a complex grouped shape with styling, transforms, and child elements is a single clone() call that deep-copies the subtree, rather than reconstructing every element. A shape registry holds default templates — "red rounded rectangle" — that the toolbar clones when the user drags a new shape onto the canvas.