Creare diagrammi di classe con UML

I diagrammi di classe sono diagrammi di struttura all’interno dell’Unified Modeling Language, abbreviato in UML. Il linguaggio di modellazione UML è uno standard ISO. Illustra i sistemi di programmazione orientata agli oggetti. Si possono registrare in modo chiaro anche i processi aziendali. Con l’ausilio di mezzi visivi, l’UML mostra gli stati dei sistemi e descrive le interazioni tra elementi del sistema. Per farlo la notazione stabilisce forme e linee per 14 tipi di diagrammi.

Diagrammi di classe nel contesto dell’Unified Modeling Language

La metamodellazione descrive sia i singoli elementi del linguaggio di modellazione che il linguaggio stesso e definisce le unità linguistiche per diversi livelli. Ad esempio, un'unità linguistica in questo linguaggio visivo è il comportamento. Descrive sia una metaclasse che un termine generico per tutti i fattori dinamici all'interno di un sistema. Un'altra unità linguistica è l'oggetto, l'elemento base della programmazione orientata agli oggetti. I diagrammi delle classi UML modellano gli oggetti come istanze di classi. Pertanto, il diagramma delle classi è uno dei più importanti e ampiamente usati tipi di diagrammi di UML.

I tipi di diagramma sono divisi in due categorie principali in base alla loro funzione: diagrammi di struttura e diagrammi di comportamento. Questi ultimi hanno una sottocategoria: i diagrammi di interazione, che non solo modellano il comportamento generale di un sistema, ma si concentrano anche sui flussi di informazioni tra gli oggetti nel corso di un processo. Questi includono, per esempio, i diagrammi di sequenza. Modellano l'ordine cronologico dei messaggi che fluiscono in un caso d'uso dettagliato. I diagrammi comportamentali visualizzano i processi dinamici. Un esempio è il diagramma di attività, che mostra come le singole azioni interagiscano in un flusso. I diagrammi strutturali, d'altra parte, mostrano stati statici; illustrano gli elementi di un sistema e le loro interdipendenze.

Il diagramma di classe suddivide le istanze oggetto a seconda delle loro proprietà in diverse classi, che hanno tra loro dipendenze gerarchiche. Allo stesso tempo esistono relazioni tra le diverse classi o tra oggetti.

Diagrammi di classe UML: campi di applicazione

I diagrammi delle classi rappresentano gli stati con gli elementi del sistema e mostrano le strutture fino all'istanza più piccola. Di conseguenza sono adatti per la presentazione di architetture software dettagliate. Da ciò si possono ricavare passi concreti di programmazione. Alcuni ambienti di programmazione basati su software convertono questi diagrammi UML direttamente in frame di codice.

Utilizzando la condivisione del team, gli sviluppatori comunicano tra loro o con altri responsabili delle decisioni all'interno di un'azienda. Per i non specialisti, un diagramma UML fornisce una panoramica delle strutture di sistema pianificate o dei flussi di processo. Inoltre, è possibile formulare i requisiti di sistema, che verranno poi implementati dagli sviluppatori. Gli esperti IT possono modellare e modificare efficacemente i diagrammi senza dover programmare ambienti o processi più grandi nella fase di pianificazione.

Di seguito i campi di applicazione dei diagrammi delle classi:

  • Descrivono i tipi all’interno di un sistema. La rappresentazione grafica può essere trasferita in diversi linguaggi e ambienti di programmazione. Pertanto esiste indipendentemente dall’applicazione futura.
  • Modellano le architetture software esistenti. Se i componenti aggiunti devono essere integrati, visualizzano strutture adeguate in cui è possibile incorporare nuovi componenti. Per i futuri elementi del sistema, i diagrammi delle classi creano una guida per il codice del programma. A seconda delle esigenze, questo passaggio potrebbe essere approssimativo o molto dettagliato.
  • Rappresentano modelli di dati e sono adatti a sistemi di varia complessità.
  • Nelle applicazioni nidificate, la documentazione e la manutenzione possono essere molto complesse. I diagrammi delle classi forniscono una panoramica dello schema.
  • Rappresentano i requisiti per un software. Come file immagine, possono essere facilmente inoltrati tramite canali aziendali interni. Ciò consente agli esperti di diversi reparti di scambiarsi idee sull’architettura.
  • Lo standard UML utilizza diagrammi di classe per rappresentare visivamente la propria notazione.

Diagrammi di classe: la notazione UML

I diagrammi delle classi UML consistono in classi e nelle relative istanze (oggetti) e interfacce. Creano relazioni gerarchiche e associazioni tra questi elementi. La notazione di questo tipo di diagramma è l’elemento chiave per la maggior parte degli altri diagrammi di struttura. L’UML 2 definisce i diagrammi di struttura come classificatori. All’interno della metamodellazione UML ci sono diagrammi di pacchetti, diagrammi di componenti e le stesse sottoclassi del diagramma di struttura, che non è però modellato, in quanto si tratta di una classe astratta. Il diagramma di classe è più adatto come esempio di diagramma di struttura. Altri diagrammi di questa categoria utilizzano componenti modificati del diagramma delle classi per la loro notazione.

Fatto

Come classificatore (in inglese: “classifier”), l’UML comprende una metaclasse astratta, che serve per assegnare elementi di modello all’interno del linguaggio di modellazione a un concetto comune. Questo processo è chiamato generalizzazione e lo standard si può formulare in generale. Se la specifica si basa su un particolare elemento, basta spiegare solo questa particolare caratteristica.

La classe

La classe è un elemento del modello nel diagramma delle classi e una specializzazione del classificatore incapsulato (EncapsulatedClassifier) e del classificatore del comportamento (BehavioredClassifier). Riunisce una grande quantità di istanze. Le istanze di oggetti all’interno di una classe hanno le stesse caratteristiche (Attributes) e comportamenti (Methods). Inoltre hanno la stessa semantica, il che significa che utilizzano gli stessi segni con lo stesso significato. In questo modo la classe è un tipo di modello per i loro oggetti. Crea un’istanza degli oggetti e definisce il loro comportamento nel sistema.

Fatto

L’istanza è un’espressione concreta di un elemento astratto. Esegue un comportamento prescritto all’interno dei parametri specificati. Alcune istanze sono denominate da UML in modo esplicito e in questo modo l’oggetto è un’istanza denominata della classe. Le proprietà delle istanze si modellano con diagrammi a livello di istanza. Al posto di un diagramma di classe, si disegna ad esempio un diagramma di oggetti.

