What is flyweight?

A flyweight is a software design pattern that lets you share many fine‑grained objects efficiently. Instead of creating a separate object for every item, you reuse a small set of shared objects and store only the unique data separately. This reduces memory usage while still letting each item behave as if it had its own object.

Let's break it down

  • Intrinsic state: the part of an object that is the same for all instances (e.g., the shape of a chess piece). This data lives inside the shared flyweight object.
  • Extrinsic state: the part that varies per instance (e.g., the piece’s position on the board). This data is supplied from outside whenever the flyweight is used.
  • Flyweight factory: a central place that creates flyweights on demand and returns existing ones if they already exist.
  • Client code: asks the factory for a flyweight, then combines it with the extrinsic state to perform an operation.

Why does it matter?

Because many applications need thousands or millions of tiny objects (characters, particles, UI widgets). Storing a full object for each one can quickly exhaust memory and slow the program down. Flyweight cuts down on duplicate data, leading to lower memory consumption, faster loading times, and often better overall performance.

Where is it used?

  • Text editors and word processors (each character shares a glyph object).
  • Graphical user interfaces (buttons, icons, or menu items that look the same).
  • Video games (trees, bullets, or particles that share the same model or texture).
  • Compiler design (syntax tree nodes that represent the same token type).
  • Web browsers (rendering of repeated HTML elements like list items).

Good things about it

  • Memory efficiency: dramatically reduces the number of objects in memory.
  • Performance boost: less allocation and garbage collection work.
  • Simplified updates: change the intrinsic state once and all users see the change.
  • Scalability: makes it feasible to handle very large numbers of similar items.

Not-so-good things

  • Added complexity: you must separate intrinsic and extrinsic state correctly.
  • Thread‑safety concerns: shared objects need careful handling in multithreaded environments.
  • Limited to immutable intrinsic data: mutable shared state can cause bugs.
  • Potential overhead: the factory lookup and passing extrinsic data may offset gains for small numbers of objects.