Flyweight Pattern

What is Flyweight?
Why Use It? (Intent)
Key Concepts
Real-Life Example: Game Particles
The Problem:
- In a game, you have thousands of particles (bullets, missiles).
- Each particle stores its own copy of color, image, and position.
- Game crashes on low-RAM devices because too much memory is used.
The Solution:
- Move shared data (like color, sprite) to a flyweight.
- Keep unique data (like position, speed) outside, in a context object.
- Now, instead of 1000 full particles, you store 1 flyweight per type (bullet, missile, shrapnel) and reuse it.
Code Example: Forest with Trees
Without Flyweight:
- Position
- Name
- Color
- Texture
With Flyweight:
Pseudo
// Flyweight: shared part
class TreeType {
name
color
texture
draw(x, y) // takes position as parameter
}
// Factory to manage and reuse TreeTypes
class TreeFactory {
static treeTypes = []
static getTreeType(name, color, texture) {
if not found in treeTypes:
create new TreeType
return existing TreeType
}
}
// Context: unique part
class Tree {
x, y
type: TreeType
draw() {
type.draw(x, y)
}
}
How to Implement
- Identify common data: make it intrinsic (put in flyweight).
- Separate unique data: make it extrinsic (pass it in).
- Create a factory to manage flyweights.
- Use flyweights instead of full objects wherever possible.
When to Use Flyweight
- You need tons of similar objects
- Memory is tight (e.g., mobile games, graphics apps)
- Many objects have repeating/shared data
Pros and Cons
- β Big memory savings
- β Makes apps faster on low-spec systems
- β More complex code
- β Slight CPU cost (extrinsic data must be passed every time)