Linguaggio UML e diagramma delle classi

Linguaggio UML e diagramma delle classi

Il diagramma delle classi definito mediante il linguaggio UML nell’ambito dell’ingegneria del software serve ad illustrare come è strutturato il sistema. Esso contiene le classi e le relazioni che sussistono tra di esse. Le classi sono formate da attributi e metodi. Il diagramma delle classi non è altro che un modello di dati oltre che un modello del sistema software che si vuole realizzare. Non ci dà un modello dinamico sulle specifiche, non vi è nessun algoritmo masolo una dichiarazione di metodi.

Le principali relazioni fra classi sono associazione, generalizzazione e dipendenza. Vedremo in modo più specifico, nel seguito di questo articolo, la relazione di associazione e quella di generalizzazione, e solo infine descriveremo brevemente la relazione di dipendenza fra classi.

Relazione di associazione

La relazione di associazione è una relazione semantica tra due o più classi, questa relazione semantica viene in realtà trasferita tra le istanze delle classi, ossia gli oggetti, e quindi quando si implementerà quella relazione graficamente tracciata nel diagramma delle classi diventerà a livello di codice qualcosa che permetterà di legare due o più oggetti, ed è sempre bidirezionale.

L’associazione può essere individuata o assegnando un nome alla relazione o individuando i ruoli per le entità che sono coinvolte.

Vediamo subito un esempio:

Linguaggio UML e diagramma delle classi - Relazione di associazione
Linguaggio UML e diagramma delle classi – Relazione di associazione

In questo caso abbiamo un’azienda e una persona, due classi con propri attributi e metodi. La relazione che posso avere tra queste due classi, rappresentata graficamente dalla linea che le congiunge, è che la persona lavora nell’azienda e l’azienda dà lavoro alla persona. Oppure posso leggere la relazione in termini di ruoli e quindi la persona è un impiegato o dipendente(ruolo) mentre l’azienda è il datore di lavoro. La differenza sta nel fatto che la relazione esprime un’azione che collega le due classi mentre il ruolo caratterizza la classe relativamente all’altra.

Inoltre le relazioni hanno una molteplicità che si esprime sulla linea in prossimità di una o dell’altra classe. Esempio: L’azienda dà lavoro a una o più persone, la persona è impiegata in 0 o 1 aziende. Per implementare alcune relazioni, non tutti i linguaggi di programmazione hanno dei costrutti ben precisi. Per realizzare l’associazione tra due classe devo realizzare un mapping, usando in una e nell’altra classe un attributo dell’altra classe. Ad esempio in azienda metterò un attributo di Persona e in persona metto un attributo di Azienda.

Se la relazione è uno a molti metterò una lista di attributi dell’altra classe.

Ovviamente l’associazione si realizza a run-time. A livello statico non avrò mai un collegamento tra classi!

Ecco un esempio:

Implementazione uno a uno (C++)

Implementazione uno a uno (C++)
Implementazione uno a uno (C++)

Uso dell’associazione uno a uno

Uso dell'associazione uno a uno
Uso dell’associazione uno a uno

Implementazione associazione uno a molti

Implementazione associazione uno a molti
Implementazione associazione uno a molti

Uso dell’associazione uno a molti (C++)

Uso dell'associazione uno a molti (C++)
Uso dell’associazione uno a molti (C++)

Relazioni di Aggregazione e composizione

L’aggregazione come la composizione è un esempio particolare di relazione di associazione, in cui sostanzialmente abbiamo diverse parti che messe insieme ci danno una classe aggregata. Una classe contenitore e classi contenute all’interno.

Per l’aggregazione valgono le proprietà transitiva (se A è parte di B, e B è parte di C, allora A è parte di C)  e antisimmetrica ( se A è parte di B, allora B non è parte di A).

La caratteristica della proprietà è che a run-time l’oggetto contenuto sopravvive all’oggetto contenitore. Un esempio classico è quello dell’automobile che può essere considerata una classe aggregata di carrozzeria e motore, posso avere il motore costruito da un azienda e la carrozzeria da un’altra azienda, esse unite danno vita all’automobile.

Come capisco che si tratta di aggregazione?

Dal fatto che entrambe le parti hanno vita propria anche separate. Se ad esempio durante un incidente la carrozzeria si distrugge e il motore rimane intatto, il motore potrà essere riutilizzato e viceversa. Parti distinte con vita propria che messe insieme danno vita a una classe con proprie caratteristiche.

Come si crea l’aggregazione?

Devo definire dei riferimenti alle istanze aggregate nella parte privata della classe aggregante. Definire riferimenti significa sostanzialmente definire dei puntatori o un qualcosa che mi possa far ricollegare alla parte aggregata.

Bisogna poi definire delle operazioni per creare il collegamento tra le diverse classi.

