Overview
The Flyweight pattern reduces memory by sharing the common, immutable part of many similar objects. It splits object state into intrinsic state (shared, like a tree type's texture and mesh) and extrinsic state (unique per instance, like each tree's position). A factory caches flyweights so each intrinsic combination exists once.
Flyweight matters when you have huge numbers of objects: characters in a text editor, trees or bullets in a game, map markers, or tokens in a compiler. Java's Integer cache and string interning are everyday flyweights.
A book has millions of letters, but the shape of the letter 'e' in a given font is stored once. Each occurrence only records where it appears.
When to use it
- Millions of similar objects consume too much memory.
- Most object state can be shared and made immutable.
- Identity of individual objects does not matter for the shared part.
Where it shows up in interviews
Recognize it when: huge counts of similar objects.
- Design a text editor
- Design a game with a forest of trees
- Design a map with millions of markers
Where it is used in real software
Small integers (-128 to 127) and interned strings are shared instances.
GPU instancing renders thousands of copies of one mesh with per-instance transforms.
Glyph caches share font rendering data across characters.
Key terms
- Intrinsic state
- Shared, immutable data stored in the flyweight.
- Extrinsic state
- Context-specific data passed in or stored separately.
- Flyweight factory
- Returns cached instances for a key.
- Interning
- Keeping one canonical copy of equal values.
How it works, step by step
- 1Measure memory
Confirm object count is the problem.
- 2Split state
Intrinsic (shared) vs extrinsic (unique).
- 3Make intrinsic state immutable
Safe to share.
- 4Create a factory with a cache
Key by intrinsic attributes.
- 5Store extrinsic state separately
In lightweight instance records.
Forest of one million trees
Each tree type has a 50 KB texture; 3 types
| Design | Texture memory | Per-tree memory |
|---|---|---|
| Texture per tree | 1,000,000 x 50 KB = 50 GB | Large |
| Flyweight TreeType shared | 3 x 50 KB = 150 KB | x, y, type reference (~24 bytes) |
NOWDesign: Texture per tree | Texture memory: 1,000,000 x 50 KB = 50 GB | Per-tree memory: Large
Sharing intrinsic state turns an impossible memory footprint into a trivial one.
Implementation
class TreeType { // flyweight: intrinsic, immutable constructor(readonly name: string, readonly color: string, readonly texture: Uint8Array) {} draw(x: number, y: number) { return `${this.name}@${x},${y}`; }} class TreeTypeFactory { private static cache = new Map<string, TreeType>(); static get(name: string, color: string) { const key = `${name}:${color}`; let type = this.cache.get(key); if (!type) { type = new TreeType(name, color, new Uint8Array(50_000)); // loaded once this.cache.set(key, type); } return type; } static count() { return this.cache.size; }} class Tree { // extrinsic state only constructor(readonly x: number, readonly y: number, readonly type: TreeType) {}} const forest = Array.from({ length: 100_000 }, (_, i) => new Tree(i % 1000, Math.floor(i / 1000), TreeTypeFactory.get(i % 2 ? "oak" : "pine", "green")));TreeTypeFactory.count(); // 2Complexity and performance
vs O(n) large objects.
Factory cache.
Trade-offs
Saves memory but splits state and complicates code; only use when object counts are huge.
Shared factories need concurrent maps; flyweights must be immutable.
Variants and related techniques
Canonicalize equal values (strings, enums).
Reuse mutable objects over time; different from sharing immutable ones.
Common mistakes
- Mutable flyweights.
Fix: Shared state must be immutable, or one change affects every user.
- Premature use.
Fix: Measure memory first; modern JVMs handle millions of small objects.
Interview questions
Intrinsic vs extrinsic state?
Intrinsic state is shared and context-independent (the letter shape, the tree texture) and lives in the flyweight. Extrinsic state varies per use (position, color override) and is stored or passed separately.
How would you store characters in a text editor efficiently?
Share glyph flyweights for each (character, font, size) combination and store only positions and references per character, often combined with a piece table or rope for the text itself.
Practice problems
| Problem | Difficulty | What it trains |
|---|---|---|
| Forest renderer with shared tree types | Medium | State split. |
| Map with millions of markers and shared icons | Medium | Factory cache. |