Flyweight
Flyweight shares immutable intrinsic state across many objects while clients supply extrinsic state, slashing memory for huge object counts. It trades simplicity and some CPU for memory savings.
The Flyweight pattern minimizes memory use by sharing common data among many fine-grained objects instead of storing it redundantly in each. It applies when a program must create a very large number of similar objects and the resulting memory footprint becomes a problem. The insight is to split an object's state into the part that can be shared and the part that cannot.
How It Works
Object state is divided into intrinsic state — constant, context-independent data that can be shared across many objects — and extrinsic state — data that varies per use and is supplied by the client at call time. A Flyweight stores only intrinsic state and is immutable, so it can be safely shared. A Flyweight Factory maintains a pool of flyweights and returns a shared instance for a given intrinsic state, creating it only if it does not already exist.
The client keeps the extrinsic state and passes it into the flyweight's methods. Thousands of logical objects thus map onto a small number of shared flyweight instances plus lightweight per-instance context.
When to Use It
Use Flyweight when an application uses a huge number of objects, storage cost is high because of that quantity, most object state can be made extrinsic, and removing the extrinsic state lets many groups be replaced by a few shared objects. Classic uses include glyphs in a text editor (the character's shape is shared; its position is extrinsic), tiles or sprites in games, and shared formatting or style objects.
It is inappropriate when objects have little shareable state, when their identity matters, or when the added indirection outweighs modest memory savings.
Trade-offs
Flyweight can dramatically cut memory consumption when the conditions hold, sometimes turning an infeasible workload into a practical one. The shared flyweights are immutable, which also makes them thread-safe.
The costs are increased complexity and a CPU/memory trade-off: extrinsic state must be computed or stored and passed in on every call, which can add runtime overhead and shift memory cost to the client. The code becomes harder to read because object state is split across two places. The pattern is only worthwhile under genuine memory pressure; applied prematurely it complicates the design for no gain.
Related Patterns
The Flyweight Factory typically uses a pool keyed by intrinsic state, much like a Multiton, and individual flyweights are often effectively Singletons. Flyweight frequently appears with Composite, where shared leaf nodes are flyweights. It differs from Object Pool: Object Pool lends out mutable objects for exclusive temporary use, while Flyweight shares immutable objects concurrently.
Example
A text editor represents each character as a glyph object carrying font, style, and outline — the intrinsic state. Rather than one object per character on screen, a flyweight factory returns one shared glyph per unique character-and-style combination. The document stores only positions and references to shared glyphs; rendering passes each glyph its position (extrinsic state). A million-character document uses a few hundred glyph objects instead of a million.