Chaturmind
LearnDSASystem DesignBlogPremium
Sign inGet started
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML

Company

  • Blog
  • Premium
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight
Chaturmind
← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight
HomeLearnSystem DesignLow-Level Design & Design PatternsCreational Design Patterns
✓ FreeBeginner· 6 min read

Prototype Pattern

Cloning existing objects instead of building from scratch — and the shallow-vs-deep-copy bug that catches almost everyone the first time.

Published September 22, 2026


Prototype Pattern

The idea: clone instead of construct

Some objects are expensive to build from scratch — heavy initialization, an expensive DB lookup to populate default state, or a complex object graph assembled step by step. Prototype sidesteps rebuilding all of that by cloning an existing, already-configured instance.

interface Shape extends Cloneable {
    Shape clone();
}

class Circle implements Shape {
    private int radius;
    private String color;

    Circle(int radius, String color) {
        this.radius = radius;
        this.color = color;
    }

    public Circle clone() {
        return new Circle(this.radius, this.color); // manual copy, not Object.clone()
    }
}

Circle template = new Circle(10, "red");
Circle copy1 = template.clone();
copy1.setColor("blue"); // independent — doesn't affect template

Shallow copy vs deep copy — where the bug hides

A naive clone only copies the object's own fields, including references — it does not clone the objects those references point to. This is fine for primitive/immutable fields, but dangerous for mutable, nested ones.

class Order implements Cloneable {
    private List<String> items;

    // SHALLOW clone — the bug
    public Order clone() {
        Order copy = new Order();
        copy.items = this.items; // same list reference!
        return copy;
    }
}

Order original = new Order();
original.items = new ArrayList<>(List.of("book"));
Order copy = original.clone();
copy.items.add("pen"); // mutates the SAME list original.items points to
// original.items now also contains "pen" — not what "clone" implies

The fix is a deep copy — recursively cloning mutable nested objects, not just copying the outer object's references:

public Order clone() {
    Order copy = new Order();
    copy.items = new ArrayList<>(this.items); // new list, same elements — safe if elements are immutable
    return copy;
}

If items held mutable objects themselves (not Strings), each element would need its own .clone() too — deep copying is recursive by nature, and how deep it needs to go depends entirely on which fields are actually mutable.

When Prototype earns its complexity

Prototype is worth it when object creation is genuinely expensive (a costly initialization step, or an object with dozens of pre-configured fields you'd otherwise have to re-specify every time) and you have a small number of "template" configurations that get cloned and lightly customized repeatedly — a common example is a graphics/game engine cloning pre-configured entity templates rather than re-running full initialization for every spawned instance.

When a plain copy constructor suffices — most everyday cases — prefer it; it's simpler, doesn't require implementing Cloneable (whose contract is famously awkward — Object.clone() is protected, doesn't call constructors, and its shallow-by-default behavior is exactly the bug shown above), and makes the deep-vs-shallow decision explicit and visible at the call site rather than hidden inside an overridden clone().

// Copy constructor — the more idiomatic modern alternative
class Order {
    private List<String> items;

    Order(Order source) { // explicit, visible copying — no Cloneable pitfalls
        this.items = new ArrayList<>(source.items);
    }
}

Follow-up questions this topic invites — and their answers

Q: Why is Object.clone() considered a design mistake by many, including its own creators? A: It's shallow by default (silently sharing mutable state unless every subclass remembers to override correctly), it bypasses constructors entirely (so invariants enforced in a constructor aren't re-checked), and Cloneable is a marker interface with no actual clone method on it — calling clone() on a non-Cloneable object throws CloneNotSupportedException at runtime, not compile time.

Q: Is Prototype the same as the Builder pattern? A: No — Builder constructs a new object step by step from scratch (see Builder Pattern); Prototype starts from an existing fully-formed object and copies it. They can combine (clone a prototype, then use builder-style setters to adjust the copy) but solve different problems.

Q: How would you implement Prototype using serialization instead of clone()? A: Serialize the object to bytes, then deserialize into a new instance — this produces a guaranteed deep copy automatically (every reachable object in the graph gets recreated), at the cost of serialization overhead and requiring every field's type to be serializable. A reasonable fallback when the object graph is deep and hand-writing recursive clones would be error-prone.

Previous

Builder Pattern

Next

Adapter & Facade

AI Tutor

Lesson: Prototype Pattern

Quick actions

AI responses can be inaccurate. Verify critical information.