Prototype Pattern: Efficient Object Cloning
design-patternscreationalprototype

Intent
The Prototype pattern allows creating new objects by copying an existing instance (the prototype), avoiding the cost of creating objects from scratch.
The Problem
Creating complex objects from scratch can be expensive:
// Creating a complex document is expensive
const doc1 = new Document();
doc1.loadTemplate('report');
doc1.applyStyles(defaultStyles);
doc1.initializePlugins(['charts', 'tables']);
// 500ms of initialization...
// What if I need 100 similar documents?The Solution: Prototype
classDiagram
class Prototype {
<<interface>>
+clone(): Prototype
}
class ConcretePrototype {
-state: State
+clone(): ConcretePrototype
}
Prototype <|.. ConcretePrototypeTypeScript Implementation
interface Cloneable<T> {
clone(): T;
}
class Document implements Cloneable<Document> {
constructor(private config: DocumentConfig) {}
clone(): Document {
return new Document({
...this.config,
styles: { ...this.config.styles },
plugins: [...this.config.plugins],
metadata: {
...this.config.metadata,
created: new Date(),
},
});
}
}
// Prototype registry
class DocumentRegistry {
private prototypes = new Map<string, Document>();
register(name: string, prototype: Document): void {
this.prototypes.set(name, prototype);
}
create(name: string): Document {
const prototype = this.prototypes.get(name);
if (!prototype) throw new Error(`Prototype '${name}' not found`);
return prototype.clone();
}
}
// Usage
const registry = new DocumentRegistry();
registry.register('report', expensiveDocument);
// Create multiple documents (fast)
const doc1 = registry.create('report');
const doc2 = registry.create('report');When to Use
| Situation | Recommendation |
|---|---|
| Expensive objects to create | ✅ Recommended |
| Templates or base configs | ✅ Recommended |
| Object caches | ✅ Recommended |
| Simple objects | ❌ new is sufficient |
Conclusion
Prototype is ideal when creation from scratch is expensive and you can reuse existing instances as a starting point.