Il pattern Composite

Trattare oggetti composti come oggetti semplici con il pattern Composite

Il pattern Composite consente di rappresentare oggetti che sono composti da oggetti semplici e da oggetti compositi. Il pattern propone una interfaccia omogenea per gli oggetti semplici e compositi, in modo da lasciare massima libertà nella composizione, si parla quindi di composizione ricorsiva. L’oggetto utilizzatore tratta in maniera uniforme gli oggetti individuali (foglie) e gli oggetti (compositi) e forma una struttura simile ad albero. Il pattern Composite rientra nella categoria dei pattern strutturali dato che modificano la struttura di oggetti già esistenti.

Un tipo esempio di pattern Composite è nella creazione di un finestra: se creiamo due contenitore di tipo Container, nel primo aggiungiamo due pulsanti, mentre nel secondo Container inseriamo il primo Container ed un nuovo pulsante. In questo caso, quando abbiamo aggiunto il primo Container nel secondo abbiamo trattato il primo contenitore come un normale componente. Un esempio si trova a questo link.

Viene utilizzato quando i client utilizzatori vogliono trattare gli oggetti della struttura in maniera uniforme, ignorando le differenze. Composite rende più semplice l’aggiunta di nuovi tipi di componenti e semplifica l’utilizzo delle classi da parte dei client. Al contrario, rende più difficile restringere il tipo di componenti del pattern.

Graficamente il pattern Composite sarà:

Il pattern Composite

  1. Contesto:

      Gli oggetti primitivi possono essere combinati in un oggetto composito;
    • I clienti possono trattare un oggetto composito come primitivo.
  2. Soluzione:
    • Definire un’interfaccia (Primitive) che rappresenti un’astrazione dell’oggetto primitivo;
    • Un oggetto composito contiene una collezione di oggetti primitivi;
    • Sia gli oggetti primitivi che quelli compositi implementano l’interfaccia Primitive;
    • Nel realizzare un metodo dell’interfaccia Primitive, un oggetto composito applica il metodo corrispondente a tutti i propri oggetti primitivi, e poi combina i risultati ottenuti.

JButton: un esempio del pattern Composite in Java

Composite contiene i riferimenti degli oggetti di cui è composto. Gli oggetti leaf possono avere o meno la referenza dell’oggetto che vanno a comporre. I metodi di composizione add, remove e getChild vanno dichiarati per uniformità in Component. La lista dei componenti Leaf appartiene in genere al component per non avere informazione inutile nei leaf.

L’interfaccia Primitive rappresenta un oggetto primitivo. Sia i veri oggetti primitivi (chiamati Leaf, “foglia”) che quelli compositi implementano l’interfaccia Primitive. Primitive non deve essere obbligatoria un’interfaccia, può anche essere una classe come nel caso di Component.

Il pattern Composite

Il diagramma illustra come il pattern Composite è stato applicato nel caso dei contenitori e dei componenti grafici Swing/AWT. La relazione di aggregazione tra Composite e Primitive indica che un oggetto di tipo Composite contiene un insieme di riferimenti ad oggetti primitivi. La classe Component ricopre il ruolo dell’interfaccia Primitive, il cui metodo getPreferredSize è uno dei tanti metodi di questa classe e restituisce le dimensioni “ideali” del componente.
Sia JButton che Container estendono Component. Il metodo add di Container permette di aggiungere un altro Component all’insieme. Inoltre, in accordo col pattern, quando un contenitore deve rispondere ad una chiamata a getPreferredSize, chiamerà il metodo su tutti i componenti contenuti, e poi sommerà le dimensioni ottenute e restutuirà le sue dimensioni ideali.

Per una lista completa di tutti i design pattern fate riferimento a questa pagina.

Pubblicato in Design Pattern, Guide, Java, Programmazione Taggato con: , , , , , , , , , ,

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

*