I classificatori incapsulati ampliano i cosiddetti classificatori strutturati. Questi ultimi sono caratterizzati dal fatto che possono prescrivere una struttura interna e possono accogliere elementi connessi. Questi elementi (metaclassi: ConnectableElements) influenzano il comportamento dei classificatori. Ogni elemento connesso rappresenta un partecipante al comportamento nel classificatore. Si dice anche che assumano il ruolo. Il classificatore incapsulato ha inoltre un punto di aggancio (Port). Ciò isola il classificatore dal sistema senza perdere la connessione.

Le classificazioni del comportamento spesso si connettono a un’interfaccia chiamata InterfaceRealization. Il classificatore corrisponde implicitamente alle condizioni dell’interfaccia supportando la funzionalità dell’interfaccia. L’InterfaceRealization (chiamata anche “Lollipop”) si disegna come un cerchio vuoto, collegato alla classe tramite una linea.

Le metaclassi menzionate classificano gli oggetti. La classe è l’espressione specifica di queste metaclassi. Quindi definisce la classificazione più da vicino e concretizza le singole componenti che costituiscono la struttura e il comportamento degli oggetti. Le classi hanno proprietà che definiscono le classi stesse nonché gli oggetti subordinati. Tra queste proprietà si possono menzionare:

  • Proprietà (Properties o Attributes, se appartengono alla classe)
  • Operazioni (Operations, possono essere richiamate per un oggetto)
  • Ricevitori di segnale (Receptions) a partire da UML 2.0
  • Porte (Ports) a partire da UML 2.0
  • Connettori (Connectors)

Quando create un diagramma di classi, aggiungete queste proprietà alla notazione. In UML una classe si rappresenta come un rettangolo con una linea continua. Il suo corpo è composto da tre compartimenti, che sono disposti uno sopra l’altro. Solo la parte superiore deve essere modellata, poiché è lì che si definisce il nome della classe. Le altre due partizioni si possono opzionalmente etichettare con attributi (al centro) e operazioni (in basso). Assegnate una visibilità diversa a questi elementi scrivendo i seguenti simboli davanti ai loro nomi:

  • + = pubblico
  • - = privato
  • # = protetto
  • / = derivato
  • ~ = pacchetto
  • * = casuale

Properties (proprietà)

Le properties sono elementi collegati. Gli attributi di classe (ownedAttributes) sono sempre ruoli. Li si collega tramite connettori. Se hanno la proprietà isComposite = true (“è composto = vero”), allora sono chiamate parti (Parts).

La proprietà UML è una caratteristica strutturale che ha diversi utilizzi. Accanto alla funzione come attributo in una classe, può anche rappresentare estensioni di associazione.

Il Property Type deriva dal nome del classificatore. Facoltativamente potete specificare un valore standard per una caratteristica; inoltre i modificatori specificano meglio come si comporta una caratteristica:

  • ordinata (notazione: isOrdered = true)
  • unica (notazione: isUnique = true)
  • non unica (notazione: isUnique = false)
  • sola lettura (la caratteristica si può leggere ma non modificare, notazione: isReadOnly = true)
  • sequenza (la caratteristica è una raccolta ordinata, notazione: isUnique = false e isOrdered = true)
  • unione (unione derivata da sottoinsiemi, notazione: union)
  • ID (appartiene alla definizione del suo classificatore, notazione: id)
  • Vincolo di funzione (un vincolo che influenza la proprietà, notazione: property-constraint)
  • Ridefinizione di una proprietà (ridefinisce una proprietà ereditata e denominata, notazione: redefines [nomeproprietà])
  • Sottoinsieme della proprietà (simboleggia una proprietà che è un sottoinsieme di una proprietà denominata: subsets [nomeproprietà])

Operazioni

Le operazioni sono funzioni comportamentali. Si presentano sotto forma di classi, ma anche di tipi di dati o interfacce. Richiamano direttamente l’istanza di una classe. L’operazione specifica i seguenti aspetti:

  • Nome
  • Tipo
  • Parametro
  • Vincoli

L’operazione appartiene al suo classificatore principale, anche se questo può cambiarlo ridefinendo il tipo o i parametri.

Per le operazioni ci sono condizioni preliminari che devono essere soddisfatte prima che venga eseguita l’operazione. Tuttavia, l’UML non definisce come si comporta una chiamata di comportamento se non vengono soddisfatte le condizioni preliminari. Si impostano anche postcondizioni da soddisfare quando si conclude l’operazione. Le condizioni del corpo della classe limitano il risultato in uscita a un valore calcolato dalle sue specifiche. Questo valore dovrebbe soddisfare le postcondizioni, ma l’operazione può anche originare un’eccezione durante l’esecuzione, quindi probabilmente non soddisfa le postcondizioni.

La notazione per il diagramma di classe stabilisce che le operazioni vengano annotate in un compartimento nel corpo della classe. Secondo lo standard UML, questa informazione è obbligatoria. Allo stesso tempo, l’UML consente di comprimere tutte le informazioni standard all’interno di una classe. Soltanto il nome va annotato.

Ricevitore di segnale

Un ricevitore di segnale indica che un classificatore è pronto a ricevere un segnale. Definisce anche quali tipi di segnali sono accettati dalle istanze della classe. Il ricevitore di segnale è chiamato come il suo segnale. Le informazioni corrispondenti devono essere annotate nel corpo della classe in un compartimento sotto le operazioni.

Port

Le cosiddette “port” sono porte per classificatori incapsulati. Rappresentano un punto in cui il classificatore interagisce con il suo ambiente. A parte le porte, il classificatore incapsulato è un sistema autonomo. Poiché la sua struttura interna e gli elementi di comportamento sono indipendenti dal resto del sistema, è anche possibile definire tale classificatore in modo indipendente. Finché un sistema soddisfa i limiti della porta, è possibile riutilizzare il classificatore incapsulato in diversi ambienti.

Inoltre, l’UML consente più punti di aggancio per il classificatore. È possibile definire le proprie regole per ciascuna porta. La porta è una proprietà del classificatore, quindi si impostano le sue regole nell’area Properties. Esse includono i servizi offerti dal classificatore al suo ambiente e i servizi di cui ha bisogno. È possibile distinguere tra diversi flussi di informazioni identificando la porta che si sta utilizzando.

