Prototype Pattern in Document Editor
A document editor like Figma or Canva allows users to create shapes (rectangles, circles, text boxes) and duplicate them. Instead of rebuilding each shape with all its properties (color, position, border style, effects), we clone existing shapes. This is especially valuable when shapes have complex configurations or attached resources.
+ draw(): void
+ setPosition(x, y): void
- width, height: int
- color: Color
- borderStyle: Style
- radius: int
- fillColor: Color
- text: String
- font: Font
- effects: List<Effect>
+ addShape(shape: Shape): void
When a user selects a shape and presses duplicate, the Canvas calls shape.clone(). Each shape type implements cloning differently. Rectangle copies its dimensions and styling. TextBox performs a deep clone of its effects list because effects are mutable and shouldn't be shared between instances.
function duplicateShape(original: Shape):
cloned = original.clone()
cloned.setPosition(original.x + 10, original.y + 10)
shapes.add(cloned)
return cloned
// In TextBox class
function clone():
newTextBox = new TextBox()
newTextBox.text = this.text
newTextBox.font = this.font // shallow (Font is immutable)
newTextBox.effects = deepCloneList(this.effects)
return newTextBox
The TextBox has a list of effects (shadows, glows, gradients). If we shallow copy the list, both original and clone share the same effect objects. Modifying an effect on the clone would affect the original. Therefore, we deep clone the effects list. However, if Font objects are immutable, shallow copying the font reference is safe and efficient.