Flyweight Pattern – optimizarea memoriei prin reutilizarea obiectelor

  • Doru Bulubasa
  • 05 December 2025

Când dezvolți aplicații care procesează un număr foarte mare de obiecte – liste lungi, noduri grafice, caractere, structuri repetitive – consumul de memorie poate deveni rapid o problemă.

Aici intervine Flyweight Pattern, un Structural Design Pattern care permite partajarea obiectelor comune, reducând masiv memoria alocată.


🔍 Ce este Flyweight Pattern?

Flyweight este un pattern care separă starea intrinsecă (care poate fi partajată) de starea extrinsecă (specifică fiecărui obiect).

Astfel, în loc să creezi mii sau milioane de obiecte identice, reutilizezi instanțele deja create.

Este util mai ales în aplicații cu:

  • multe elemente grafice repetate

  • liste mari de date

  • texte caractere-cu-caractere

  • scenarii de cache

  • generare de documente sau hărți


🧠 Conceptul pe scurt

Obiectele se împart în:

  • Stare intrinsecă – proprietăți comune tuturor instanțelor

  • Stare extrinsecă – valori specifice fiecărei utilizări

Chestia cheie: numai starea extrinsecă se pasează la runtime, iar obiectele intrinseci sunt reutilizate.


🏗 Structura actorilor

  • Flyweight – interfața pe care o folosesc toate obiectele partajate

  • ConcreteFlyweight – obiect reutilizabil, ce conține starea intrinsecă

  • FlyweightFactory – creează și gestionează instanțele comune

  • Client – furnizează starea extrinsecă și folosește flyweight-ul


🧪 Exemplu practic în C#

Scenariu: gestionăm caracterele unui text într-un editor. Literele sunt identice ca formă, diferă doar pozițiile lor pe ecran.

🎯 1. Interfața Flyweight

public interface ICharacterFlyweight
{
    void Render(int fontSize, int x, int y);
}


🎯 2. Flyweight concret (stare intrinsecă)

public class CharacterFlyweight : ICharacterFlyweight
{
    private readonly char _symbol; // intrinsec

    public CharacterFlyweight(char symbol)
    {
        _symbol = symbol;
    }

    public void Render(int fontSize, int x, int y)
    {
        Console.WriteLine($"Rendering '{_symbol}' at ({x},{y}) with size {fontSize}");
    }
}


🎯 3. Flyweight Factory (cache-ul de caractere)

public class CharacterFlyweightFactory
{
    private readonly Dictionary<char, ICharacterFlyweight> _characters = new();

    public ICharacterFlyweight GetFlyweight(char symbol)
    {
        if (!_characters.ContainsKey(symbol))
        {
            _characters[symbol] = new CharacterFlyweight(symbol);
            Console.WriteLine($"Creating new flyweight for '{symbol}'");
        }

        return _characters[symbol];
    }
}


🎯 4. Utilizare Flyweight în aplicație

var factory = new CharacterFlyweightFactory();
string text = "AAABBC";

int x = 0;
foreach (char c in text)
{
    var character = factory.GetFlyweight(c);
    character.Render(fontSize: 12, x: x, y: 10);
    x += 10;
}


📉 Beneficii

Consum redus de memorie

✔ Scalabilitate mare în structuri repetitive

✔ Creștere de performanță în scenarii grafice, hărți, cache

⚠ Dezavantaje

❌ Necesită separarea atentă a stării intrinseci/extrinseci

❌ Crește complexitatea codului

❌ Poate fi supra-inginerie dacă numărul de obiecte nu este mare


🧭 Când să folosești Flyweight?

Folosește-l când:

  • ai foarte multe obiecte similare

  • memoria consumată devine o problemă

  • obiectele împart o mare parte din comportament/stare

  • vrei un cache de obiecte reutilizabile

Evită-l dacă:

  • obiectele sunt puține

  • starea extrinsecă este complicată

  • diferențele între instanțe sunt mari


🔚 Concluzie

Flyweight Pattern este esențial pentru optimizarea memoriei în aplicații mari, repetititve sau grafice. Prin separarea stărilor și reutilizarea obiectelor comune, poți reduce dramatic amprenta RAM, păstrând același comportament funcțional.

Dacă aplicația ta .NET procesează milioane de elemente, acest pattern poate face diferența între un sistem lent și unul performant.

Scrie un comentariu

Adresa de mail nu va fi publicata. Campurile obligatorii sunt marcate cu *