Anche le porte stesse hanno proprietà. Quando la porta esegue le funzioni pubblicate del classificatore, indica la proprietà isService. Se si verifica isService = true, la porta è considerata un componente indispensabile delle funzioni esternamente visibili del classificatore incapsulato. Se isService = false, la porta non è una delle funzionalità essenziali e può quindi essere modificata o cancellata, proprio come le altre funzioni interne.

Le porte interagiscono con le interfacce. Ci sono interfacce già pronte e necessarie (vedi il paragrafo “Interfacce”). L’interfaccia connessa alla porta specifica le interazioni che passano tramite la porta. Poiché il punto di aggancio è una proprietà, ha un tipo. Il valore di isConjugated si interpone tra il tipo e l’interfaccia della porta. Se il valore è “vero”, l’interfaccia richiesta si può derivare direttamente dal tipo di porta o dall’insieme di interfacce implementate dal tipo di porta. Un’interfaccia pronta è derivata in questo caso dall’insieme di interfacce. Se isConjugated è “vero”, l’interfaccia fornita deriva dal tipo.

Se un classificatore incapsulato genera un’istanza, vengono create istanze appropriate per ciascuna delle sue porte. Una porta mantiene la rispettiva istanza in base al suo tipo e alla sua molteplicità (vedi sotto). L’UML chiama le istanze punti di interazione. Ogni istanza ha riferimenti univoci che si distinguono tra le diverse richieste di funzionalità comportamentali indirizzate alle sue porte.

Le porte con la proprietà isBehavior = true mandano una richiesta all’istanza del classificatore incapsulato. La richiesta assume il comportamento specificato dall’istanza. Le cosiddette “Behavior Ports” (porte comportamentali) non inoltrano richieste all’interno del classificatore. Se non è impostato alcun comportamento nel diagramma delle classi, i messaggi su queste porte andranno persi.

Potete modellare una porta come un piccolo quadrato sul frame del classificatore a cui appartiene. Nella porta disegnate l’interfaccia necessaria o già fornita. Se non specificate alcuna proprietà speciale per la porta, disegnate l’interfaccia senza porta.

Connettori

I connettori definiscono le connessioni tra due o più istanze. Le specifiche consentono la loro comunicazione. A differenza delle relazioni come l’associazione, i connettori non collegano le istanze arbitrarie, ma solo le istanze definite come connettori. I connettori sono modellati come linee con almeno due estremità. Rappresentano le istanze partecipanti che assegnano un tipo agli elementi collegabili.

Molteplicità

Un’altra dimensione importante è la molteplicità. Questo parametro specifica quante istanze può formare una classe strutturata e limita gli attributi e le operazioni. Fa parte della struttura interna (questo è un elemento prescritto nel corpo della classe). Lo inserite dopo gli attributi e le operazioni. Questa sezione include anche la topologia. I nodi (istanze dell’oggetto) si collegano alle reti di topologia tramite i percorsi di comunicazione (CommunicationPaths).

Annotate le molteplicità come segue:

<molteplicità> : <intervallo di molteplicità> [<indicazione ordine> , <identificatore di unicità>]

L’intervallo di molteplicità indica un valore fisso o un intervallo da-a:

  • 0 = la classe non forma le istanze (accade raramente)
  • 0..1 = o nessuna istanza o un’istanza
  • 1 o 1..1 = esattamente un’istanza
  • 0..* o solo * = nessuna istanza o più istanze con valore aperto
  • 1..* = una o più istanze con valore aperto

L’ordine e l’unicità si possono esprimere come un set (insieme) o per singoli termini separati da una virgola. A seconda che i nodi del set siano unici o ordinati, al set viene fornita una descrizione del tipo. Nella notazione descrivete ogni dimensione come ordered/unordered (ordinata/non ordinata) o unique/not unique (unica/non unica).

Tipo di set

Unico

Ordinato

Sequenza

No

Multiset (Bag)

No

No

Set ordinato

Set

No

Vincoli

Bisogna menzionare anche il vincolo (Constraint): nelle versioni precedenti di UML, questo elemento rientrava tra le relazioni. L’UML definisce il vincolo come un elemento impacchettabile, il che significa che può appartenere direttamente a un pacchetto. Entra anche in tali relazioni con altri elementi, ad esempio con classi o proprietà, ma ciò non influisce sulla notazione. La restrizione è una condizione o garanzia per il suo proprietario e può influenzare uno o più elementi.

L’elemento proprietario deve avere accesso al vincolo, in modo da poter controllare se il vincolo è valido e se è stato soddisfatto. La possibilità che ciò accada dipende dal proprietario. Alcuni elementi, come l’operazione, verificano i vincoli prima dell’esecuzione, durante e/o in seguito. Hanno precondizioni, condizioni nel corpo della classe e postcondizioni. La specifica di quando un elemento debba verificare il proprio vincolo viene indicata come contesto dall’UML. Si distingue tra il contesto e le specifiche effettive: queste ultime descrivono quale elemento tracci la restrizione, quale aspetto venga valutato e quale risultato ci si aspetta. Alla specifica esatta viene assegnato un Constraint attraverso una specifica di valore booleano

La notazione consiste in una stringa di testo nel seguente formato:

<Nome dell’elemento vincolato> ::= { <Nome del vincolo> : <espressione booleana> }

L’UML non prescrive alcuna lingua specifica: nel creare un diagramma delle classi potete scegliere le restrizioni che volete nella lingua che preferite. Potete utilizzare un linguaggio di programmazione come Java, una lingua naturale o un linguaggio leggibile da una macchina come XML. L’Object Management Group, che stabilisce gli standard UML, pubblica l’Object Constraint Language (OCL). Questa lingua definisce i vincoli compatibili con UML. Il loro vantaggio è che si adatta perfettamente alla notazione.

Alcuni elementi vincolati in UML sono scritti come testo, ad esempio un attributo di una classe nel diagramma delle classi. Indicate la restrizione dopo l’elemento di testo tra parentesi graffe. Se si tratta del proprietario di un elemento che rappresentate come un’icona, posizionate il vincolo il più vicino possibile all’icona; in questo modo dovrebbe essere evidente che i due elementi hanno una relazione semantica. Per rendere ancora più chiara la connessione, scrivete la restrizione in un’icona di nota e collegatela al proprietario con una linea tratteggiata.

