design patterns · advanced

Flyweight Pattern

Flyweight is a structural GoF pattern that uses sharing to support large numbers of fine-grained objects efficiently. It splits each object's state into intrinsic state — shared, immutable, and context-independent (a glyph's character shape and font) — and extrinsic state — unique per use and context-dependent (the glyph's position). One shared flyweight is stored per distinct intrinsic value, and extrinsic state is passed in at call time (draw(x,y)), so a document with millions of characters keeps millions of tiny (pointer+position) records but only as many Glyph objects as there are distinct character/font combinations. A FlyweightFactory owns a pool keyed by intrinsic state and is the sole source of flyweights — returning an existing shared instance or creating it once — which is what guarantees sharing; clients never construct flyweights directly. The flyweight must be immutable because it is shared across countless contexts, so intrinsic state is const and extrinsic state is never stored; in C++ a shared_ptr<const T> pool is idiomatic, with the pool's lazy creation guarded for thread safety. The payoff is dramatic memory reduction (and better locality / fewer allocations) when many objects share intrinsic state that dominates memory; the costs are the complexity of splitting state and threading extrinsic data through calls, and possible CPU overhead. It is distinct from an object pool, which recycles interchangeable mutable objects for lifetime management, whereas Flyweight shares immutable content-keyed value-objects. Typical uses: text glyphs, map tiles, game particles/entities, terminal cells, and interned strings.

🔑 Key line

Flyweight (structural): share large numbers of fine-grained objects by splitting state into INTRINSIC (shared, immutable, context-free — stored in the flyweight) and EXTRINSIC (per-use, context-dependent — passed in at call time). A factory pool keyed by intrinsic state returns one shared immutable instance per distinct value (shared_ptr<const T> in C++), so a million-char document holds ~100 glyphs. Big memory win when many objects share intrinsic state; ≠ a mutable object pool.

The code

// Flyweight — share one immutable INTRINSIC object across many uses;
// keep the per-use EXTRINSIC state outside. Saves huge memory.
struct Glyph { // Flyweight: INTRINSIC, shared
char ch;
Font font; // same for every 'a' on the page
void draw(int x, int y) const; // x,y are EXTRINSIC (passed in)
};
class GlyphFactory { // hands out SHARED flyweights
std::unordered_map<std::string, std::shared_ptr<const Glyph>> pool_;
public:
std::shared_ptr<const Glyph> get(char c, const Font& f) {
auto key = makeKey(c, f);
auto& g = pool_[key];
if (!g)
g = std::make_shared<Glyph>(Glyph{c, f}); // create once
return g; // everyone shares this instance
}
};
// A document with millions of chars stores POINTERS to ~100 glyphs
// plus each char's own position (extrinsic) — not millions of Glyphs.
struct PlacedChar {
std::shared_ptr<const Glyph> g;
int x, y;
};

What this lesson walks through

  1. 01Intent — share the part that's common to millions
  2. 02Structure — a factory pools shared flyweights
  3. 03Intrinsic shared, extrinsic passed in
  4. 04Gotcha — never share mutable extrinsic state

A text editor has millions of characters but only ~100 distinct glyphs. Flyweight stores the heavy, identical part (the glyph shape, font metrics) ONCE and shares it across all occurrences, slashing memory.

See it animated — step by step, at your own pace

Unlock the full interactive walkthrough of Flyweight Pattern and 100+ animated C++ interview lessons.

← Previous
Bridge Pattern
Next →
GoF Observer — Publish-Subscribe State Notification