Structural Cache

Flyweight

Flyweight cuts memory usage for large populations of similar objects by factoring out the data they have in common into shared instances, leaving each object to hold only what makes it unique.

Complexity
Popularity

Problem

A map-rendering engine needs to place a million trees across a forest layer. Each tree object naively stores its coordinates, current growth stage, plus a mesh, a texture atlas, and material settings describing what an oak or a pine looks like.

The mesh and texture data alone might be several megabytes per species, and it's identical across every tree of that species - yet if it lives inside each `Tree` instance, a million trees means a million redundant copies of the same few megabytes, quickly exceeding any reasonable memory budget and stalling the renderer.

Solution

Split each object's data along a fault line: the part that's identical across many instances (species, mesh, texture - the intrinsic state) versus the part that's unique to this one instance (position, growth stage - the extrinsic state).

Pull the intrinsic part out into a small, shared object - the flyweight - and store only one copy per distinct combination. The extrinsic part stays with the caller and gets passed into the flyweight's methods as arguments whenever behavior is needed. A factory sits in front of flyweight creation: it hands back an existing shared instance if one already matches the requested intrinsic data, and only builds a new one when it doesn't.

When to Use

  • The application needs to keep an enormous number of objects alive at once, and their combined memory footprint is becoming a real constraint.
  • Most of what makes those objects heavy is data that repeats identically across many of them, leaving only a small, cheap remainder that's genuinely unique per instance.

Real-World Examples

  • **Browser text rendering** - a font/size/weight glyph bitmap is rasterized once and shared by every occurrence of that character on the page; each occurrence only needs its own screen position.
  • **Java's `Integer.valueOf()` cache** - small boxed integers (-128 to 127) are pooled and reused rather than allocated fresh, since the same handful of values recur constantly in typical programs.
  • **Game engine particle/instance systems** - thousands of bullets or foliage sprites reference one shared mesh-and-material record, while each instance keeps only its own transform and velocity.