Se la restrizione si applica a due elementi, connettete i proprietari con una linea tratteggiata. Scrivete il vincolo in parentesi graffe. Se posizionate una freccia ad un’estremità, essa segnala la posizione del proprietario all’interno di un campione di elementi vincolati (constrainedElements). La freccia mostra il percorso dalla prima posizione verso la seconda. Se più di due elementi hanno la restrizione, utilizzate l’icona della nota e associate ciascun elemento al vincolo.

Anche le linee appartengono agli elementi che possono essere vincolati: se state modellando più di due linee dello stesso tipo, trascinate la linea del Constraint attraverso tutte le linee che rappresentano gli elementi coinvolti.

Stereotipi

Gli stereotipi definiscono le estensioni delle metaclassi. Secondo la specifica UML appartengono ai profili. Se uno stereotipo descrive proprietà aggiuntive di più metaclassi, può descrivere solo un’istanza della metaclasse alla volta in fase di esecuzione. Tra le metaclassi lo stereotipo assume un ruolo specifico, perché non può mai stare da solo. Modellate sempre uno stereotipo in combinazione con il classificatore che lo amplia. Connettete la metaclasse allo stereotipo modellando un’estensione (Extension).

N.B.

A partire dall’UML 2.4 la specifica si definisce così: l’etichetta di uno stereotipo si scrive all’inizio con una lettera maiuscola, come <<Type>>. Le altre etichette, come ad esempio le proprietà alle estensioni delle associazioni, si scrivono generalmente in minuscolo.

Si distinguono due tipi di relazioni tra (meta)classi e stereotipi. L’estensione richiesta (notazione: isRequired = true) definisce che uno stereotipo si associa a ciascuna istanza della metaclasse nel diagramma delle classi. L’estensione non necessaria (notazione: isRequired = false) consente di associare liberamente le istanze della metaclasse a uno stereotipo. Potete anche cancellare lo stereotipo. Tuttavia, una particolare istanza può essere associata ad un determinato stereotipo solo una volta durante il runtime.

Se volete rimuovere uno stereotipo, eliminate il profilo che lo definisce dalla sezione profili applicati (appliedprofiles) nel pacchetto sovraordinato. In alternativa, si elimina l’istanza che esso estende.

L’UML definisce alcuni stereotipi di classe (sei dei quali sono standard) che ampliano il vostro diagramma di classe UML. Anche se non standardizzati, spesso sono utilizzati tre stereotipi che traducono il pattern “modello-presentazione-gestione” (Model-View-Controller, abbreviato in MVC) in UML. I tre stereotipi non standardizzati sono:

  • L’entità (notazione: <<Entity>>): lo stereotipo Entity definisce una classe o un oggetto. L’istanza corrispondente rappresenta una raccolta di dati. Spesso si tratta di dati di sistema che devono essere archiviati per un lungo periodo di tempo. L’entità assume il ruolo di modello dal pattern MVC. L’UML conosce questo stereotipo, ma lo assegna per impostazione predefinita ai diagrammi dei componenti. La notazione usata più frequentemente non elenca le specifiche. In questo caso l’entità è indicata con un cerchio che poggia su una linea corta.
  • Il confine (notazione: <<Boundary>>): il confine è uno stereotipo per una classe o un oggetto. Corrisponde approssimativamente all’elemento View nel pattern MVC. Il confine modella il limite del vostro sistema, ad esempio un’interfaccia utente. Di solito è rappresentato come un cerchio, dal quale parte a sinistra una linea che incontra una linea verticale.
  • L’elemento di controllo (notazione: <<Control>>): l’elemento di controllo rappresenta gli stessi elementi del controller nello schema MVC. Le classi o gli oggetti con questo stereotipo modellano elementi che regolano il comportamento del sistema o i flussi di controllo. Nello standard UML lo stereotipo <<focus>> assume compiti simili. Un’istanza di controllo si disegna come un cerchio con una punta della freccia aperta sulla linea.

Questi tre stereotipi si possono anche designare come una semplice classe. Nel rettangolo annotate il nome dello stereotipo corrispondente. Principalmente i modellisti usano queste forme nei diagrammi di sequenza. Se volete saperne di più sui diagrammi Entity-Boundary-Control, leggete il nostro articolo sui diagrammi di sequenza con UML.

Per i diagrammi di classe sono adatti i seguenti stereotipi standardizzati:

  • focus (<<Focus>>)
  • ausiliario (<<Auxiliary>>)
  • tipo (<<Type>>)
  • classe di implementazione (<<ImplementationClass>>)
  • metaclasse (<<Metaclass>>)
  • utility (<<Utility>>)

Focus

La classe focus definisce la logica aziendale di base o il flusso di controllo delle classi ausiliarie. Esse supportano la classe focus che raccorda uno o più ausiliari. Definisce implicitamente le classi di supporto ammettendo una relazione di dipendenza (vedi “la relazione diretta”). Se utilizza le classi di aiutanti, le definisce esplicitamente. Lo standard UML raccomanda questo stereotipo specialmente per la fase di progettazione, quando si mostrano i flussi di controllo tra i componenti o si imposta la logica di business.

Fatto

La logica aziendale, chiamata anche logica di applicazione, descrive la logica di un sistema che gestisce l’esecuzione di requisiti aziendali reali. È diversa dalla logica che determina l’esecuzione tecnica. Nella programmazione orientata agli oggetti, la logica aziendale ha prodotto il concetto dell’oggetto business, che modella i processi concreti e i valori reali in un sistema di informazioni.

Ausiliario

La classe helper (ausiliario) di solito funziona in combinazione con la classe focus. In genere supporta classi di importanza critica per il sistema. A tale scopo esegue flussi di controllo secondari e definisce la logica sussidiaria. Se la classe helper supporta una classe focus, la definizione risulta esplicita. Utilizzate una relazione di dipendenza per definire implicitamente la classe supportata.

Tipo

La classe di tipi definisce un’area per gli oggetti di business. Inoltre specifica gli operatori di questi oggetti. Lo stereotipo del tipo può presentare attributi e associazioni. Tuttavia non descrive l’esecuzione fisica dell’oggetto.

Classe di implementazione

