CreationalTypeScriptverifiedVerified
Prototype Pattern in TypeScript
Creates new objects by cloning an existing instance, avoiding the cost of building from scratch.
How to Implement the Prototype Pattern in TypeScript
1Step 1: Define the cloneable Prototype interface
interface Prototype<T> {
clone(): T;
}2Step 2: Implement cloneable Shape and GroupShape
class Shape implements Prototype<Shape> {
constructor(
public type: string,
public x: number,
public y: number,
public color: string
) {}
clone(): Shape {
return new Shape(this.type, this.x, this.y, this.color);
}
toString(): string {
return `${this.color} ${this.type} at (${this.x}, ${this.y})`;
}
}
class GroupShape implements Prototype<GroupShape> {
constructor(public name: string, public shapes: Shape[]) {}
clone(): GroupShape {
return new GroupShape(this.name, this.shapes.map(s => s.clone()));
}
}3Step 3: Create a prototype registry for template management
class ShapeRegistry {
private templates = new Map<string, Shape>();
register(key: string, shape: Shape): void {
this.templates.set(key, shape);
}
create(key: string): Shape {
const template = this.templates.get(key);
if (!template) throw new Error(`No template: "${key}"`);
return template.clone();
}
}4Step 4: Clone and customize objects from the registry
const registry = new ShapeRegistry();
registry.register("red-circle", new Shape("circle", 0, 0, "red"));
const c1 = registry.create("red-circle");
const c2 = registry.create("red-circle");
c2.x = 50;
c2.y = 100;
console.log(c1.toString()); // "red circle at (0, 0)"
console.log(c2.toString()); // "red circle at (50, 100)"
console.log(c1 === c2); // false// ── Document Template System ──────────────────────────────────────
interface Cloneable<T> {
clone(): T;
}
class FontStyle implements Cloneable<FontStyle> {
constructor(
public family: string,
public size: number,
public weight: number,
public color: string
) {}
clone(): FontStyle {
return new FontStyle(this.family, this.size, this.weight, this.color);
}
}
class Margin implements Cloneable<Margin> {
constructor(public top: number, public right: number, public bottom: number, public left: number) {}
clone(): Margin { return new Margin(this.top, this.right, this.bottom, this.left); }
}
class Section implements Cloneable<Section> {
constructor(
public heading: string,
public content: string,
public font: FontStyle,
public margin: Margin,
public subsections: Section[] = []
) {}
clone(): Section {
return new Section(
this.heading, this.content,
this.font.clone(), this.margin.clone(),
this.subsections.map(s => s.clone())
);
}
}
class Document implements Cloneable<Document> {
private readonly id = crypto.randomUUID();
constructor(
public title: string,
public author: string,
public tags: string[],
public sections: Section[],
public headerFont: FontStyle,
public bodyFont: FontStyle,
public pageMargin: Margin
) {}
getId(): string { return this.id; }
clone(): Document {
return new Document(
this.title, this.author,
[...this.tags],
this.sections.map(s => s.clone()),
this.headerFont.clone(),
this.bodyFont.clone(),
this.pageMargin.clone()
);
}
}
// Template Registry
class TemplateRegistry {
private templates = new Map<string, Document>();
register(name: string, template: Document): void { this.templates.set(name, template); }
create(name: string): Document {
const t = this.templates.get(name);
if (!t) throw new Error(`Template "${name}" not found. Available: ${[...this.templates.keys()].join(", ")}`);
return t.clone();
}
list(): string[] { return [...this.templates.keys()]; }
}
// Pre-built templates
const registry = new TemplateRegistry();
const serif = new FontStyle("Georgia", 12, 400, "#333");
const sans = new FontStyle("Helvetica", 11, 400, "#444");
const margin = new Margin(72, 72, 72, 72);
registry.register("report", new Document(
"Untitled Report", "", ["report"],
[
new Section("Executive Summary", "", serif.clone(), margin.clone()),
new Section("Findings", "", serif.clone(), margin.clone(), [
new Section("Data Analysis", "", serif.clone(), margin.clone()),
]),
new Section("Recommendations", "", serif.clone(), margin.clone()),
],
new FontStyle("Georgia", 24, 700, "#111"), serif, margin
));
const report = registry.create("report");
report.title = "Q4 Performance Review";
report.author = "Alice Chen";
export { Document, Section, FontStyle, Margin, TemplateRegistry, type Cloneable };Prototype Pattern Architecture
hourglass_empty
Rendering diagram...
lightbulb
Prototype Pattern in the Real World
“Think of a cell dividing through mitosis. Instead of building a new cell from raw amino acids, the existing cell duplicates itself — copying its DNA, organelles, and membrane. The result is a fully functional copy produced far faster than assembling one molecule at a time.”