Flyweight Design Pattern in Java
Learn Flyweight Design Pattern in Java with real-world examples, memory optimization techniques, intrinsic and extrinsic state, UML diagrams, Java implementation, JVM examples, enterprise use cases, and interview questions.
What You Will Learn
In this article, you'll learn:
- What is Flyweight Pattern?
- Why Flyweight Pattern is Needed
- Memory Optimization Concepts
- Intrinsic vs Extrinsic State
- UML Diagrams
- Java Implementation
- JVM Examples
- Gaming Examples
- Enterprise Use Cases
- Benefits and Limitations
- Interview Questions
Introduction
Imagine building a game.
The game contains:
100,000 Trees
100,000 Soldiers
100,000 Cars
If every object stores:
Color
Texture
Shape
Coordinates
Size
Memory usage becomes enormous.
Example:
100,000 Trees
×
1 MB Each
=
100 GB Memory
Clearly impossible.
Most tree objects share common information:
Tree Type
Color
Texture
Shape
Only location changes.
Flyweight Pattern solves this problem.
What is Flyweight Pattern?
Flyweight is a Structural Design Pattern that reduces memory usage by sharing common object state among multiple objects.
Instead of creating:
100,000 Separate Objects
we create:
1 Shared Object
+
100,000 References
Purpose of Flyweight Pattern
Primary goal:
Reduce Memory Consumption
Improve Performance
Real World Analogy
Imagine a library.
Without sharing:
Every Student
Gets Their Own Book Copy
Requires thousands of books.
With sharing:
One Book
Used By Many Students
Much more efficient.
This is Flyweight.
Problem Without Flyweight
flowchart TD
A[Tree 1]
B[Tree 2]
C[Tree 3]
D[Tree 100000]
A --> X[Large Memory]
B --> X
C --> X
D --> X
Each object stores duplicate data.
Solution With Flyweight
flowchart TD
A[Shared Tree Object]
B[Position 1]
C[Position 2]
D[Position 3]
E[Position 100000]
B --> A
C --> A
D --> A
E --> A
Common data is shared.
Key Idea
Separate state into:
Intrinsic State
Extrinsic State
Intrinsic State
Shared data.
Stored inside Flyweight.
Examples:
Color
Texture
Shape
Font
Character
Never changes.
Extrinsic State
External data.
Passed from client.
Examples:
X Coordinate
Y Coordinate
Size
Position
Changes per object.
Tree Example
Intrinsic State:
Tree Type
Green Color
Oak Texture
Extrinsic State:
X=100
Y=200
Flyweight Architecture
flowchart LR
Client --> FlyweightFactory
FlyweightFactory --> SharedFlyweight
Client --> ExtrinsicState
Components
Flyweight
Shared object.
Concrete Flyweight
Stores intrinsic state.
Flyweight Factory
Creates and reuses objects.
Client
Provides extrinsic state.
UML Diagram
classDiagram
class Flyweight {
+display(x,y)
}
class ConcreteFlyweight
class FlyweightFactory
class Client
Flyweight <|-- ConcreteFlyweight
FlyweightFactory --> ConcreteFlyweight
Client --> FlyweightFactory
Gaming Example
Suppose game has:
100000 Trees
Without Flyweight:
100000 Objects
With Flyweight:
1 Tree Type Object
100000 Locations
Step 1: Flyweight Interface
public interface Tree {
void display(
int x,
int y);
}
Step 2: Concrete Flyweight
public class OakTree
implements Tree {
private final String color;
private final String texture;
public OakTree() {
this.color = "Green";
this.texture = "Oak";
}
@Override
public void display(
int x,
int y) {
System.out.println(
"Tree at "
+ x
+ ","
+ y);
}
}
Step 3: Flyweight Factory
import java.util.HashMap;
import java.util.Map;
public class TreeFactory {
private static final Map<
String,
Tree> cache =
new HashMap<>();
public static Tree getTree(
String type) {
if (!cache.containsKey(type)) {
cache.put(
type,
new OakTree());
}
return cache.get(type);
}
}
Step 4: Client Code
public class FlyweightDemo {
public static void main(
String[] args) {
for (int i = 0;
i < 5;
i++) {
Tree tree =
TreeFactory.getTree(
"OAK");
tree.display(
i * 10,
i * 20);
}
}
}
Output
Tree at 0,0
Tree at 10,20
Tree at 20,40
Tree at 30,60
Tree at 40,80
Only one Tree object exists.
Execution Flow
sequenceDiagram
Client->>Factory:getTree("OAK")
Factory->>Cache:Check Existing
Cache-->>Factory:Return Object
Factory-->>Client:Shared Tree
Client->>Tree:display(x,y)
Memory Comparison
Without Flyweight:
100000 Trees
×
1 MB
=
100 GB
With Flyweight:
1 Shared Tree
+
Coordinates
≈ Few MB
Huge savings.
JVM Example
Java String Pool is a Flyweight Pattern.
Example:
String s1 = "JAVA";
String s2 = "JAVA";
Memory:
One String Object
Shared by both references.
String Pool Diagram
flowchart TD
A[s1]
B[s2]
A --> C["JAVA"]
B --> C
Integer Cache Example
Integer a = 100;
Integer b = 100;
JVM reuses cached objects.
Flyweight in action.
Database Connection Pool
Connections are expensive.
Instead of:
New Connection Per Request
Use:
Shared Connection Pool
Similar concept.
Logging Framework Example
Loggers are often reused.
Logger logger =
LoggerFactory
.getLogger(
MyClass.class);
Shared instances reduce memory.
Enterprise Examples
Banking
Currency objects:
USD
EUR
INR
Shared across transactions.
Insurance
Policy templates.
Shared by millions of customers.
Gaming
Trees
Cars
Buildings
Characters
Shared models.
Text Editors
Characters:
A
B
C
Shared fonts and styles.
Benefits
✅ Significant Memory Reduction
✅ Better Performance
✅ Faster Object Creation
✅ Reuse Existing Objects
✅ Improved Scalability
Limitations
❌ Increased Complexity
❌ Difficult State Management
❌ Extrinsic State Must Be Managed Carefully
❌ Debugging Can Be Harder
When To Use
Use Flyweight when:
- Large number of similar objects exist
- Memory is a concern
- Object creation is expensive
- Shared state is possible
When Not To Use
Avoid Flyweight when:
- Object count is small
- Memory is not an issue
- Shared state does not exist
Flyweight vs Singleton
| Feature | Flyweight | Singleton |
|---|---|---|
| Instances | Many Shared Objects | One Object |
| Purpose | Save Memory | Global Access |
| Scope | Object Pool | Single Instance |
Flyweight vs Prototype
| Feature | Flyweight | Prototype |
|---|---|---|
| Goal | Reuse Objects | Clone Objects |
| Memory | Shared | New Copies |
| Focus | Optimization | Object Creation |
Real Enterprise Architecture
flowchart LR
Client
--> FlyweightFactory
FlyweightFactory
--> SharedObjects
SharedObjects
--> MemoryOptimization
Interview Questions
What is Flyweight Pattern?
A structural design pattern used to reduce memory usage by sharing common object state.
What Problem Does It Solve?
Memory consumption caused by large numbers of similar objects.
What is Intrinsic State?
Shared state stored inside Flyweight objects.
What is Extrinsic State?
External state provided by the client.
Real Java Example?
String Pool.
Real Enterprise Example?
Database Connection Pooling.
Difference Between Flyweight and Singleton?
Flyweight manages many shared objects.
Singleton manages one object.
Key Takeaways
- Flyweight is a Structural Design Pattern.
- Reduces memory usage through object sharing.
- Separates Intrinsic and Extrinsic State.
- Widely used in JVM internals.
- String Pool is the most common Java example.
- Excellent for gaming, caching, pooling, and large-scale systems.
- Improves performance and scalability significantly.