The Flyweight Design Pattern is a structural pattern that focuses on efficiently sharing common parts of object state across many objects to reduce memory usage and boost performance.
It’s particularly useful in situations where:
When building high-volume systems like text editors (with thousands of character glyphs), map applications (with repeated icons or tiles), or game engines (with many similar objects like trees or particles), developers often instantiate huge numbers of objects many of which are functionally identical.
But this can lead to significant performance issues, excessive memory allocation, and poor scalability especially when most of these objects differ only by a few small, context-specific values.
The Flyweight Pattern solves this by sharing common state (the intrinsic part) across all similar objects and externalizing unique data (the extrinsic part). It allows you to create lightweight objects by caching and reusing instances instead of duplicating data.
Let’s walk through a real-world example to see how we can apply the Flyweight Pattern to drastically reduce memory usage and create scalable object-heavy systems.
Imagine you're building a rich text editor that needs to render characters on screen — much like Google Docs or MS Word.
Every character (a
, b
, c
, ...
, z
, punctuation, etc.) must be displayed with formatting information such as:
A naïve implementation might look like this:
Now imagine rendering a 10-page document with 500,000 characters. Even if most characters share the same font, size, and color — you’re still allocating half a million objects, most of which contain duplicate formatting data.
Each character glyph holds repeated data (font, size, color) — even though these are shared across thousands of characters. You're wasting memory by storing the same values over and over.
Creating and managing a massive number of objects increases GC pressure, reduces cache performance, and may cause your app to lag on lower-end machines.
Want to render an entire book or open multiple large documents? Memory usage will balloon out of control, and you'll hit limits quickly.
We need a way to:
This is where the Flyweight Pattern comes in.
The Flyweight Pattern minimizes memory usage by sharing as much data as possible between similar objects.
Instead of creating a new object for every instance — even when the data is the same — the Flyweight Pattern allows you to reuse shared objects (called flyweights) and externalize the state that differs between them.
Declares a method like draw(x, y)
that takes extrinsic state (position)
Implements the flyweight and stores intrinsic state like font and symbol
Caches and reuses flyweights to avoid duplication
Maintains extrinsic state and uses shared flyweights to perform operations
Let’s implement the Flyweight Pattern to optimize how we render text in a document editor. Our goal is to share common formatting properties (font, size, color) across characters and store only unique data (like position) at the instance level.
The flyweight interface declares a method like draw(x, y)
that renders a character on screen.
Importantly, the flyweight does not store extrinsic state (like position). Instead, this data is supplied by the client at runtime.
Each flyweight object represents shared formatting (intrinsic state), but it expects position to be passed in when drawn.
This class holds the intrinsic state — the shared, repeatable properties like:
'A'
)All glyphs with the same combination of character, font, size, and color can reuse the same
CharacterGlyph
instance.
The factory ensures flyweights are shared and reused. It checks whether a flyweight with a given set of intrinsic values already exists and returns it, or creates a new one if it doesn't.
This factory is the heart of memory optimization. It ensures no duplicate formatting objects are created.
The client is responsible for rendering the document. It:
RenderedCharacter
objects that contain a flyweight and coordinatesFinally, let’s use the system to render two words, each with different formatting:
Only 8 shared glyphs were created, even though we rendered 10 characters — memory-efficient and scalable!