SwadhyAI Notes

All Low-Level Design notes

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?

Diagram text: the exact Mermaid definition below preserves the nodes, labels, and connections. Enable JavaScript to view the rendered diagram.
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.

java
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

java
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

java
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);
}

Related pages