Alcuni linguaggi di programmazione (ad esempio Java o C++) consentono solo una classe per ogni istanza. Con UML tuttavia potete associare un’istanza a più classi. La classe di applicazione crea un ponte tra questi due mondi. Questo stereotipo limita la classe UML. Stabilisce che un’istanza da lui dipendente possa realizzare solo una classe. In compenso la classe di implementazione può implementare diversi tipi. Per eseguire correttamente un classificatore ad essa associato, deve soddisfare due condizioni: deve fornire tutte le operazioni del classificatore ed esse devono presentare il comportamento definito per il classificatore. Gli attributi fisici e le associazioni non devono per forza corrispondere.

Metaclasse

Poiché le forme della classe e della metaclasse sono indistinguibili, l’etichetta Metaclass indica che si tratta dello stereotipo della metaclasse. Le istanze di questa classe sono esse stesse classi. Con questo stereotipo lavorate perciò ad un livello più alto di astrazione.

Utility

La classe Utility non ha istanze, ma identifica semplicemente una raccolta di attributi e operazioni denominati, che sono sempre statici. Gli attributi statici non cambiano quando vengono richiamati e le operazioni statiche sono applicate a entità o tipi di entità. Se si utilizza la classe utility, dovete specificare i valori e le operazioni appropriate sin dall’inizio, poiché non variano più. Questi elementi sono segnalati dalla sottolineatura.

N.B.

L’UML specifica ulteriori stereotipi predefiniti per altri tipi di diagramma, le cui aree di applicazione e notazione si possono trovare nelle specifiche dell’UML 2.5.1, capitolo 22: profili standard, tabella 22.1, pagina 680.

Interfacce

Le interfacce sono classificatori. Nella loro notazione sono simili alle classi. A differenza della classe, tuttavia, sono dichiarazioni, cioè dichiarano molte delle funzioni e degli obblighi pubblici logicamente coerenti. Per questo usano un contratto. Se un’istanza esegue l’interfaccia, deve soddisfare questo contratto. In quanto dichiarazione, l’interfaccia stessa non forma istanze.

A questo punto si situa la classe, poiché produce istanze. La sua istanza utilizza specifiche dell’interfaccia e per questo deve rispettare il contratto dell’interfaccia. In cambio utilizza l’interfaccia come scenario pubblico. Inoltre un classificatore può utilizzare più interfacce, mentre un’interfaccia può servire anche più classificatori. Nel diagramma delle classi UML, le notazioni di interfaccia e classe sono simili: un rettangolo, opzionalmente suddiviso in tre aree attraverso delle linee.

Per dimostrare che una classe utilizza un’interfaccia, usiamo la notazione InterfaceRealization (nota dai classificatori del comportamento). Essa rappresenta un’interfaccia già fornita (Provided Interface), cioè un’interfaccia che esegue direttamente un’istanza. Quest’ultima si applica anche alle classi di livello superiore come i componenti. Se la classe ha una porta pubblica, questa fornisce l’interfaccia. L’InterfaceRealization è rappresentata da un cerchio collegato al classificatore tramite una linea.

Ci sono anche interfacce richieste (Required Interfaces), che visualizzano una relazione di dipendenza (vedi “Relazioni”). Un elemento richiede un altro elemento per eseguire l’intera estensione delle proprie funzioni. In questo caso un classificatore (o una delle sue istanze) ha bisogno di un’interfaccia. L’InterfaceUsage (utilizzo dell’interfaccia) specifica i requisiti per l’interfaccia. Per questo una linea continua collega il classificatore a un semicerchio aperto che simboleggia l’interfaccia. Annotate il nome dell’interfaccia in entrambi i rappresentanti sotto il (semi)cerchio.

Se una classe eredita un’interfaccia per una classe subordinata, modellate il collegamento dell’interfaccia alla classe o all’istanza subordinata. Mostrate la relazione gerarchica con il circonflesso (^), ad esempio come ^interfaccia 1.

Se utilizzate la notazione con le interfacce rettangolari, tracciate una linea tra i due nodi. Nel diagramma delle classi le linee modellano le relazioni tra classi, istanze o componenti. L’UML prescrive linee o frecce diverse per funzioni e relazioni diverse. In questo caso collegate una classe con l’interfaccia richiesta tramite una freccia tratteggiata con una punta aperta. Date alla freccia l’etichetta <<use>>. Un’interfaccia pronta si connette a una classe tramite una freccia tratteggiata con una punta chiusa non piena. La freccia punta sempre nella direzione dell’interfaccia.

Tipi di dati

I tipi di dati combinano un insieme di oggetti con le loro operazioni. Utilizzano intervalli di valori concreti e li combinano con le loro operazioni specifiche. Gli oggetti possono avere diversi tipi. I loro valori numerici vanno da tipi primitivi a enumerazioni più lunghe.

I tipi di dati sono classificatori. Le vostre istanze vi identificheranno solo in base al loro valore. I tipi di dati visualizzano i tipi di valore, i tipi primitivi e i tipi strutturati nel diagramma di classe UML. Se si copia un’istanza del tipo di dati o se si modellano due istanze dello stesso tipo di dati con lo stesso valore, vengono considerate le stesse istanze.

Se il tipo di dati ha attributi, l’UML lo assegna come un tipo di dati strutturato. Le sue istanze sono considerate uguali solo se la loro struttura e i valori dei loro attributi sono gli stessi.

I tipi primitivi non hanno una struttura subordinata ma rappresentano valori atomici di dati. Vengono applicati nel diagramma di classi anche in caso di restrizioni. Molti di questi tipi hanno una semantica complessa al di fuori delle specifiche UML. Nell’UML, tuttavia, non hanno alcuna identità, motivo per cui sono indistinguibili nel caso dello stesso valore. Questi sono alcuni tipi primitivi nell’UML:

  • Boolean (variabili booleane)
  • Integer (numero intero)
  • UnlimitedNatural (illimitato, numero naturale)
  • Real (numeri reali)
  • String (catena di caratteri)

I tipi primitivi si annotano con l’etichetta <<primitive>> sopra il nome del rispettivo tipo di dati.

L’Enumeration (enumerazione) è un tipo di dati. Esse rappresentano il valore dell’enumerazione come un cosiddetto simbolo di lettera di enumerazione. Come si vede nella figura sopra, si tratta semplicemente di un nome che simboleggia un valore specifico, che potete scegliere voi. Ad esempio nell’elenco “tipi di rose”, il nome “rosa Bourbon” sta per il numero di rose Bourbon che un negozio di fiori ha nel proprio assortimento. Nel diagramma di classe indicate questo classificatore con il simbolo per la classe, un rettangolo. Il nome così come l’etichetta <<enumeration>> si inseriscono nell’intestazione dividendola dal corpo del testo con una linea orizzontale.

