Java Omnibus
OOAD & Architecture / GoF patterns / Structural / Flyweight Pattern in Java
GoF Structural Java Order Management
GoF Pattern

Flyweight only becomes compelling when there are many fine-grained objects and shared state can be separated safely.

Use sharing to support large numbers of fine-grained objects efficiently.

Intent

What the pattern is trying to do

Use sharing to support large numbers of fine-grained objects efficiently.

Problem

What force creates the need

The system creates many similar small objects, and memory pressure grows because shared state is duplicated repeatedly.

Solution

How the pattern responds

Extract common intrinsic state into shared flyweights and keep varying extrinsic state outside the shared objects.

Structure

How the moving parts fit together

A flyweight factory manages shared instances keyed by intrinsic state, while callers provide extrinsic context at use time.

Java Example

Java example in the Order Management domain

Flyweight Pattern in Java example
package org.javaomnibus.ecommerce.gof.structural;

public record CurrencyDisplayStyle(String symbol, String localeCode) {}

public final class CurrencyDisplayStyleFactory {
    private final java.util.Map cache = new java.util.HashMap<>();

    public CurrencyDisplayStyle forCode(String currencyCode) {
        return cache.computeIfAbsent(currencyCode, code -> switch (code) {
            case "USD" -> new CurrencyDisplayStyle("$", "en-US");
            case "EUR" -> new CurrencyDisplayStyle("EUR", "de-DE");
            default -> new CurrencyDisplayStyle(code, "en-US");
        });
    }
}
Code Walkthrough

Step by step

  1. Shared style metadata is cached by currency code.
  2. Callers reuse intrinsic display state instead of recreating it repeatedly.
  3. Flyweight only helps if the sharing opportunity is real and object counts are high enough to matter.
  4. The separation between intrinsic and extrinsic state is the core design move.
When To Use

Where this pattern helps

  • When very large numbers of similar objects are created
  • When shared immutable state can be separated cleanly from request-specific context
When Not To Use

When a simpler design is better

  • When memory pressure is not actually a problem
  • When state cannot be split safely into shared and external parts
Trade-Offs

What this pattern costs

  • Introduces indirection and state-splitting complexity
  • Can make code harder to understand if applied without real performance pressure
Modern Relevance

How this fits today

Flyweight is less common than Adapter or Facade in everyday Java, but it still matters in rendering systems, large catalogs, parsers, caches, and memory-sensitive workloads.

Common Misuse

Where teams get it wrong

Adding flyweight-style caching to ordinary objects with low creation volume creates complexity long before it creates measurable value.

Related Patterns

Compare with nearby choices


What To Read Next