install
source · Clone the upstream repo
git clone https://github.com/Intense-Visions/harness-engineering
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/claude-code/gof-prototype-pattern" ~/.claude/skills/intense-visions-harness-engineering-gof-prototype-pattern && rm -rf "$T"
manifest:
agents/skills/claude-code/gof-prototype-pattern/SKILL.mdsource content
GOF Prototype Pattern
Clone objects using prototype registry and structured clone for deep copy scenarios.
When to Use
- Creating a new object from scratch is expensive (network call, heavy computation) and cloning is cheaper
- You need many variations of a base object with slight differences
- You want to avoid subclassing for object variations — prefer cloning over inheritance
- You maintain a registry of pre-initialized templates to clone on demand
Instructions
Explicit clone method (most control):
interface Cloneable<T> { clone(): T; } class DocumentTemplate implements Cloneable<DocumentTemplate> { constructor( public title: string, public sections: string[], public metadata: Record<string, string> ) {} clone(): DocumentTemplate { return new DocumentTemplate( this.title, [...this.sections], // shallow copy of array { ...this.metadata } // shallow copy of object ); } } // Use a cloned base instead of constructing from scratch const invoiceTemplate = new DocumentTemplate( 'Invoice', ['Header', 'Line Items', 'Total', 'Footer'], { type: 'invoice', version: '1.0' } ); const march = invoiceTemplate.clone(); march.title = 'Invoice - March 2024'; march.metadata['period'] = '2024-03';
structuredClone for deep copies (Node 17+, no custom classes):
interface ConfigSnapshot { database: { host: string; port: number; pool: { min: number; max: number } }; features: string[]; limits: Record<string, number>; } function cloneConfig(config: ConfigSnapshot): ConfigSnapshot { return structuredClone(config); // deep clone, no circular reference issues } const baseConfig: ConfigSnapshot = { database: { host: 'localhost', port: 5432, pool: { min: 2, max: 10 } }, features: ['auth', 'billing'], limits: { rateLimit: 100, timeout: 5000 }, }; const devConfig = cloneConfig(baseConfig); devConfig.database.pool.max = 2; // doesn't affect baseConfig devConfig.features.push('debug');
Prototype registry:
class ShapeRegistry { private prototypes = new Map<string, Shape>(); register(name: string, prototype: Shape): void { this.prototypes.set(name, prototype); } create(name: string): Shape { const proto = this.prototypes.get(name); if (!proto) throw new Error(`Unknown shape prototype: ${name}`); return proto.clone(); } } // Pre-warm registry at startup const registry = new ShapeRegistry(); registry.register('red-circle', new Circle({ radius: 10, color: 'red' })); registry.register('blue-rect', new Rectangle({ width: 20, height: 10, color: 'blue' })); // Clone cheaply at runtime const shape1 = registry.create('red-circle'); const shape2 = registry.create('red-circle');
Object.assign for simple shallow clones:
class UserProfile { constructor( public name: string, public email: string, public preferences: { theme: string; locale: string } ) {} withPreferences(overrides: Partial<typeof this.preferences>): UserProfile { return Object.assign(new UserProfile(this.name, this.email, { ...this.preferences }), { preferences: { ...this.preferences, ...overrides }, }); } }
Details
Deep vs. shallow clone — pick the right tool:
| Scenario | Tool |
|---|---|
| Simple POJOs, no class methods needed | |
| Class instances with methods | Explicit method |
| Shallow one-level copy | or |
| Arrays | or |
structuredClone limitations: Cannot clone functions, class instances (loses prototype chain), DOM nodes, or WeakMap. If you need class instances, use an explicit
clone() method.
Anti-patterns:
- Forgetting to deep-copy nested mutable objects — mutations in the clone affect the original
- Cloning objects with circular references without handling them —
handles this,structuredClone
does notJSON.parse(JSON.stringify()) - Treating prototype as a substitute for dependency injection — cloning infrastructure objects (DB pools, HTTP clients) is wrong; inject them instead
JSON round-trip clone (legacy, avoid):
// Works for simple data, but loses: undefined, Date, functions, class prototypes const copy = JSON.parse(JSON.stringify(original)); // Prefer structuredClone() instead
Source
refactoring.guru/design-patterns/prototype
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.