Come con altre classi, l’enumerazione riserva i reparti superiori per attributi e operazioni. Se questi rimangono vuoti, lasciate entrambe le sezioni fuori dal diagramma. Nella parte inferiore inserite il simbolo della lettera di enumerazione. Ad esempio l’enumerazione dei tipi di rose in un negozio di fiori consiste nell’intestazione “tipi di rosa” e il corpo del testo con una lista dei singoli tipi: rosa indica fragrans, rosa Noisette, rosa gallica, rosa Bourbon, rosa majalis.

Relazioni

I diagrammi delle classi rappresentano le relazioni tra gli elementi del sistema: l’osservatore dovrebbe quindi vedere di quali componenti necessita il sistema e come si influenzano a vicenda. La relazione tra gli elementi UML è una classe astratta. Rappresenta l’idea di una relazione tra i componenti del sistema. Pertanto questo elemento non ha una notazione separata. Le sue caratteristiche, tuttavia, hanno dettagli specifici che li contraddistinguono.

Le relazioni in UML sono intese come linee che collegano i nodi. In questo modo si modellano in generale le relazioni con una linea o con delle linee modificate, come ad esempio una freccia.

La definizione UML per le sottoclassi e le istanze di relazione in alcuni casi è cambiata drasticamente nel passaggio da UML 1 a UML 2. Ad esempio c’erano originariamente relazioni semantiche, strutturali e direzionali. Tre relazioni concrete (associazione, vincolo e dipendenza) sono state assegnate alle relazioni semantiche. Nell’UML 2 i vincoli sono ora elementi componibili, le associazioni definiscono alcune fonti come una relazione strutturale e semantica. La dipendenza è ora in relazioni direzionali.

Resta da vedere come cambierà lo standard nelle versioni future. Di seguito continuiamo a spiegare i diagrammi delle classi nell’UML 2.5. Pertanto la relazione metaclasse ha due sottoclassi: la relazione diretta e l’associazione.

L’associazione

L’associazione è una relazione che collega le tuple. Nell’informatica, le tuple sono raccolte di valori ordinati. Anziché la quantità, giocano un ruolo la connessione logica e l’ordine. Pertanto non è sbagliato assegnare all’associazione anche un componente strutturale, oltre alla descrizione ufficiale come relazione semantica. L’associazione è un collegamento tra i classificatori. Gli elementi in questa relazione hanno una prossimità logica o fisica. A seconda del numero di membri, l’associazione è chiamata binaria (due istanze), ternaria (tre istanze) o n-aria (a partire da quattro istanze).

Le estremità dell’associazione connettono nei diagrammi di classe UML le associazioni con le istanze. L’estremità dell’associazione ha un nome finale che esprime il ruolo dell’istanza nella relazione. Supponiamo che uno studente realizzi diverse versioni di un cortometraggio per un seminario di cinema. Quindi il ruolo dello studente di cinema nel film sarebbe quello di “artefice”. Il ruolo del film sarebbe quello di “lavoro per il seminario”. Scrivete il nome sotto la linea di collegamento, in ogni caso presso il simbolo dell’istanza che lo descrive. L’estremità appartiene all’associazione stessa o al classificatore dell’estremità. In caso di più di due estremità, il ruolo appartiene all’associazione.

La freccia accanto ai nomi di associazione nel diagramma di classe sopra mostra la direzione della relazione. Nel diagramma sotto il punto sull’istanza “Film” indica che l’estremità dell’associazione è “lavoro per il seminario” dell’istanza “studente di cinema”. Poiché il termine “artefice” dell’associazione non ha alcun segno, appartiene all’associazione stessa: la molteplicità “1” indica che esiste esattamente un’istanza “studente di cinema”. L’istanza “Film” ha almeno tre impostazioni.

La navigabilità è una proprietà finale (End Property). Indica se un’istanza a questa estremità dell’associazione è raggiungibile dall’altra estremità dell’associazione. Se l’istanza B è raggiungibile per l’istanza A, tracciate una punta della freccia aperta sulla linea dell’associazione nella direzione dell’istanza B direttamente sul simbolo dell’istanza B. Se l’istanza D non è raggiungibile per l’istanza C, tracciate una X sulla linea dell’istanza D. Se non desiderate nessun tipo di navigabilità, non disegnate notazioni separate.

Ci sono due varianti dell’associazione: il collegamento (link) e l’aggregazione.

  • Il collegamento (link) è un’istanza dell’associazione. Ha almeno due estremità, ognuna con una molteplicità. Questo valore deve essere un’istanza del tipo di dati delle estremità. Nella nostra immagine di esempio sopra uno studente di cinema filma tre film durante i propri studi. Il valore per l’istanza “studente” è “1”. Il valore per l’istanza “film” è “3”. Si modella la connessione come linee continue tra partecipanti relazionali. A differenza dell’associazione, il link collega le istanze e non i classificatori.
  • L’aggregazione è un’associazione binaria, perciò ha sempre due partecipanti. A differenza del link, non crea relazioni sullo stesso livello, ma mostra le relazioni tra una parte e il tutto. Rappresentate l’aggregazione con una proprietà all’estremità dell’associazione: modellate un rombo sull’istanza che rappresenta il tutto.

Un tipo di aggregazione è l’aggregazione composita (Composite Aggregation), che descrive la relazione tra una composizione di parti e una singola parte di esse. Se il sistema cancella il tutto (la composizione), distrugge anche la singola parte. Ad esempio se un albero rappresenta il tutto, allora la foglia è una parte di esso. Se l’albero è vittima di un incendio boschivo, il fuoco distrugge anche le foglie. Se si vuole creare per esempio un diagramma di classe e rappresentare tale relazione, tracciate una linea continua tra le istanze. Disegnate un rombo colorato di nero dalla parte della composizione (in questo caso, l’istanza “albero”). Questo lato è anche chiamato estremità dell’aggregazione.

