vai al contenuto principale

Composizioni

Una composizione è una relazione tra due classi nella quale una, detta part, è parte dell'altra, detta whole.

La composizione stabilisce un legame speciale tra le due classi, in cui l’esistenza degli oggetti della classe part diventa dipendente da quella degli oggetti della classe whole. L’uso delle composizioni è dunque indicato in tutti quei casi in cui la relazione tra le due classi non è paritaria, ma si vuole esprimere in maniera più stringente la subalternità di una delle due classi rispetto all’altra.

Il ruolo che punta verso la classe whole non è mai navigabile; nel Designer esso è rappresentato da un rombo nero, che distingue graficamente una composizione da un’associazione. L’unica molteplicità consentita per questo ruolo è Exactly one (1); questo perché ogni oggetto della classe part può essere parte di un solo oggetto all’interno dell’applicazione.

L’altra estremità della composizione, quella del ruolo della classe part, è invece sempre navigabile e può avere qualunque molteplicità. In altri termini, un oggetto part può essere parte di un unico intero (whole), mentre per ogni intero possono essere definite un numero arbitrario di parti.

Una composizione

In figura è mostrato un esempio di composizione: la classe Project_assignment è stata modellata come part della classe whole Employee; questo perché l’incarico relativo un progetto non è un concetto indipendente, ma è sempre subordinato a quello di impiegato. In altre parole, gli incarichi hanno senso di esistere come oggetti solo in quanto parti di specifiche istanze della classe Employee.

Creare una composizione #

Fai click destro sulla classe whole per aprire il suo Class menu e seleziona l’opzione New composition; apparirà una linea tratteggiata che va dalla classe whole alla posizione del tuo cursore. Spostati sulla classe part e cliccaci sopra.

In alternativa, clicca sull’icona della Palette Create a new composition, poi clicca prima sulla classe whole e dopo sulla classe part.

Crea una composizione

Nel momento in cui viene creata una composizione, la classe che diventa part perde il proprio class role, e con esso la possibilità di poter essere gestita indipendentemente nell’applicazione generata:

  • su questa classe non è più possibile creare oggetti in maniera autonoma (direttamente dalla form della classe), ma solo definendoli in quanto parti di un oggetto che si sta creando o modificando all’interno della classe whole;
  • non è possibile associare gli oggetti part già creati, perché a ciascuno di essi può corrispondere un solo oggetto intero;
  • quando un oggetto della classe whole è eliminato, sono eliminate anche le istanze della classe part a esso associate.

Composizioni riflessive #

È possibile creare anche composizioni riflessive, in cui una classe è contemporaneamente sia whole sia part di se stessa. Questo può essere utile nel caso si voglia modellare una tassonomia, o comunque tutti quei casi in cui una classe rappresenta un nodo in una gerarchia di oggetti. Il procedimento per creare una composizione riflessiva è analogo a quello per l’associazione riflessiva; tuttavia, è necessario che la classe sulla quale è dichiarata la composizione riflessiva abbia almeno una relazione con un’altra classe. Se non si rispetta questa condizione, il Designer ci segnala che ogni gruppo connesso di classi nel modello deve includere almeno una classe che non è parte di nessun’altra. Affinché la composizione riflessiva sia raggiungibile nell’applicazione generata, la relazione (di qualunque tipo) che la connette all’altra classe deve essere navigabile da quest’ultima verso la classe con la composizione riflessiva. Riprendendo l’esempio della tassonomia, in altre parole, è necessario che la radice della gerarchia sia modellata su un’altra classe non riflessiva.

Convertire un’associazione in composizione #

Una composizione può sempre essere trasformata in associazione tramite l’opzione Convert to association del suo Composition menu. La cardinalità del ruolo di quella che precedentemente era la classe whole viene automaticamente impostata a Exactly one (1).

Fai click destro sull’associazione che vuoi convertire per aprire il suo Association menu e seleziona l’opzione Convert to composition. Il ruolo con molteplicità Exactly one (1) sarà quello della classe whole e apparirà come un rombo nero. La direzione di navigabilità verrà automaticamente corretta in modo che punti verso la classe part.

Convertire un'associazione in composizione

Esempio: composizione a molti #

Nel modello in figura abbiamo rappresentato i clienti (Customer) di uno store digitale e i metodi di pagamento da essi utilizzati (Payment_method). Abbiamo modellato la relazione tra le due classi attraverso una composizione: poiché la presenza nel sistema dei dati relativi alle carte di credito è subordinata al singolo record del cliente, Customer è la classe whole, mentre Payment_method è la classe part; non avrebbe infatti senso gestire i metodi di pagamento in maniera indipendente, mantenendo in memoria le carte dei clienti che non utilizzano più l’applicazione (e che quindi sono stati eliminati dal database).

Poiché ogni cliente può avere utilizzare più metodi di pagamento, abbiamo impostato Any (*) come molteplicità per il ruolo della classe part.

Una composizione a molti

Esempio: composizione a uno #

Espandiamo ora l’esempio precedente modellando l’indirizzo di residenza dei clienti, un altro concetto fortemente dipendente da Customer. A differenza dei metodi di pagamento, che potevano essere più di uno per ciascun cliente, a ogni oggetto di Customer può corrispondere un solo indirizzo. Per questo motivo, abbiamo scelto come molteplicità Zero or one (01); rispetto a una molteplicità più stringente come Exactly one (1), Zero or one consente di aggiungere l’indirizzo anche in un secondo momento (ma sempre dalla form di Customer).

Una composizione a uno

Abbiamo poi aggiunto al modello la classe Employee, per creare un’anagrafica degli impiegati della nostra applicazione. Invece di modellare una classe a parte per memorizzare i loro indirizzi, abbiamo preferito riutilizzare la classe Address già presente. Abbiamo così creato un’altra composizione con molteplicità Zero or one (01), che collega Employee a Address.

Classe part coinvolta in più composizioni

Ora la classe Address è part sia di Employee sia di Customer,ma ciò naturalmente non vuol dire che impiegato e cliente debbano condividere lo stesso indirizzo! Anzi, data la natura delle composizioni, un oggetto di Address non potrà mai essere part sia di un Employee sia di un Customer. Quando una classe part è coinvolta in più composizioni, ciascuno dei suoi oggetti può essere parte di un solo oggetto whole in tutta l’applicazione.

In caso di composizioni multiple come questa, il Designer ci permette di definire un vincolo di unicità specifico (Unique constraint options for parts), in base alla provenienza dell’oggetto part. In questo modo possiamo evitare che le informazioni di una classe vadano in conflitto con quelle di un’altra.