L'associazione di aggregazione
L'associazione di aggregazione è una relazione debole
tra due classi.
Essa è un tipo di associazione tutto-parte (o
tutto-parti), in cui una classe (detta classe
tutto o contenitore o aggregato) è composta, cioè contiene, una o
più istanze di un'altra classe (detta classe parte o
componente).
Il termine relazione debole sta ad indicare che gli oggetti della
classe parte
esistono in qualità di componenti dell'istanza della classe tutto ma possono esistere anche
indipendentemente da essa e viceversa.
Se l'oggetto della classe tutto viene
distrutto, le istanze della classe parte possono continuare ad esistere autonomamente, oppure in
un'altra classe aggregato.
L'indipendenza delle vite degli oggetti delle classi tutto e
parte rappresenta la principale
differenza con l'associazione di composizione, precedentemente esaminata.
Anche questa associazione è nota come associazione HAS-A, in
quanto gli oggetti della classe tutto hanno (contengono) gli oggetti della classe parte.
Nei diagrammi UML, l'aggregazione si rappresentata con una linea
continua con un rombo vuoto dalla parte della classe tutto.

L'associazione può essere unidirezionale, ossia solo la classe tutto dipende dalla classe parte.
In tal caso è presente anche una freccia a punta aperta dal lato
della classe parte.

Se la dipendenza è, invece, bidirezionale, non sono presenti
frecce, come raffigurato nell'immagine seguente.

Come già visto nel caso della composizione, possiamo dedurre che, necessariamente, la classe
tutto deve dipendere dalla
classe
parte, in quanto, per forza di cose, deve avere uno o più attributi con funzione di
contenitore delle istanze della classe parte.
Viceversa, la classe
parte potrebbe non sapere
di essere un
componente della classe tutto, nel senso che potrebbe non
avere nessun attributo che fa riferimento alla classe tutto a cui appartiene.
Ne
consegue che è proprio questa caratteristica a determinare il tipo unidirezionale o bidirezionale dell'associazione.
Vediamo qualche esempio concreto per comprendere meglio.
Consideriamo il diagramma UML
seguente:

Da un punto di vista logico, il legame tra l'automobile e le ruote è un legame debole, in quanto
l'automobile può continuare ad esistere anche senza ruote e,
viceversa, le ruote possono essere prelevate ed utilizzate su
un'altra automobile.
Tale conclusione conduce, questa volta,
l'analista a produrre il diagramma raffigurato.
Inoltre, l'analista potrebbe decidere che l'automobile sia a conoscenza
dell'esistenza delle ruote (vedi attributo di tipo Ruota[*], ossia array di Ruota),
ma
non viceversa (la classe Ruota
non presenta nessun attributo, o parametro di input/output di metodi di tipo Automobile).
Questo comporterebbe l'unidirezionalità dell'associazione, rappresentata nella figura.
Da un punto di vista tecnico, a differenza della composizione, il
programmatore che implementerà il modello sarà libero di creare le istanze di Ruota
internamente alla classe Automobile (nel costruttore
o in altro metodo), oppure riceverle attraverso metodi setter o altri metodi
specifici. Inoltre sarà libero di restituirle come parametro di output di metodi pubblici
(es. getter).
Se, invece, il progettista avesse voluto che anche la classe Ruota fosse stata a conoscenza
dell'automobile di appartenenza, allora l'associazione sarebbe stata bidirezionale, con le
integrazioni illustrate di seguito.

Si noti la presenza dell'attributo e del parametro del costruttore, di tipo Automobile nella classe Ruota. In presenza di tale scelta del progettista, l'associazione deve, per forza di cose, essere bidirezionale, come evidenziato dall'assenza di frecce nella linea che unisce le due classi.