Un secondo tipo di aggregazione è l’aggregazione condivisa (o semplicemente abbreviata in aggregazione). Questa relazione asimmetrica esiste tra una proprietà e un’istanza che rappresenta un insieme di istanze. La connessione dovrebbe essere diretta. Altrimenti un’istanza di composizione potrebbe essere interpretata come parte di se stessa. Ciò può accadere se modellate la relazione di dipendenza in modo ciclico. La proprietà condivisa può appartenere a più composizioni. Allo stesso tempo la loro istanza può esistere indipendentemente dalla composizione. Se il sistema dovesse in questo caso eliminare una composizione (o tutte), l’istanza secondaria può continuare ad esistere. Pertanto questa relazione è considerata debole rispetto alla composizione.

Inoltre l’associazione offre un’altra caratteristica speciale: la classe di associazione, che è allo stesso tempo classe e relazione. Ciò consente di assegnare attributi alla classe di associazione nel diagramma di classi.

La relazione diretta

La relazione diretta è una classe astratta. Descrive le relazioni tra un’origine e una destinazione. Entrambe le estremità della relazione possono avere più elementi. Come l’associazione, anche la relazione diretta non ha una notazione fissa. Le loro sottoclassi costituiscono forme specifiche che si basano su una linea dall’origine alla destinazione. Le seguenti istanze definiscono una relazione diretta:

  • generalizzazione (Generalization)
  • dipendenza (Dependency)
  • vincolo del modello (Template Binding)
  • inclusione (Include): fa parte della notazione per i diagrammi dei casi d‘uso
  • estensione (Extend): fa parte della notazione per i diagrammi dei casi d‘uso

La generalizzazione è una relazione binaria tra le classi. È orientato da una sottoclasse a una superclasse, cioè da una classe specifica a una classe più generale. La classe determinata (ad esempio dalia) ha la generalizzazione. Una freccia con la punta chiusa ma non riempita punta da questa origine alla destinazione, che è la classe generale (ad esempio la famiglia delle asteraceae).

La sottoclasse specifica la classe generale. Ciò significa anche che la sottoclasse condivide alcune delle sue proprietà, sia di contenuto che di struttura, con la superclasse, di solito gli elementi di base. Questa circostanza viene chiamata ereditarietà. Ad esempio la classe “dalia” dell’esempio condivide l’infiorescenza a forma di coppa con la superclasse della famiglia delle Asteraceae. Una caratteristica specifica del genere “dalia” sono le sue otto coppie di cromosomi (le piante di solito hanno soltanto due coppie di cromosomi). Le diverse specie di dalia hanno caratteristiche che conferiscono aspetti diversi.

Fatto

Nel linguaggio colloquiale, le generalizzazioni sono anche indicate dalla relazione “è un…”. Per esempio si può dire “una dalia è un’asteracea”.

Implicitamente l’UML consente l’ereditarietà multipla. In questo modo modellate diverse sottoclassi che hanno sia superclassi comuni che diverse. In alternativa ci sono diversi livelli di generalizzazione. Potete rappresentare queste relazioni con la notazione a freccia o nidificare le sottoclassi nelle loro superclassi. Per fare ciò, modellate tutte le sottoclassi nel corpo della superclasse.

Il set di generalizzazione (Generalization Set) vi aiuta a tenere traccia del diagramma delle classi. Il set è un elemento impacchettabile. I pacchetti in UML sono contenitori per elementi denominati che hanno somiglianze semantiche e possono cambiare insieme. Un pacchetto è uno spazio dei nomi e non una classe. È possibile associare il set di generalizzazione a un classificatore. Ciò prende il nome di powertype.

Modellate il powertype come stringa sulla linea di generalizzazione in questa forma: {[isCovering Property] , [isDisjoint Property]} : [nome del tipo powertype]. La proprietà isCovering descrive se il set è completo. I valori sono complete (completi) o incomplete (incompleti). La proprietà isDisjoint dice ai classificatori di condividere istanze comuni. I valori sono o disjoint (non sovrapposti) o overlapping (quando si verifica una sovrapposizione).

N.B.

La standardizzazione UML 2.5 fornisce poche informazioni sull’ereditarietà. Tuttavia è possibile fare riferimento alle versioni precedenti. L’UML 2 afferma generalmente che le classi specializzate assumono le caratteristiche e i limiti delle loro superclassi. L’UML 1.4 specifica che gli attributi dichiarati sovrascrivono gli attributi ereditati in una sottoclasse.

La dipendenza (Dependency) è una relazione tra “fornitore” e “cliente” (supplier-client relationship). Questa relazione diretta descrive che un elemento dipende da un altro elemento. Si può trattare anche di molti elementi. Il cliente ha bisogno di un altro elemento per una più corretta specificazione o per eseguire il proprio compito. Senza il fornitore al cliente manca la componente strutturale o semantica. Pertanto le modifiche al fornitore potrebbero influire sui clienti. Nell’UML 2.5, la semantica influenza sempre l’elemento denominato, ma non le sue istanze. Le dipendenze hanno un ruolo non solo nel diagramma delle classi UML, ma anche in altri diagrammi strutturali come il diagramma dei componenti o il diagramma di distribuzione.

La dipendenza ha tre sottocategorie:

- astrazione (Abstraction)

- distribuzione (Deployment)

- uso (Usage)

L’astrazione collega elementi a diversi livelli. In alternativa, mostra prospettive diverse. Gli elementi denominati in questa relazione rappresentano lo stesso concetto. Secondo lo standard UML l’elemento più specifico è il client, che dipende dal provider, l’elemento più astratto. Pertanto l’estremità della freccia dovrebbe appartenere alla sottoclasse e la punta alla superclasse. L’UML consente anche una notazione inversa. Se ritenete che abbia più senso che l’elemento astratto dipenda dalla sua sottoclasse, disegnate la punta della freccia sull’elemento più specifico.

L’astrazione ha due sottoclassi: realizzazione (Realization) e manifestazione (Manifestation).

La realizzazione è già stata introdotta nell’ambito delle interfacce. La realizzazione dell’interfaccia (InterfaceRealization) è una specifica della realizzazione. Descrive una relazione tra classificatore e interfaccia. Il classificatore utilizza l’interfaccia per fornire un servizio alla propria clientela. L’interfaccia esegue questo servizio. Per fare ciò, il classificatore deve soddisfare il contratto stabilito dall’interfaccia. La notazione per le interfacce fornite e richieste è disponibile nella sezione “Interfacce”.

