Design Patterns Mastery

Flyweight Pattern: Drastically reducing memory footprint

1 Views Updated 5/4/2026

The Flyweight Pattern

The Flyweight Pattern is used to minimize memory usage by sharing as much data as possible with other similar objects. It is the secret behind high-performance gaming engines and text editors that can handle millions of characters with zero lag.

1. Intrinsic vs Extrinsic State

  • Intrinsic: Data that is the same for all objects (e.g., The shapes of the 'A' character in a font). This is Shared.
  • Extrinsic: Data that varies for each object (e.g., The coordinates of 'A' on page 5). This is Unique.

2. Implementation Tip

We use a Flyweight Factory. When you ask for an object, the factory checks if it already has one in memory. If yes, it returns the existing instance. If no, it creates a new one and stores it for the next person.

public class TreeFactory 
{
    private static Dictionary<string, TreeType> _types = new();

    public static TreeType GetTreeType(string name, string color) 
    {
        // If we already have a 'Green Oak', reuse the object!
        if (!_types.ContainsKey(name)) 
            _types[name] = new TreeType(name, color);
            
        return _types[name];
    }
}

4. Interview Mastery

Q: "How does the .NET 'String Intern Pool' implement the Flyweight pattern?"

Architect Answer: ".NET maintains a hidden table (the Intern Pool) for all literal strings. If you have 10,000 variables all set to the string 'Error', the CLR doesn't create 10,000 objects. It creates ONE 'Error' object (the Flyweight) and points all 10,000 variables to that same memory address. This saves significant RAM and makes string comparison (`==`) much faster. This is Flyweight in action at the runtime level."

Design Patterns Mastery
1. Introduction to Design Patterns
Introduction to GoF Patterns: Why patterns matter? SOLID Principles: The foundation of all patterns DRY, KISS, and YAGNI (Architectural Philosophy)
2. Creational Patterns
Singleton Pattern: Thread-safety & Captive Dependencies Factory Method: Abstracting complex object creation Abstract Factory: Creating families of related objects Builder Pattern: Constructing complex fluents Prototype Pattern: Cloning high-cost objects
3. Structural Patterns
Adapter Pattern: Bridging incompatible interfaces Bridge Pattern: Decoupling abstraction from implementation Composite Pattern: Managing tree structures & hierarchies Decorator Pattern: Enhancing behavior without inheritance Facade Pattern: Simplifying complex library subsystems Flyweight Pattern: Drastically reducing memory footprint Proxy Pattern: Interception, Lazy-Loading, and Security
4. Behavioral Patterns
Chain of Responsibility: Middleware & Pipeline Architecture Command Pattern: Implementing Undo/Redo & Queueing Interpreter Pattern: Building domain-specific languages Iterator Pattern: Unified traversal of collections Mediator Pattern: Decoupling components with MediatR Memento Pattern: Capturing and restoring object state Observer Pattern: Pub/Sub & Event-driven architecture State Pattern: Managing complex object lifecycles Strategy Pattern: Swappable algorithms at runtime Template Method: Defining skeleton algorithms Visitor Pattern: Separating operations from data structures
5. Modern Enterprise & Cloud Patterns
Repository & Unit of Work (The EF Core Standard) CQRS Pattern (Command Query Responsibility Segregation) Circuit Breaker & Retry Patterns (Resilience with Polly) Dependency Injection Pattern (The Modern King)