Prendiamo l’esempio dell’automobile, abbiamo detto che essa deriva dall’aggregazione tra carrozzeria e motore , per cui immaginiamo di avere tre classi: automobile, carrozzeria e motore e di avere nella parte privata della classe automobile i riferimenti alle classi carrozzeria e motore, e poi un metodo che permetterà di mettere in relazione tra loro le parti provenienti dalle altre classi. Bisogna poi definire motore e carrozzeria, si definisce il puntatore e si richiama il metodo che crea,attraverso i puntatori di carrozzeria e motore, l’automobile.

La differenza sostanziale tra l’aggregazione e la composizione sta nel fatto che le classi componenti non hanno vita propria al di fuori della classe composta. La classe componente è responsabile della creazione e della distruzione degli oggetti componenti, e le classi componenti sono ad uso esclusivo della classe composta.

Relazione di generalizzazione

La seconda relazione è quella di generalizzazione che rappresenta essenzialmente una relazione gerarchica. Quindi avremo una superclasse con delle classi figlie poste a un livello inferiore che però ereditano le proprietà delle classi superiori. Queste classi figlie però, oltre ad ereditare le proprietà della superclasse, hanno delle loro proprietà specifiche che le specializzano. La relazione si legge come “è un tipo di”(leggendo dal basso verso l’alto) o “Può essere un”(leggendo dall’alto verso il basso). Ad esempio, tra gli animali, ho i vertebrati, gli invertebrati e così via. La classe animali è la classe superclasse , mentre vertebrati, invertebrati e così via sono tutte sottoclassi con una propria peculiarità. Le classi specializzate ereditano attributi e metodi. La sottoclasse può contenere nuovi attributi e può ridefinire gli attributi della superclasse. Possiamo pensare alle figure geometriche , per tutte si calcola l’area o il perimetro ma in ogni figura geometrica(Triangolo, quadrato ecc) cambiano le variabili e i calcoli, per cui esso va ridefinito di classe in classe.

La sintassi per la relazione di generalizzazione prevede l’uso della parola chiave <<extends>> .

Esempio:

class Cerchio extends FormaGeometrica.

La classe Cerchio estende la classe FormaGeometrica.

Relazione di dipendenza

Nel linguaggio UML, una relazione di dipendenza è una relazione nella quale un elemento, il client, utilizza o dipende da un altro elemento, il fornitore. È possibile utilizzare relazioni di dipendenza nei diagrammi di classe, componente, di distribuzione e di casi d’uso per indicare che una modifica al fornitore potrebbe richiedere una modifica al client.

È inoltre possibile utilizzare una relazione di dipendenza per rappresentare la precedenza, in cui un elemento del modello deve precederne un altro.

Generalmente, le relazioni di implementazione non hanno nomi.

Come viene illustrato nella seguente figura, una dipendenza viene visualizzata nell’editor del diagramma come una linea tratteggiata con una freccia aperta rivolta dal client al fornitore.

Linguaggio UML e diagramma delle classi - Relazione di dipendenza
Linguaggio UML e diagramma delle classi – Relazione di dipendenza

Utilizzo di relazioni di dipendenza

È possibile utilizzare relazioni di dipendenza ai modelli per ottenere i seguenti obiettivi:

  • Collegare due pacchetti per indicare che almeno un elemento nel pacchetto consumer dipende da un elemento del modello nel pacchetto fornitore. La relazione di dipendenza non indica che tutti gli elementi nel pacchetto consumer sono dipendenti.
  • Collega due classi per indicare che il collegamento tra tali classi è a un livello superiore di astrazione rispetto a una relazione di associazione. La relazione di dipendenza indica che la classe del consumer svolge una delle seguenti funzioni:
    • Utilizza temporaneamente una classe fornitore con un ambito globale
    • Utilizza temporaneamente una classe fornitore come parametro per una delle relative operazioni
    • Utilizza temporaneamente una classe fornitore come variabile locale per una delle relative operazioni
    • Invia un messaggio a una classe fornitore
  • Collega componenti a interfacce o altri componenti per indicare che utilizzano una o più operazioni specificate dall’interfaccia o dipendono dall’altro componente durante la compilazione.

Esempio relazione di dipendenza

In un’applicazione e-commerce, una classe Cart dipende da una classe Product perché la classe Cart utilizza la classe Product come parametro per un’operazione di aggiunta. In un diagramma di classe, una relazione di dipendenza è rivolto dalla classe Cart alla classe Product. Come viene illustrato nella seguente figura, la classe Cart è, di conseguenza, il client e la classe Product è il fornitore. La suddetta relazione indica che una modifica alla classe Product potrebbe richiedere una modifica alla classe Cart.

Pubblicato da Vito Lavecchia

Lavecchia Vito Ingegnere Informatico (Politecnico di Bari) Email: [email protected] Sito Web: https://vitolavecchia.altervista.org

Lascia un commento

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