La sostituzione (Substitution) è un’altra relazione che specifica la realizzazione. Consiste in un classificatore sostitutivo e un classificatore del contratto. Il classificatore sostitutivo soddisfa il contratto dell’altro classificatore. Durante il runtime le istanze del classificatore di sostituzione possono potenzialmente sostituire le istanze del classificatore del contratto. Contrariamente alla specializzazione, non vi è alcuna somiglianza strutturale tra gli elementi della sostituzione. Contrassegnate la sostituzione come linea di dipendenza (freccia tratteggiata con punta aperta) nel diagramma delle classi e aggiungete la parola chiave <<substitute>> sulla linea.

La manifestazione descrive una relazione tra un artefatto e uno o più elementi del modello. L’UML definisce gli artefatti come classificatori. Simbolizzano istanze concrete e fisiche come cartelle di archivio. La manifestazione rappresenta un artefatto che esegue direttamente un elemento connesso. D’altra parte può simboleggiare che gli elementi sono coinvolti nella creazione dell’artefatto. La manifestazione è un elemento del diagramma di distribuzione ed è menzionata qui solo per motivi di completezza. Richiede la stessa notazione delle sostituzioni e la parola chiave è <<manifest>>.

L’astrazione definisce anche alcuni stereotipi, i quali appartengono ai profili UML. Se una metaclasse esistente per un progetto deve essere estesa, si definisce per essa un profilo. La classe stereotipo si utilizza sempre insieme alla metaclasse, poiché un profilo cambia solo uno esistente o aggiunge una terminologia. A partire da UML 2.4.1., l’UML contrassegna gli stereotipi all’inizio in maiuscolo. Gli stereotipi standard per un’astrazione sono:

  • Derivare (<<Derive>>): un elemento è derivato da un altro elemento. Per lo più sono dello stesso tipo.
  • Affinare (<<Refine>>): un elemento fornisce informazioni più dettagliate per una classe che esiste anche nell’altro elemento. Gli elementi sono a diversi livelli di astrazione. Ad esempio un modello a livello esecutivo perfeziona la classe “impiegato” relativa alla classe “impiegato” a livello di progettazione.
  • Tracciare (<<Trace>>): diversi modelli esprimono aspetti diversi di un sistema. Per tracciare elementi che rappresentano lo stesso concetto in diversi modelli utilizzate mapping o tracing. Con Trace potete tenere traccia delle modifiche agli elementi e alle specifiche.
N.B.

Con l’aiuto di questi stereotipi di astrazione mappate la relazione tra client e provider. Questo processo può essere bilaterale o unilaterale e formale o informale. Client e provider sono in diagrammi diversi, ad esempio in un diagramma di classe e in un diagramma dei casi d’uso.

La distribuzione mostra la relazione tra un artefatto e la sua missione. Nel diagramma UML, la linea di distribuzione di uno o più artefatti punta alla missione (Deployment Target). La parola chiave per la linea è <<deploy>>. Potete anche applicare questa dipendenza a livello delle istanze. In alternativa modellate l’artefatto nel corpo del fine della missione. Per farlo potete disegnare l’artefatto come simbolo o elencare gli artefatti forniti. Questa dipendenza fa parte della notazione del diagramma di distribuzione.

L’uso descrive una relazione in cui il client ha bisogno del provider per completare le sue attività o eseguire le operazioni. L’uso implementa quindi la dipendenza generale come un’istanza. Questa dipendenza forma alcune relazioni concrete:

  • Utilizzare (<<use>>): un elemento utilizza un altro elemento, ma la relazione esatta e il beneficio preciso non sono specificati in dettaglio.
  • Creare (<<create>>): un classificatore del client o uno dei suoi elementi strutturali o comportamentali crea una o più istanze del classificatore del provider.
  • Richiamare (<<call>>): un’operazione richiama un’altra operazione. La destinazione può essere qualsiasi operazione intorno all’operazione di origine, inclusi i classificatori sovraordinati.
  • Inviare (<<send>>): un’operazione è l’origine, ovvero il client. Il suo obiettivo è un segnale. La dipendenza fa quindi in modo che l’operazione invii il segnale di destinazione.
  • Interfaccia richiesta (Required Interface ­­­-----C): contrariamente all’interfaccia fornita, l’interfaccia richiesta non esiste nel classificatore. Determina i servizi di cui necessita un classificatore per il proprio client. La dipendenza sussiste tra classificatore e interfaccia. Nella sezione “Interfacce” troverete maggiori informazioni sull’argomento.

Il vincolo del modello (Template Binding) è l’ultima relazione diretta utilizzata nel diagramma delle classi. Quando create un diagramma di classe, a volte è utile creare modelli per le classi. I modelli nelle classi consistono di parametri del modello, cioè parametri che appartengono alla firma del modello. La firma a propria volta determina l’insieme ordinato di parametri all’interno del modello. Se modellate classi che non hanno bisogno di avere proprietà individuali, lavorerete in modo più efficiente se utilizzate i modelli. Ma se una classe dovesse ricevere parametri fissi, utilizzate il Template Binding. La relazione sussiste tra un elemento associato e la firma del modello in un modello di destinazione.

L’elemento associato è in grado di creare modelli, il che significa che può diventare un modello o si può legare ad altri modelli. L’oggetto è legato perché ha una connessione a un modello. Questa connessione descrive la struttura dell’elemento sostituendo i parametri del modello formale dal modello con parametri di valore.

In sintesi

Il diagramma di classe è uno dei diagrammi UML più popolari perché presenta strutture di sistema in modo dettagliato e chiaro. Come diagramma strutturale mostra il sistema in stato statico. Ciò offre agli spettatori una panoramica degli elementi necessari in un sistema. Inoltre, rappresentano relazioni tra i blocchi costitutivi dell’architettura di sistema: dagli oggetti reali alle classi astratte con profili espandibili, è possibile utilizzare il diagramma di classe UML per modellare indipendentemente dal linguaggio di programmazione. In tal modo promuovete la comprensione tra i dipartimenti nella realizzazione di un progetto.

Per offrirti una migliore esperienza di navigazione online questo sito web usa dei cookie, propri e di terze parti. Continuando a navigare sul sito acconsenti all’utilizzo dei cookie. Scopri di più sull’uso dei cookie e sulla possibilità di modificarne le impostazioni o negare il consenso.