Thursday, 28 November 2013

Flyweight Design pattern - Implementation

Master Software Design Patterns!

Subscribe to Ram N Java for clean code, architecture patterns, and practical Java tutorials!

SUBSCRIBE NOW

Why Use the Flyweight Design Pattern?

Imagine your application needs to render hundreds of thousands of graphical elements (like circles with various colors). If you instantiate a brand-new object using the new operator for each circle, your application will quickly consume massive amounts of heap memory and slow down.

The Flyweight Pattern is a structural design pattern that solves this problem by sharing common object instances instead of creating duplicate objects. By reusing existing instances, memory consumption drops drastically and overall application performance improves.

Understanding Intrinsic vs Extrinsic State

To successfully implement the Flyweight pattern, divide the object's data into two distinct states:

  • Intrinsic State: Data that is constant, shared across instances, and stored inside the object memory (e.g., the underlying shape definition).
  • Extrinsic State: Data that varies and depends on external context (e.g., color, coordinates, or runtime properties). This data is passed into methods or modified on the fly rather than storing separate objects.

Core Implementation in Java

The Flyweight factory maintains a lookup map (cache) of reusable objects. When a shape is requested, it checks the map first before creating a new instance.

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

// 1. Common Interface
interface Shape {
    void draw();
}

// 2. Concrete Flyweight Class
class Circle implements Shape {
    private String color;
    private int x, y, radius;

    public void setColor(String color) {
        this.color = color;
    }

    public void setX(int x) { this.x = x; }
    public void setY(int y) { this.y = y; }
    public void setRadius(int radius) { this.radius = radius; }

    @Override
    public void draw() {
        System.out.println("Drawing Circle [Color: " + color + 
                           ", X: " + x + ", Y: " + y + 
                           ", Radius: " + radius + 
                           ", HashCode: " + System.identityHashCode(this) + "]");
    }
}

// 3. Flyweight Factory
class ShapeFactory {
    private static final Map<String, Shape> shapeMap = new HashMap<>();

    public static Shape getShape(String shapeType) {
        Shape shape = shapeMap.get(shapeType);

        if (shape == null) {
            if ("CIRCLE".equalsIgnoreCase(shapeType)) {
                shape = new Circle();
                shapeMap.put(shapeType, shape);
                System.out.println("Created new Circle object in memory.");
            }
        }
        return shape;
    }
}

// 4. Demo / Client
public class FlyweightPatternDemo {
    private static final String[] COLORS = { "Red", "Green", "Blue", "Orange", "Black" };

    public static void main(String[] args) {
        for (String color : COLORS) {
            for (int i = 0; i < 2; i++) {
                Circle circle = (Circle) ShapeFactory.getShape("CIRCLE");
                circle.setColor(color);
                circle.setX(i * 10);
                circle.setY(i * 20);
                circle.setRadius(15);
                circle.draw();
            }
        }
    }
}

Watch More Related Design Pattern Tutorials


Click here to watch in Youtube : https://www.youtube.com/watch?v=SKZQx1DdA9U

Click the below Image to Enlarge
Flyweight Design pattern - Implementation

Flyweight Design pattern - Class Diagram



Shape.java

public interface Shape
{
void draw();
}

Circle.java

public class Circle implements Shape
{
private String    color;
private final int x      = 10;
private final int y      = 20;
private final int radius = 30;

public Circle()
{
}

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

public String getColor()
{
return color;
}

public void setColor( String color )
{
this.color = color;
}

@Override
public void draw()
{
System.out.println(this+" : Circle: Draw() [Color : " + color + ", x : " + x + ", y :" + y + ", radius :"
               + radius);
}
}

ShapeFactory.java

import java.util.HashMap;

public class ShapeFactory
{
private static final HashMap<String, Shape> shapeMap = new HashMap<String, Shape>();

public static Shape getShape( String shapeType )
{
Shape shape=null;
if( shapeType.equalsIgnoreCase("circle") )
{
shape = (Circle) shapeMap.get("circle");

if( shape == null )
{
shape = new Circle();
shapeMap.put("circle", shape);
System.out.println("Creating circle object with out any color in shapefactory : " + shape
               + "\n");
}
}
return shape;
}
}

FlyweightPatternDemo.java

public class FlyweightPatternDemo
{
private static final String colors[] = { "Red", "Green", "Blue", "Orange", "Black" };

public static void main( String[] args )
{

System.out.println("\n################ Red color Circles ####################");
for( int i = 0; i < 10; ++i )
{
Circle circle = (Circle) ShapeFactory.getShape("circle");
circle.setColor(colors[0]);
circle.draw();
}
System.out.println("\n############### Green color Circles ####################");
for( int i = 0; i < 10; ++i )
{
Circle circle = (Circle) ShapeFactory.getShape("circle");
circle.setColor(colors[1]);
circle.draw();
}
System.out.println("\n################ Blue color Circles ####################");
for( int i = 0; i < 10; ++i )
{
Circle circle = (Circle) ShapeFactory.getShape("circle");
circle.setColor(colors[2]);
circle.draw();
}
System.out.println("\n################ Orange color Circles ####################");
for( int i = 0; i < 10; ++i )
{
Circle circle = (Circle) ShapeFactory.getShape("circle");
circle.setColor(colors[3]);
circle.draw();
}
System.out.println("\n################ Black color Circles ####################");
for( int i = 0; i < 10; ++i )
{
Circle circle = (Circle) ShapeFactory.getShape("circle");
circle.setColor(colors[4]);
circle.draw();
}
}
}

Output

################ Red color Circles ####################
Creating circle object with out any color in shapefactory : Circle@10385c1

Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30

############### Green color Circles ####################
Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30

################ Blue color Circles ####################
Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30

################ Orange color Circles ####################
Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30

################ Black color Circles ####################
Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30

See also:

  • Flyweight Design pattern - Introduction
  • Flyweight Design pattern - Real Time Example
  • Flyweight Design pattern - Class Diagram
  • Flyweight Design pattern - Sequence Diagram
  • Flyweight Design pattern - Key Points
  • All Design Patterns Links
  • No comments:

    Post a Comment

    Tutorials