Why this matters
When a game needs to render 10 000 trees, each with a 1 MB texture, naively storing the texture in every object consumes 10 GB. Most of that data is identical. Flyweight splits object state into two parts: intrinsic (shared, immutable — the tree type, texture, color) and extrinsic (unique — the x/y coordinates). A factory caches one TreeType per species; each Tree instance stores only a reference to it plus its own position.
The problem
Bad
The solution
Good
Intrinsic vs extrinsic state
The intrinsic state must be immutable — if shared objects could be mutated, one tree changing its texture would affect all trees of that species. In Python, a frozen=True dataclass or @lru_cache enforces this. In TypeScript, readonly fields and a factory that returns from a Map cache accomplish the same. String interning in languages like Java is Flyweight applied automatically to string literals.
Key takeaway
Flyweight pays off when you have thousands of objects that share most of their state — split the shared part into one cached object instead of duplicating it.