Flyweight Pattern
Flyweight is a class in boxing which includes fighters weighing up to and including 51 kg (112 lb) for a title fight.
The What
The Flyweight pattern is a structural design pattern aimed at reducing the memory footprint of programs by sharing common parts of the state among multiple objects. This is achieved by storing shared (intrinsic) state within a flyweight object and passing the unique (extrinsic) state to methods. This pattern is especially useful in scenarios where an application needs to manage a large number of similar objects that consume a significant amount of memory.
The General Problem It Tries to?Solve
The primary issue the Flyweight pattern addresses is the excessive memory consumption caused by the instantiation of numerous similar objects. In many applications, objects often contain a lot of redundant data that can be shared. By sharing these common parts, the memory usage can be significantly reduced.
Example of the General?Problem
Consider a text editor that needs to display thousands of characters on the screen. Each character object typically contains attributes such as the character itself, font type, font size, color, position on the screen, etc. If each character object stores all of this data, the memory usage can become substantial.
Generalizing The?When
The Flyweight pattern is beneficial when:
The How
To implement the Flyweight pattern, follow these steps using the example of a text editor:
领英推荐
Step 1: Divide the class fields into intrinsic and extrinsic states. And define the Flyweight class. Keep the intrinsic state immutable within the flyweight class.
// The Flyweight class containing the intrinsic state
public class CharacterFlyweight {
private final char character;
private final String font;
private final int size;
private final String color;
public CharacterFlyweight(char character, String font, int size, String color) {
this.character = character;
this.font = font;
this.size = size;
this.color = color;
}
public void display(int x, int y) {
// The extrinsic state (x, y coordinates) is passed as parameters
System.out.println("Displaying character " + character + " at (" + x + ", " + y + ") in font " + font + " size " + size + " color " + color);
}
}
Step 2: Create a factory to manage and share flyweight objects.
import java.util.HashMap;
import java.util.Map;
public class CharacterFlyweightFactory {
private static final Map<String, CharacterFlyweight> flyweightPool = new HashMap<>();
public static CharacterFlyweight getFlyweight(char character, String font, int size, String color) {
String key = character + font + size + color;
if (!flyweightPool.containsKey(key)) {
flyweightPool.put(key, new CharacterFlyweight(character, font, size, color));
}
return flyweightPool.get(key);
}
}
Step 3: Store or compute the extrinsic state outside the flyweight class. Use this in the client
public class TextEditor {
public static void main(String[] args) {
CharacterFlyweight characterA1 = CharacterFlyweightFactory.getFlyweight('A', "Arial", 12, "black");
CharacterFlyweight characterA2 = CharacterFlyweightFactory.getFlyweight('A', "Arial", 12, "black");
characterA1.display(10, 10);
characterA2.display(20, 20);
// Since both characterA1 and characterA2 share the same intrinsic state, they are the same instance
System.out.println(characterA1 == characterA2); // Output: true
}
}
Pros:
Cons:
Conclusion
The Flyweight pattern is a powerful tool for optimizing memory usage in applications that need to manage a large number of similar objects. By sharing common states, it significantly reduces memory consumption. However, this comes at the cost of increased code complexity and potential CPU overhead. The example of a text editor clearly illustrates how to implement the Flyweight pattern and the benefits it brings. Use this pattern judiciously when memory optimization is a priority and the benefits outweigh the complexity introduced.
Thank you