Memory Optimization through Sharing
Structural design patterns are about how to put classes and objects together into bigger structures. The Flyweight Pattern is a structural pattern that saves memory. It does this by sharing data between objects that look alike.
The problem: a program may need millions of objects, and many of them hold the same data. A forest of 1 million trees would store the name "Oak" 1 million times. That wastes memory and can crash the program.
1. What is the Flyweight Pattern?
Use the Flyweight Pattern when a program needs a huge number of objects, and many of them hold the same data. Instead of every object keeping its own copy, the data is stored once in a "Flyweight" object. All the other objects share it.
The Core Concept: State Separation
To share data, we split an object's data into two kinds:
- Intrinsic State (The "What"): Data that never changes and is the same for many objects (e.g., a tree's name, color, and texture). It is stored inside the Flyweight.
- Extrinsic State (The "Where"): Data that is different for every object (e.g., a tree's $x, y$ coordinates). It is stored outside the Flyweight and passed in when needed.
2. Real-Life Analogy: Trees in a Video Game
Imagine an open-world game with a massive forest:
- Shared Model: Every "Oak" tree uses the same 3D model and leaf texture. Loading that model 10,000 times could crash the game. So the model is loaded once and shared. This shared model is the Flyweight.
- Unique Data: Every tree has its own position on the map and a slightly different size. This is the Extrinsic State.
The game engine draws the one "Oak" model 10,000 times at different coordinates. This saves gigabytes of RAM.
3. Class Diagram
In the diagram below, TreeFactory creates and keeps the shared TreeType objects. Each Tree is small: it holds only its coordinates and a reference to a TreeType.
4. Real-World Applications
- Google Maps: Shows millions of trees or landmarks. The "type" data (Oak, Pine) is shared, and only the GPS coordinates differ.
- Uber App: Draws dozens of nearby car icons. Many cars use the same icon, so the app reuses one shared flyweight object and only updates each car's $x, y$ position.
- Web Browsers: A page can have thousands of identical buttons or icons. Browsers reuse one shared style object (CSS rules) instead of giving every element its own copy.
5. Pros and Cons
Advantages
- Massive Memory Savings: Can cut RAM use by a huge amount when a program has very many objects.
- Performance Boost: Garbage Collection (GC, the cleanup of unused objects) has less work, because there are fewer heavy objects to track.
- Faster Initialization: Reusing an object is faster than building a new one.
Disadvantages
- Increased Complexity: You need a Factory and a clear split between intrinsic and extrinsic state.
- Execution Time: Each call has a tiny cost, because extrinsic state must be passed into the flyweight's methods.
6. When to Use
Use the Flyweight Pattern when:
- Your application uses a large number of objects (thousands or millions).
- The sheer number of objects makes memory use high.
- Most of an object's data can be made intrinsic (shared).
- The program does not care about object identity (whether two objects are the same instance), because shared objects are the same instance.