Flyweight Design Pattern in Java
This article explains Flyweight design pattern in java with UML class diagram. It then takes an example scenario in java and explains it with class diagram and code.
Introduction Flyweight Design Pattern is a structural design pattern among the Gang Of Four(GOF) Design PatternsClick to read: Gang Of Four(GOF) Design Patterns. Being a structural design pattern, the Flyweight pattern deals with how objects are composed - here, by sharing one object among many others to save memory. What is Flyweight Design Pattern The Flyweight design pattern uses sharing to support large numbers of fine-grained objects efficiently. When an application needs a very large number of similar objects - characters in a document, trees in a game world, cells in a spreadsheet - creating each one with all its data can use an enormous amount of memory. The Flyweight pattern splits an object's state in two -
Class Diagram for Flyweight Design Pattern
Explanation of Flyweight Design Pattern's Class Diagram
The example plants a forest of a million trees, as a game or a map renderer might. Each tree has a position, but there are only a few kinds of tree, and each kind's name, colour and texture are the same for all trees of that kind.
Code for the classes shown in Java Example's Class Diagram
OUTPUT on running Forest.java
Explanation of Java Example's Class Diagram & Code
Summary
In the above tutorial we understood what is Flyweight design pattern, the difference between intrinsic and extrinsic state, and the main scenarios in which it is applicable. We then looked at the UML class diagram for Flyweight Design Pattern & its explanation, a Java use case which planted a million trees using three shared tree types, with its class diagram, code and output, followed by an explanation of both the class diagram & code. This concludes the tutorial on Flyweight design pattern.
Introduction Flyweight Design Pattern is a structural design pattern among the Gang Of Four(GOF) Design PatternsClick to read: Gang Of Four(GOF) Design Patterns. Being a structural design pattern, the Flyweight pattern deals with how objects are composed - here, by sharing one object among many others to save memory. What is Flyweight Design Pattern The Flyweight design pattern uses sharing to support large numbers of fine-grained objects efficiently. When an application needs a very large number of similar objects - characters in a document, trees in a game world, cells in a spreadsheet - creating each one with all its data can use an enormous amount of memory. The Flyweight pattern splits an object's state in two -
- Intrinsic state - data which is the same for many objects and does not depend on context, such as a tree's species, colour and texture. It is stored once, in a shared flyweight object, which must be immutable.
- Extrinsic state - data which is different for each object, such as a tree's position. It is stored outside the flyweight, or passed to it when it is used.
- A very large number of objects: The application uses so many objects that storing all their data separately is costly in memory.
- Most of the state can be made extrinsic: Most of an object's data is shared with many other objects, and the part which is unique can be kept outside it or computed when needed.
- Object identity does not matter: The application does not depend on each object being a distinct instance, since many logical objects will share one flyweight.
Flyweightis the interface through which flyweights receive their extrinsic state, as a parameter ofoperation(extrinsicState).ConcreteFlyweightstores only intrinsic state, and is shared. It must be immutable, since many clients use the same instance.UnsharedConcreteFlyweightis an optional class which implements the interface but is not shared - for objects whose state is all unique.FlyweightFactorykeeps a pool of flyweights.getFlyweight(key)returns an existing flyweight for the key, or creates, stores and returns a new one.Clientobtains flyweights only from the factory, and keeps or computes the extrinsic state, passing it in when it uses a flyweight.
TreeType.java - the flyweight (intrinsic state)
//TreeType.java
public final class TreeType {
private final String name;
private final String color;
private final String texture; // imagine a large texture image here
TreeType(String name, String color, String texture) {
this.name = name;
this.color = color;
this.texture = texture;
}
String draw(int x, int y) { // extrinsic state passed in
return name + " (" + color + ") at (" + x + ", " + y + ")";
}
}
TreeTypeFactory.java - the flyweight factory
//TreeTypeFactory.java
import java.util.HashMap;
import java.util.Map;
public class TreeTypeFactory {
private static final Map<String, TreeType> types = new HashMap<>();
static TreeType getTreeType(String name, String color, String texture) {
String key = name + "|" + color + "|" + texture;
return types.computeIfAbsent(key, k -> new TreeType(name, color, texture));
}
static int typesCreated() { return types.size(); }
}
Tree.java - one tree: extrinsic state plus a shared TreeType
//Tree.java
public class Tree {
private final int x;
private final int y;
private final TreeType type; // shared, not copied
Tree(int x, int y, TreeType type) {
this.x = x;
this.y = y;
this.type = type;
}
String draw() { return type.draw(x, y); }
TreeType type() { return type; }
}
Forest.java (with the main() method)
//Forest.java
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Random;
public class Forest {
private final List<Tree> trees = new ArrayList<>();
void plantTree(int x, int y, String name, String color, String texture) {
trees.add(new Tree(x, y, TreeTypeFactory.getTreeType(name, color, texture)));
}
public static void main(String[] args) {
String[][] kinds = {{"Oak", "green", "oak.png"}, {"Pine", "dark green", "pine.png"}, {"Birch", "white", "birch.png"}};
Forest forest = new Forest();
Random random = new Random(42);
for (int i = 0; i < 1_000_000; i++) {
String[] k = kinds[random.nextInt(kinds.length)];
forest.plantTree(random.nextInt(10_000), random.nextInt(10_000), k[0], k[1], k[2]);
}
System.out.println("Trees planted : " + forest.trees.size());
System.out.println("TreeType objects : " + TreeTypeFactory.typesCreated());
IdentityHashMap<TreeType, Boolean> distinct = new IdentityHashMap<>();
forest.trees.forEach(t -> distinct.put(t.type(), true));
System.out.println("Distinct TreeTypes referenced by trees: " + distinct.size());
System.out.println("First tree : " + forest.trees.get(0).draw());
}
}
Trees planted : 1000000 TreeType objects : 3 Distinct TreeTypes referenced by trees: 3 First tree : Birch (white) at (2763, 1248)
TreeTypeis the flyweight. It holds the intrinsic state - name, colour and texture - and is immutable, so one instance can safely be shared by any number of trees.TreeTypeFactoryis the flyweight factory.computeIfAbsent()creates aTreeTypeonly the first time a combination is requested, and returns the cached one afterwards.Treeholds only the extrinsic state - its position - plus a reference to its sharedTreeType, which it passes its position to when drawn.Forest, the client, planted a million trees, but only 3TreeTypeobjects exist, and every tree references one of them. If each tree held its own copy of the type data - and a real texture is many kilobytes - memory use would grow a million-fold for that data instead of staying constant.
Integer.valueOf() returns shared, cached objects for values from -128 to 127 (and similarly for Long, Short, Byte and Character), Boolean.valueOf() returns one of two shared objects, and string literals are shared through the string poolClick to read: string pool.
Gang of Four (GOF) Design Patterns on JavaBrahman
Creational Patterns: Abstract Factory PatternAbstract Factory Design Pattern in Java Builder PatternBuilder Design Pattern in Java Factory Method PatternFactory Method Design Pattern in Java Prototype PatternPrototype Design Pattern in Java Singleton PatternSingleton Design Pattern in Java
Structural Patterns: Adapter PatternAdapter Design Pattern in Java Bridge PatternBridge Design Pattern in Java Composite PatternComposite Design Pattern in Java Decorator PatternDecorator Design Pattern in Java Facade PatternFacade Design Pattern in Java Flyweight PatternFlyweight Design Pattern in Java Proxy PatternProxy Design Pattern in Java
Behavioral Patterns: Chain of Responsibility PatternChain of Responsibility Design Pattern in Java Command PatternCommand Design Pattern in Java Interpreter PatternInterpreter Design Pattern in Java Iterator PatternIterator Design Pattern in Java Mediator PatternMediator Design Pattern in Java Memento PatternMemento Design Pattern in Java Observer PatternObserver Design Pattern in Java State PatternState Design Pattern in Java Strategy PatternStrategy Design Pattern in Java Template Method PatternTemplate Method Design Pattern in Java Visitor PatternVisitor Design Pattern in Java
Analysis of Patterns: Strategy vs State PatternStrategy Design Pattern versus State Design Pattern GOF Patterns OverviewGOF / Gang of Four Design Patterns in Java
Creational Patterns: Abstract Factory PatternAbstract Factory Design Pattern in Java Builder PatternBuilder Design Pattern in Java Factory Method PatternFactory Method Design Pattern in Java Prototype PatternPrototype Design Pattern in Java Singleton PatternSingleton Design Pattern in Java
Structural Patterns: Adapter PatternAdapter Design Pattern in Java Bridge PatternBridge Design Pattern in Java Composite PatternComposite Design Pattern in Java Decorator PatternDecorator Design Pattern in Java Facade PatternFacade Design Pattern in Java Flyweight PatternFlyweight Design Pattern in Java Proxy PatternProxy Design Pattern in Java
Behavioral Patterns: Chain of Responsibility PatternChain of Responsibility Design Pattern in Java Command PatternCommand Design Pattern in Java Interpreter PatternInterpreter Design Pattern in Java Iterator PatternIterator Design Pattern in Java Mediator PatternMediator Design Pattern in Java Memento PatternMemento Design Pattern in Java Observer PatternObserver Design Pattern in Java State PatternState Design Pattern in Java Strategy PatternStrategy Design Pattern in Java Template Method PatternTemplate Method Design Pattern in Java Visitor PatternVisitor Design Pattern in Java
Analysis of Patterns: Strategy vs State PatternStrategy Design Pattern versus State Design Pattern GOF Patterns OverviewGOF / Gang of Four Design Patterns in Java