The purpose on using the flyweight pattern is to avoid unnecessary object initialization and thus save space. As defined by GOF, an object can have two states, the intrinsic and the extrinsic state:
- Intrinsic state: Is stored in the flyweight; it consists of information that's independent on the flyweights context, thereby
making it shareable.
- Extrinsic state: depends on and varies with the flyweight's context and therefore cant be share. Client objects are responsible for
passing extrinsic state to the flyweight when it needs it.
Assuming that we want to develop a simple text editor application where each column contains all the rows of the text and the row can contain characters.
The dilemma here is how to design the Character class. The char c
within the Character class should be the main (intrinsic state) object. However, a char can have a Font and and Size (extrinsic state); thus we need to store its extrinsic state on the Row (client) and access it when needed. For this purpose, two lists which store the Fonts and the Sizes are created.
By following the Flyweight pattern, the Character is now reusable and the objects are being referenced from a specific list of objects (the flyweight pool) which contains all the ASCII symbols (Character
objects).
Here is what I described visually:

For printing 'hello', only 4 Character
objects are needed, instead of 5. Once the font is changed, no new objects are required; note that this would not be possible had we stored the extrinsic state on the Character class, e.g.,
class Character
{
char c;
int Size;
Font font;
....
}
Applying this pattern on large datasets would lead to significant optimizations on the memory complexity of the application and object reusability.