DEV Community

Cover image for Flyweight Pattern: condividere per risparmiare memoria
Dev-Iadicola
Dev-Iadicola

Posted on • Originally published at iadicola.it

Flyweight Pattern: condividere per risparmiare memoria

Il problema: migliaia di oggetti quasi identici

Un editor di testo deve rappresentare ogni carattere come un oggetto con font, dimensione, colore, posizione. Un documento di 100.000 caratteri creerebbe 100.000 oggetti, ognuno con le stesse proprieta di font ripetute. Se il 95% del testo usa lo stesso font a 12px in nero, stai duplicando quelle informazioni 95.000 volte. La memoria esplode senza motivo.

Il Flyweight Pattern separa lo stato di un oggetto in due parti: lo stato intrinseco (condivisibile, invariante — il font, la dimensione, il colore) e lo stato estrinseco (unico per ogni istanza — la posizione nel documento). Gli oggetti con lo stesso stato intrinseco condividono la stessa istanza. Invece di 100.000 oggetti, ne hai forse 10 (uno per ogni combinazione font/dimensione/colore) riusati 100.000 volte.

Cos'e il Flyweight Pattern: definizione formale

Il Gang of Four definisce il Flyweight come un pattern strutturale che "usa la condivisione per supportare in modo efficiente grandi quantità di oggetti a grana fine". La struttura prevede:

  • Flyweight: l'interfaccia che dichiara il metodo che riceve lo stato estrinseco come parametro
  • ConcreteFlyweight: contiene lo stato intrinseco (condiviso). Non memorizza stato estrinseco.
  • FlyweightFactory: gestisce il pool di flyweight. Se un flyweight con lo stesso stato intrinseco esiste già, lo restituisce. Altrimenti ne crea uno nuovo.
  • Client: mantiene lo stato estrinseco e lo passa al flyweight quando serve

Esempio teorico: un sistema di icone per una mappa

Un'applicazione web mostra 50.000 punti di interesse su una mappa. Ogni punto ha un'icona che dipende dalla categoria (ristorante, hotel, museo, farmacia). Le categorie sono 20. Senza Flyweight: 50.000 oggetti icona, ognuno con l'immagine, le dimensioni e i colori della categoria. Con Flyweight: 20 oggetti IconFlyweight (uno per categoria), riusati 50.000 volte. Lo stato estrinseco (posizione sulla mappa) viene passato come parametro al metodo render(x, y).

Esempio teorico: pool di connessioni

Un connection pool e un Flyweight applicato alle connessioni database. Invece di creare una connessione per ogni query (costoso: handshake TCP, autenticazione, allocazione risorse), il pool mantiene N connessioni preallocate e le riusa. La connessione e il flyweight (stato intrinseco: host, porta, credenziali), la query specifica e lo stato estrinseco passato al momento dell'uso.

Flyweight in PHP: cache di oggetti

In PHP, il Flyweight si manifesta spesso come cache di istanze. Un ColorFactory che mantiene un array statico di colori già creati: if (isset($this->colors[$hex])) return $this->colors[$hex]. Un CurrencyFactory che riusa gli stessi oggetti Currency per EUR, USD, GBP invece di crearli ad ogni transazione.

Le Enum di PHP 8.1 sono di fatto flyweight nativi: Currency::EUR e sempre la stessa istanza, mai duplicata. Ogni volta che scrivi Currency::EUR === Currency::EUR il risultato e true per identita, non solo per valore. Il linguaggio applica il pattern implicitamente.

Quando usare il Flyweight

  • Usa il Flyweight quando l'applicazione crea migliaia di oggetti simili che consumano troppa memoria
  • Usa il Flyweight quando la maggior parte dello stato degli oggetti e condivisibile (intrinseco)
  • Usa il Flyweight quando gli oggetti possono essere sostituiti da pochi oggetti condivisi più stato estrinseco
  • Non usare il Flyweight se gli oggetti sono pochi: l'overhead della factory supera il risparmio
  • Non usare il Flyweight se lo stato intrinseco e minimo: non c'e abbastanza da condividere
  • Non usare il Flyweight in PHP per request singole dove la memoria viene rilasciata a fine richiesta — ha senso per processi long-running (worker, daemon, CLI)

Il Flyweight Pattern e il pattern dell'economia strutturale: condividere cio che e identico, personalizzare solo cio che e unico. In contesti con grandi volumi di oggetti simili — mappe, editor, sistemi di particelle, pool di risorse — il risparmio e drammatico.


👉 Leggi l'articolo completo su iadicola.it

Top comments (0)