Creational · 4 of 5
Prototype
is a creational pattern: copy a ready object instead of reconstructing it from scratch. You clone the configured example, then change only what must differ.
Example: a weekly lab report already has twelve columns, three filters, a header, and a chart style. Monday’s report is that object with a new date. Tuesday’s is the same with one extra filter. Rebuilding from setters each morning duplicates work and often misses the header.
Do I already have a good example sitting in memory?
Read the diagram definition
flowchart TB
P[ReportTemplate prototype]
P -->|copy| Mon[Monday report]
P -->|copy| Tue[Tuesday report]
Mon --> D1[date = 13 Aug]
Tue --> D2[date = 14 Aug + one filter]Copy a ready object — do not call Object.clone()
Java’s is a famous trap. Prefer an explicit copy() (or a copy constructor) with a clear deep/shallow story.
final class ReportTemplate {
private final String header;
private final List<String> columns;
private final List<Filter> filters;
private Instant asOf;
ReportTemplate copy() {
return new ReportTemplate(
header,
new ArrayList<>(columns),
filters.stream().map(Filter::copy).toList(), // deep where mutable
asOf
);
}
ReportTemplate withAsOf(Instant t) {
ReportTemplate next = copy();
next.asOf = t;
return next;
}
}
class WeeklyReports {
private final ReportTemplate prototype;
ReportTemplate issue(Instant monday) {
return prototype.withAsOf(monday);
}
}Shallow vs deep copy
Shallow copy of mutable insides
A that reuses the same List<Filter> means Monday’s extra filter appears on Tuesday. That is the classic prototype bug.
Deep where you will mutate
A copies collections and nested objects you will change. Share immutable values: header strings, Money, Instant.
Prototype is not Factory Method
Factory Method answers “which class?” Prototype answers “I already have one; give me another like it.” Do not use clone as a substitute for a factory. If construction is cheap and you do not have a ready example, just construct.
Builder assembles from parts. Prototype starts from a finished example. A chess engine often uses both: build the opening position once, then copy the board for each candidate move.
Where this shows up in machine coding
Board games
Chess and tic-tac-toe copy a position to try a move. Share immutable piece types; copy the mutable squares.
Configured reports
A template with columns and filters. Issue this week’s copy; change the date. Do not re-type the header.
Test fixtures
A valid Ticket prototype. Each test copies and tweaks one field. Cheaper than a twelve-argument constructor in every method.
Shallow copy of mutable insides
If copy() reuses the same List<Filter>, Monday’s extra filter appears on Tuesday’s report. Copy collections and nested objects you will mutate. Share only immutable values.
Using Cloneable because the pattern is named Prototype
Implement copy() with a clear deep/shallow story. Cloneable does not document what is copied and is easy to get wrong in an interview.
A board that shares squares is not a clone
final class Board {
private final Piece[][] squares;
Board copy() {
Piece[][] next = new Piece[8][8];
for (int r = 0; r < 8; r++) {
System.arraycopy(squares[r], 0, next[r], 0, 8);
}
return new Board(next);
}
}
// Wrong: both boards share the same array.
// Board brokenCopy() { return new Board(squares); }Piece can be shared if it is immutable. The array cannot. In an interview, state that clearly — it shows you understand Prototype, not only the name.
copy() should be a method you can read
A one-line return (Board) super.clone() hides the shallow/deep story. Spell the constructor arguments. Interviewers can audit what is shared. If a field is missing from copy(), say so — that is a bug, not a shortcut. A reviewer’s first question is always “what is shared?” Have the list ready.
When construction is expensive
A styled widget that loaded fonts and metrics, a report that parsed twelve columns, a board that placed thirty-two pieces — those are prototypes. A Ticket with four fields is not. If new is cheap and you do not already have a correct example, construct. Prototype is about copying a ready example, not inventing a performance trick.
In snake and ladder, copying a board to simulate a roll is honest. Rebuilding the snakes from a config file each roll is not.
Prototype vs Memento vs undo
Memento saves a snapshot so you can restore later without exposing fields. Prototype creates a new working object from an example. A chess engine copies the board to try a move (Prototype). Undo of a played move is Command, and may keep a small memento if reverse is messy (castling).
Do not implement Cloneable “because the pattern is named Prototype.” Write copy(). Say what is shared. Say what is copied. That explanation is what interviewers want to hear.
Share
Immutable Piece, header string, Money
Copy
Mutable squares, filter lists, cursors
Tweak after
Date, title, the one extra filter
A test fixture that is a prototype
class Tickets {
static Ticket validCar() {
return new Ticket(TicketId.of("T-1"), new Car("KA-01"), SpotId.of("A1"), Instant.parse("2026-08-13T10:00:00Z"));
}
}
@Test
void overtimeUsesExitTime() {
Ticket t = Tickets.validCar().copy().withEntry(Instant.parse("2026-08-13T08:00:00Z"));
assertTrue(t.duration(Instant.parse("2026-08-13T12:00:00Z")).toHours() >= 4);
}