The Flyweight pattern in Java

Introduction to the Flyweight Pattern

Design pattern in a simple meaning, is a way to design reusable object-oriented code. We can think of ways to design our classes, interfaces, enums and their members so that the code is reusable but flexible.

There are 23 most important design patterns, pioneered by the book Design Patterns: Elements of Reusable Object-Oriented Software, written by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides or Gang of Four for short. We will cover these design pattern one by one.

The Flyweight pattern uses sharing to support a large number of fine-grained objects efficiently. In short, objects are cached and reused. The Flyweight will try to reuse the existing objects and only creates a new object when no matching object is found.

In Java, there are two notes we should consider:

– Though not stated explicitly, it does make sense to define those shared objects as immutable/stateless.

– As shared objects are ineligible for garbage collection, the implementation of this pattern may prove to be unfriendly to Java auto garbage collection.

Implementation of Flyweight Pattern in Java

We will create a very simple implementation of the Flyweight. Say we have a Bike class with only name variable:

public class Bike {
  private final String name;
  public Bike(String name) {
    this.name = name;
  }
  public String getName() {
    return name;
  }
}

Now suppose that the name of each Bike object is unique, we will create a HashMap and store every Bike object created into this HashMap with the key as the name and the value as the Bike object. Now, whenever a new Bike object is created, the Flyweight Factory will check if there is a key in the map. If there is, then the object in the map will be returned. If not, then we create a new Bike object, put it to the HashMap, and return this new object:

import java.util.HashMap;
public class BikeFlyWeight {
  private static final HashMap<String, Bike> map =
      new HashMap<>();
  public static Bike getBike(String name){
    Bike bike = map.get(name);
    if (bike == null){
      bike = new Bike(name);
      map.put(name, bike);
    }
    return bike;
  }
}

And in Test.java:

public class Test {
  public static void main(String[] args){
    Bike bike1 = BikeFlyWeight.getBike("Giant");
    Bike bike2 = BikeFlyWeight.getBike("Giant");
    System.out.print("Check if bike1 and bike" +
        "2 are the same object: "
        + (bike1 == bike2));
  }
}

The output will be:

Check if bike1 and bike2 are the same object: true

Leave a Reply