Understanding Flyweight Design Pattern in Java

The Flyweight Design Pattern is a powerful structural design pattern in Java used to reduce memory usage when dealing with a large number of similar objects. Instead of creating a new object every time, this pattern reuses shared objects, improving performance, memory efficiency, and scalability.

If you work with applications like editors, games, data visualization tools, or map rendering, understanding the Flyweight Pattern is extremely useful.

What is the Flyweight Pattern?

The Flyweight Pattern allows an application to support a large number of fine-grained objects by sharing common data. It splits object state into:

  • Intrinsic State – shared, reusable, constant
  • Extrinsic State – specific to each object and supplied externally

This allows the system to hold fewer objects in memory.

Real-Time Use Cases of Flyweight Pattern

  • Text editors storing repeated characters
  • Game engines rendering millions of objects
  • Map applications with repeated markers
  • Caching system objects
  • Image icon reuse in UI applications

Flyweight Pattern – UML Explanation

  • Flyweight – interface for shared objects
  • ConcreteFlyweight – actual reusable object
  • FlyweightFactory – returns shared objects
  • Client – supplies extrinsic state

Flyweight Pattern – Real-Time Java Example (Drawing Circles)

Imagine a graphics application where you draw thousands of circles. Most circles share the same color, so creating new objects each time wastes memory. Flyweight helps reuse these objects.

Step 1: Flyweight Interface

public interface Shape {
    void draw(int x, int y);
}

Step 2: ConcreteFlyweight (Shared Object)

public class Circle implements Shape {

    private String color;  // intrinsic state

    public Circle(String color) {
        this.color = color;
    }

    @Override
    public void draw(int x, int y) {
        System.out.println("Drawing " + color + " circle at (" + x + "," + y + ")");
    }
}

Step 3: Flyweight Factory

import java.util.HashMap;
import java.util.Map;

public class ShapeFactory {

    private static final Map<String, Shape> circleMap = new HashMap<>();

    public static Shape getCircle(String color) {
        Shape circle = circleMap.get(color);

        if (circle == null) {
            circle = new Circle(color);
            circleMap.put(color, circle);
        }
        return circle;
    }
}

Step 4: Client Code

public class FlyweightDemo {

    public static void main(String[] args) {

        for (int i = 0; i < 5; i++) {
            Shape circle = ShapeFactory.getCircle("Red");
            circle.draw(i, i * 10);
        }

        for (int i = 0; i < 3; i++) {
            Shape circle = ShapeFactory.getCircle("Blue");
            circle.draw(i * 5, i * 5);
        }
    }
}

Expected Output

Drawing Red circle at (0,0)
Drawing Red circle at (1,10)
Drawing Red circle at (2,20)
Drawing Red circle at (3,30)
Drawing Red circle at (4,40)
Drawing Blue circle at (0,0)
Drawing Blue circle at (5,5)
Drawing Blue circle at (10,10)

Notice that only two circle objects (Red and Blue) are created and reused multiple times.

Why Use Flyweight Pattern?

  • Drastically reduces memory usage
  • Improves application performance
  • Ideal for handling millions of similar objects

When Should You Use It?

  • When your application has a large number of similar objects
  • When memory is a concern
  • When object properties can be split into shared and non-shared states

Advantages

  • Reduced memory footprint
  • Better performance
  • Reusable objects improve consistency

Disadvantages

  • Code becomes more complex
  • Extrinsic state must be handled carefully by the client

Conclusion

The Flyweight Design Pattern in Java is essential when working with memory-heavy applications such as games, maps, editors, and UI frameworks. It helps reuse shared objects, boost performance, and reduce memory usage. If you are preparing for interviews or building large-scale applications, mastering this pattern is highly beneficial.

Comments

Popular posts from this blog

Spring Boot on AWS EC2: Upload to S3 Securely Using IAM Role

Java Streams Intermediate Operations Explained with Examples

ConcurrentHashMap vs Synchronized HashMap in Java