Structural Complexity: Medium

Flyweight in Go

Share intrinsic immutable state across many small objects so large collections stay cheaper in memory and easier to manage.

The Problem

Large collections often repeat the same immutable data many times. A cart, a catalog index, or an inventory snapshot might contain thousands of references to the same SKU metadata. If every item owns a full copy, memory usage grows with needless duplication.

The Solution

Flyweight extracts the shared intrinsic state into a reusable object and keeps changing extrinsic state outside of it. In Go, a cache or factory typically owns the shared flyweights, while callers keep their per-instance quantities, locations, or timestamps separately.

Structure

Flyweight Pattern
Step 1 of 5

The Flyweight

ProductMetadata is the shared immutable state: SKU, name, description, image URL, tax class. One instance is shared across every CartLine referencing that SKU.

  • Flyweight: ProductMetadata holds shared immutable SKU data.
  • Flyweight factory: MetadataFactory returns cached flyweights by SKU.
  • Context object: CartLine keeps changing per-line values such as quantity and warehouse.
  • Client: Reuses the same flyweight across multiple contexts.

Implementation

This example shares catalog metadata for repeated SKUs across multiple cart lines. Each line keeps its own quantity and warehouse, while the expensive descriptive fields are reused through a factory-managed cache.

package main

type ProductMetadata struct {
	SKU      string
	Name     string
	Category string
}

Real-World Analogy

Think of a library catalog. Thousands of checkout records may point to the same book metadata record instead of copying the full title, author, and publisher data into every transaction.

Pros and Cons

ProsCons
Reduces memory use when many objects share the same immutable data.Requires a clear split between shared and per-instance state.
Improves cache efficiency by reusing shared metadata.Shared mutable state is dangerous and can create subtle bugs.
Centralizes ownership of shared intrinsic state.Adds complexity that is not worth it unless the scale problem is real.

Best Practices

  • Keep flyweights immutable or treat them as effectively read-only once cached.
  • Separate intrinsic shared state from extrinsic per-instance state clearly.
  • Measure first. Flyweight is a performance pattern and only matters when repetition is actually large enough.
  • Hide caching behind a factory so callers do not manage reuse manually.
  • Avoid Flyweight if shared state becomes difficult to reason about or accidentally mutable.

When to Use

  • You have many objects that repeat the same immutable data.
  • Memory pressure or cache efficiency matters.
  • Shared metadata can be safely reused across many contexts.

When NOT to Use

  • The objects are few enough that duplication is irrelevant.
  • The supposedly shared state changes frequently.
  • The performance optimization would complicate otherwise clear code.