Sitemap

Flyweight design pattern

3 min readFeb 19, 2026

--

Flyweight design pattern is a memory optimization technique for creating a large number of similar objects, reducing memory usage by sharing common data (intrinsic state) among them, while keeping unique data (extrinsic state) separate. It works by extracting shared, immutable properties into a reusable “flyweight” object, often managed by a factory, and passing the context-specific, unique data to the client when needed, ideal for scenarios like text editors (character styles) or game engines (tree types) with many similar entities

Press enter or click to view image in full size

Key Concepts

  • Intrinsic State: Data that is shared, constant, and independent of the object’s context (e.g., font, color, character code).
  • Extrinsic State: Data that is unique to each object instance and context-dependent (e.g., position on screen, quantity).
  • Flyweight: The shared intrinsic state object, managed by a factory.
  • Factory: Creates and manages flyweights, returning existing ones if they match, or creating new ones if necessary.

How It Works

  1. Identify Shared Data: Determine which properties of your objects are identical across many instances (e.g., the actual font definition for a character).
  2. Separate States: Split the object’s data into intrinsic (shared) and extrinsic (unique) parts.
  3. Create Flyweights: The factory creates a single instance (or a pool) of the intrinsic state (the flyweight).
  4. Client Uses Flyweight: When the client needs an object, it requests the flyweight from the factory and provides the extrinsic (unique) state, which is then used in conjunction with the shared flyweight to perform operations.

Get Kaizen Chandra’s stories in your inbox

Join Medium for free to get updates from this writer.

Example Use Cases

  • Text Editors: Sharing font/style data for many characters.
  • Games: Sharing tree or texture data for thousands of similar trees in a forest.
  • Financial Apps: Caching currency exchange rates.

Benefits

  • Memory Savings: Significantly reduces memory footprint by avoiding redundant data storage.
  • Improved Performance: Faster application startup and operation due to less memory pressure.

Drawbacks

  • Increased Complexity: Adds layers of indirection (factory, state separation).
  • Potential Over-Optimization: Only useful when memory is a significant constraint due to a massive number of objects.
interface Tree {
void display(int x, int y); // extrinsic state
}

class TreeType implements Tree {

private String name; // intrinsic
private String color; // intrinsic

public TreeType(String name, String color) {
this.name = name;
this.color = color;
}

@Override
public void display(int x, int y) {
System.out.println("Drawing " + name + " tree of color "
+ color + " at position (" + x + ", " + y + ")");
}
}

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

class TreeFactory {

private static final Map<String, TreeType> treeTypes = new HashMap<>();

public static TreeType getTreeType(String name, String color) {

String key = name + "-" + color;

if (!treeTypes.containsKey(key)) {
System.out.println("Creating new TreeType: " + key);
treeTypes.put(key, new TreeType(name, color));
}

return treeTypes.get(key);
}
}


public class FlyweightDemo {

public static void main(String[] args) {

TreeType oak1 = TreeFactory.getTreeType("Oak", "Green");
oak1.display(10, 20);

TreeType oak2 = TreeFactory.getTreeType("Oak", "Green");
oak2.display(30, 40);

TreeType pine = TreeFactory.getTreeType("Pine", "Dark Green");
pine.display(50, 60);
}
}

--

--