---
name: flyweight
description: This skill should be used when the user asks about "flyweight pattern", "when to use flyweight", "implement flyweight", "memory optimization", "shared objects", "intrinsic vs extrinsic", or mentions needing to support large numbers of similar objects efficiently.
version: 1.0.0
---

# Flyweight Pattern

## What Is It
The Flyweight pattern minimizes memory usage by sharing common parts of state between multiple objects instead of keeping all data in each object. It separates intrinsic (shared) state from extrinsic (unique) state to support large numbers of fine-grained objects efficiently.

## When to Use
- **Large numbers of similar objects** - When memory is a concern
- **Text editors** - Character formatting with shared fonts
- **Game development** - Trees, particles, bullets with shared textures
- **UI frameworks** - Icons, fonts, colors shared across widgets
- **Caching immutable data** - Avoid duplicating identical data
- **Connection pools** - Share limited expensive resources

## When NOT to Use
- **Few objects** - Overhead isn't worth it for small numbers
- **Unique objects** - If most state is extrinsic, sharing provides little benefit
- **Mutable shared state** - Changes affect all users of the flyweight
- **Simple applications** - Don't optimize prematurely

## How to Implement

### Implementation Steps
1. Identify intrinsic (shared, immutable) vs extrinsic (unique, context-specific) state
2. Create flyweight class containing only intrinsic state
3. Create flyweight factory that manages pool of shared flyweights
4. Factory returns existing flyweight or creates new one
5. Client passes extrinsic state to flyweight methods

### TypeScript Implementation

```typescript
// Flyweight - shared intrinsic state
class TreeType {
  constructor(
    public name: string,
    public color: string,
    public texture: string
  ) {}

  draw(x: number, y: number): void {
    // Uses extrinsic state (x, y) with intrinsic state
    console.log(`Drawing ${this.name} at (${x}, ${y})`);
  }
}

// Flyweight Factory
class TreeFactory {
  private treeTypes: Map<string, TreeType> = new Map();

  getTreeType(name: string, color: string, texture: string): TreeType {
    const key = `${name}_${color}_${texture}`;
    if (!this.treeTypes.has(key)) {
      this.treeTypes.set(key, new TreeType(name, color, texture));
    }
    return this.treeTypes.get(key)!;
  }
}

// Context - holds extrinsic state
class Tree {
  constructor(
    private x: number,
    private y: number,
    private type: TreeType  // Flyweight reference
  ) {}

  draw(): void {
    this.type.draw(this.x, this.y);
  }
}
```

## Code Examples
See `examples/` directory for runnable TypeScript implementations:
- `examples/flyweight.ts` - Basic implementation with text formatting
- `examples/flyweight-advanced.ts` - Real-world example with game particles

## Related Patterns
- **Composite** - Often use flyweights for shared leaf nodes
- **Factory Method** - Factory can return flyweights
- **State** - State objects can be flyweights
- **Strategy** - Strategy objects can be flyweights
