Prototype
Creating an Enemy means loading models, stats and sounds, which is slow.
Give the object a copy() method.
Building an object is costly but copying is cheap
The picture from life
A teacher has a master worksheet with the school name, layout and instructions. For every student she photocopies it and then writes a name on the copy. She does not retype the whole sheet each time, and writing on a copy leaves the master unchanged.
The problem
What goes wrong when you do not use it.
Creating an Enemy means loading models, stats and sounds, which is slow. Spawning a hundred goblins this way takes seconds, even though they are all the same except for position.
- creates
- Building an object is costly but copying is cheap
- Many objects differ only slightly from a template
- You do not want to depend on the concrete class when copying
The idea
How the pattern fixes it.
Give the object a copy() method. Build one fully loaded prototype, then clone it and change only what differs. Remember to copy inner mutable parts too (a deep copy) so clones do not share them.
- creates
Who is who
- Enemy
- The prototype. Knows how to copy itself.
- copy()
- Returns an independent duplicate (deep for inner lists).
- Registry (optional)
- A shelf of ready prototypes by name.
Build it in steps
- 1Build one fully prepared object once.
- 2Add copy() that duplicates it, including nested data.
- 3Clone it each time you need a new one.
- 4Change only the parts that differ.
Watch it run
Step through the calls. Tap an arrow to jump to it.
Ask the template for a copy. The slow loading is not repeated.
copy()The code
Python and Java. Try writing the classes yourself from the diagram first.
import copy
class Enemy:
def __init__(self, kind):
self.kind = kind # imagine slow loading here
self.items = []
self.position = 0
def copy(self):
return copy.deepcopy(self) # deep: the items list is copied too
def demo():
template = Enemy("goblin")
first = template.copy()
second = template.copy()
first.position = 10
second.items.append("sword")
return template.position, first.position, template.items, first.items, second.itemsWhat you gain
- Skips costly set-up
- Clone without knowing the concrete class
What it costs
- Deep copying cyclic or complex objects is tricky
- Forgetting a nested field makes clones secretly share state
You have already met it in
- JavaScript's prototype chain and Object.create
- Java's Cloneable / clone() and Python's copy module
- Duplicating a slide or a spreadsheet tab
Often mixed up with
Make it stick
Make a Document prototype with a list of paragraphs. Clone it twice, edit each clone differently and prove the original and the other clone did not change.