Fly weight pattern is a type of structural design pattern.
Let me explain it with an example that might be familiar to everyone. Imagine that there are some trees in the area. Every tree has its name, color, texture, and position. The position of a tree is indicated by horizontal and vertical coordinates, namely x coordinate and y coordinate.
The positions of any two trees among them are not the same.
To better illustrate how to abstract the problem using flyweight pattern, or to facilitate a macroscopic understanding of the solution to this problem, we need to create a total of three classes.
They are TreeType, TreeTypeFactory, Tree, respectively.
TreeType:
For a tree type, we can define it using three elements: type name, color and texture.
Since the name property is defined in the TreeType class rather than in the Tree class, this property naturally represents the name of a tree type rather than the name of a single tree.
The name property serves as the unique identifier for objects of the TreeType class.
public class TreeType {
private String name;
private String color;
private String texture;
public TreeType(String name, String color, String texture) {
this.name = name;
this.color = color;
this.texture = texture;
}
public String getName() {
return name;
}
public String getColor() {
return color;
}
public String getTexture() {
return texture;
}
}
TreeTypeFactory
The TreeTypeFactory class has only one variable named treeTypeMap.
The treeTypeMap is a static and final variable, its type is Map.
The key type of the Map is String type, denoting the name of a tree type. And value type is TreeType, representing the actual instance of the corresponding tree type.
Additionally, the TreeTypeFactory class also has only one function.
If the treeTypeMap already contains the treeType according to the name, return the treeType. Otherwise, initialize a new TreeType instance according to the three parameters, and then store it into the treeTypeMap; eventually, return it.
public class TreeTypeFactory {
private static final Map<String, TreeType> treeTypeMap = new HashMap<>();
public static TreeType getTreeType(String name, String color, String texture) {
TreeType result = treeTypeMap.get(name);
if (result == null) {
result = new TreeType(name, color, texture);
treeTypeMap.put(name, result);
}
return result;
}
}
Tree
There is at most only one tree at any given position.
In other words, any two or more trees cannot exist in the exact same position.
Here we use the x-coordinate and y-coordinate to describe a position.
Therefore, property x and property y jointly constitute the unique identifier of a Tree object.
Besides, we define the draw method to simulate a business process.
public class Tree {
private int x;
private int y;
private TreeType type;
public Tree(int x, int y, TreeType type) {
this.x = x;
this.y = y;
this.type = type;
}
public TreeType getTreeType() {
return this.type;
}
/**
* Draw the tree
*/
public void draw() {
String name = type.getName();
String color = type.getColor();
String texture = type.getTexture();
System.out.printf(
"Drawing a %s tree at (%d, %d) with color %s and texture %s%n",
name, x, y, color, texture
);
}
}
Flyweight Pattern Demo
In the test method, we try to get a TreeType object named "Oak" and another named "Pine" at first.
Certainly, both of these program statements will create a new TreeType object, respectively.
Next, among the three Tree objects that we have created, tree1 and tree3 share the oakType.
This is permitted because the TreeType property is not a unique identifier of a Tree object.
So this means that, by using flyweight pattern, we can reuse the common parts to simplify the program.
@Test
public void testFlyweight() {
TreeType oakType = TreeTypeFactory.getTreeType("Oak", "Green", "Rough");
TreeType pineType = TreeTypeFactory.getTreeType("Pine", "Dark Green", "Smooth");
Tree tree1 = new Tree(10, 20, oakType);
Tree tree2 = new Tree(30, 40, pineType);
Tree tree3 = new Tree(50, 60, oakType);
tree1.draw();
tree2.draw();
tree3.draw();
// Verify that the same TreeType object is reused
System.out.println("Are tree1 and tree3 using the same TreeType object? " + (tree1.getTreeType() == tree3.getTreeType()));
}
Conclusion
The Flyweight pattern is suitable to handle large-scale systems with many objects.
It separates shared and unique data, making the system easier to maintain.
Flyweight objects are reusable across multiple contexts, which reduces unnecessary duplication.
Top comments (0)