How to implement Flyweight pattern in Java?

Photo by Ellie Burgin on Pexels.com

Let’s say you are an artist.

You want to create different Color Palettes using three colors at a time.

The three colors can be anything of all colors know to us.

Let’s represent this in Java code using Flyweight pattern and check what problems it solves.

Flyweight pattern let’s you reuse objects instead of creating a new one every time, particularly when the objects are used in a large number of places.

Here is the client code for creating color palettes for you :

package structural.flyweight.pattern;

public class Client {

	public static void main(String a[]) {

		ColorFactory colorFactory = new ColorFactory();
		
		Color blueColor = colorFactory.getColor("blue");

		Color greenColor = colorFactory.getColor("green");

		Color purpleColor = colorFactory.getColor("purple");
		
		
		createPalette(blueColor,greenColor,purpleColor);
		

		Color blueColor2 = colorFactory.getColor("blue");
		
		Color yellowColor = colorFactory.getColor("yellow");
		
		Color purpleColor2  = colorFactory.getColor("purple");
		
		createPalette(blueColor2, yellowColor, purpleColor2);
		
		

		colorFactory.printAllColors();
		
		
	}

	private static void createPalette(Color color1, Color color2, Color color3) {

		
		System.out.println("Preparing a new palette using the colors: ");
		System.out.println(color1+"-"+color2+"-"+color3);
	}

}

I have created two palettes in the above client code.

For the first palette I have used the colors blue , green and purple.

For the second palette I have used the colors blue, yellow and purple.

Blue and Purple colors have been used twice.

Imagine you want to create hundreds of palettes using three colors. It will be expensive to create a Color object each time. Instead you can reuse existing Color objects.

These can be stored internally (in a map for instance) and then can be reused.

Here is the ‘Factory’ class handling the reuse mechanism:

package structural.flyweight.pattern;

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

public class ColorFactory {

	Map<String, Color> colorMap = new HashMap<String, Color>();

	public Color getColor(String name) {

		if (colorMap.get(name) != null) {

			System.out.println("Returning existing Color object for the color: "+name);

			return colorMap.get(name);
		} else {

			System.out.println("Creating new Color object for the color :"+name);

			Color color = new Color(name);
			colorMap.put(name, color);
			return color;
		}

	}
	
	
	public void printAllColors() {
		
		
		System.out.println("List of all colors in system");
		for(String key:colorMap.keySet()) {
			
			System.out.println(colorMap.get(key));
		}
	}

}

Every time a color is looked up , it is checked if it exists in a map . If yes it is returned else a new Color object is created , stored in the map and then returned.

Here is the Color model class:

package structural.flyweight.pattern;

public class Color {

	String name;
	
	
	public Color(String name) {
		
		this.name = name;
	}


	@Override
	public String toString() {
		return "Color [name=" + name + "]";
	}
	
	
}

Here is the output of the client code:

Creating new Color object for the color :blue
Creating new Color object for the color :green
Creating new Color object for the color :purple
Preparing a new palette using the colors: 
Color [name=blue]-Color [name=green]-Color [name=purple]
Returning existing Color object for the color: blue
Creating new Color object for the color :yellow
Returning existing Color object for the color: purple
Preparing a new palette using the colors: 
Color [name=blue]-Color [name=yellow]-Color [name=purple]
List of all colors in system
Color [name=green]
Color [name=blue]
Color [name=yellow]
Color [name=purple]

Quoting the Gang of Four:

Use sharing to support large numbers of fine grained objects efficiently

And they suggest to use it when :

– An application uses a large number of objects (in our case we use a large number of Color objects)

– Storage costs are high because of the sheer quantity of objects ( If there are a hundred palettes we will end up creating three hundred Color objects)

– Most object state can be made extrinsic.

[Here the Gang of Four refers to extrinsic and intrinsic properties of an object. Extrinsic properties are dependent on context , they change easily . In the case of a Color object , ‘the quantity of a color’ is an extrinsic property. If we were to define the quantity also inside the Color class we cannot reuse the object. Intrinsic state refers to the internal property of an object which will not change with context. Blue Color object will always be blue in color no matter where it is used in the application. Thus the property ‘quantity’ can be moved out of the Color class in our case]

– Many groups of objects can be replaced by relatively few shared objects once extrinsic state is removed ( If we remove the property ‘quantity’ the Color object becomes reusable across different palettes)

– The application doesn’t depend on object identity. Since flyweight objects may be shared , identity tests will return true for conceptually distinct objects ( If we create a Blue Color object for one palette and use it in another palette both will represent the same identity though they are used in two different places. And this is fine in our case , we don’t care about the identity of the Color object)

Here is the code :

https://github.com/vijaysrj/designPatternsGoF/tree/master/src/structural/flyweight/pattern


Posted

in

,

by

Comments

Leave a Reply

Discover more from The Full Stack Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading