Il più diffuso diagramma compreso in UML è il diagramma delle classi.
Si tratta di un diagramma statico che può essere utilizzato:
I concetti fondamentali di un class diagram sono estensioni dei concetti fondamentali dei paradigmi object-oriented.
Nel seguito verrà presentato il class diagram nella sua accezione più completa, relativa alla modellazione dell’implementazione di sistemi object-oriented.
I principali elementi dei class diagram sono:
Una classe è semplicemente rappresentata da un rettangolo con il nome della classe all’interno.
Il concetto di classe è lo stesso dell’OO.
La signature completa di un’operazione è:
operationName(parameterName: parameterType …): returnType
visibilità nome molteplicità: tipo = default {proprietà}
Sono consentiti tre livelli di visibilità:
+ Livello pubblico: L’utilizzo viene esteso a tutte le classi;
# Livello protetto: L’utilizzo è consentito soltanto alle classi che derivano dalla classe originale;
- Livello privato: Soltanto la classe originale può utilizzare gli attributi e le operazioni definite come tali.
Il nome dell’attributo é l’unico parametro necessario.
Il tipo dell’attributo può essere un tipo standard (int, double, char, etc…) oppure il nome di una classe definita nello stesso diagramma (in tal caso forse l’attributo andrebbe indicato con un’associazione …).
Default rappresenta il valore di default dell’attributo.
nome molteplicità: tipo = default {proprietà}
La molteplicità indica il quantitativo degli attributi (ad esempio la dimensioni per un array). Tramite la molteplicità è possibile indicare come attributi degli array o matrici. Il valore di default é 1.
Alcuni valori possibili sono:
1 (uno e uno solo). E’ il valore di default;
0..1 (al più uno);
* (un numero imprecisato, eventualmente anche nessuno; equivalente a 0..*);
1..* (almeno uno).
Gli elementi di una molteplicità sono considerati come un insieme.
Se essi sono dotati anche di ordine si aggiunge l’indicazione {ordered}.
Se sono possibili valori duplicati si aggiunge l’indicazione {nonunique}
{proprietà} rappresenta caratteristiche aggiuntive dell’attribute (ad esempio la sola lettura); Esempio: name: String [1] = “Untitled” {readOnly}.
visibilità nome (lista parametri) : tipo-ritornato {proprietà}
La visibilità e il nome seguono regole analoghe a quelle degli attributi.
Lista parametri contiene nome e tipo dei parametri della funzione, secondo la forma:
direzione nome parametro: tipo = valore-di-default
direzione: input (in), output (out) o entrambi (inout). Il valore di default é in.
nome, tipo e valore di default sono analoghi a quelli degli attributi.
Tipo-ritornato é il tipo del valore di ritorno: dovrebbe essere un tipo appartenente ad una classe standard.
Esempio: + balanceOn (date: Date) : Money
Un’associazione rappresenta una relazione (fisica o concettuale) tra classi.
Esempio (fig.1): Persona possiede Automobile
Il verso di navigazione è un’informazione utile soprattutto in fase di progetto di dettaglio.
Indica in quale direzione è possibile reperire le informazioni.
Nell’esempio in figura, nota una persona è possibile sapere quali sono le automobili che possiede (se ne possiede).
Viceversa, non è possibile conoscere il possessore di una data automobile.
Non ci sono, però, indicazioni sul quantitativo di automobili possedute, nè sul numero di proprietari di un automobile (da questo diagramma non possiamo sapere se si tratti di informazioni non note o di informazioni soppresse).
Di solito, il verso di navigazione rappresenta una scelta di progetto, per cui non è presente nei diagrammi concettuali.
La molteplicità delle associazioni indica il numero di istanze di oggetti di ogni classe che possono appartenere ad una istanza della associazione.
In figura:
Quest’esempio si configura come associazione uno a molti (una Persona, molte Automobili).
Uno studente può conseguire un numero potenzialmente non limitato di esami;
Un esame può essere conseguito da un numero potenzialmente non limitato di studenti;
Possono esserci studenti che non hanno conseguito esami;
Possono esserci esami non conseguiti (ancora) da nessuno studente;
Se avessimo voluto modellare il caso in cui uno studente era considerato solo dal momento del conseguimento del primo esame, allora sarebbe stato (vedi figura).
Ogni studente ha uno e un sol badge
Un badge identifica uno e un solo studente.
Se avessimo voluto considerare anche studenti che, magari temporaneamente, non abbiano un badge, allora diventa: (vedi figura).
Molti a uno (es.: una Persona, molte Automobili):
Molti a molti (es: molti Studente, molti Esame)
Uno a Uno (es: uno Studente, un Badge)
Associazione uno a uno
class A {
Public: link(B* linkato):ruolo_di_B(linkato) {}
Private: B* ruolo_di_B;
};
Class B {
Public: link(A* linkato):ruolo_di_A(linkato) {}
Private: A* ruolo_di_A;
};
Void main() {
A a;
B b;
a.link(&b);
b.link(&a);
};
Associazione uno a molti
class A {
Public: aggiungi(B* newobj);
rimuovi(B* oldobj);
Private: lista_puntatori_a_B;
};
Class B {
Public: link(A* linkato):ruolo_di_A(linkato) {}
Private: A* ruolo_di_A;
};
Una prenotazione si riferisce sempre ad un solo passeggero:
Un Passeggero può avere più prenotazioni
Una prenotazione si riferisce ad un volo.
Un volo può avere più passeggeri prenotati.
In alcuni casi, un attributo che si riferisce a due classi collegate non può essere riferito a nessuna delle due.
Può esistere nel caso di molteplicità molti-a-molti.
Prima di creare un’istanza della classe Voto, devono esistere le istanze delle classi collegate.
La classe associativa può avere attributi, metodi, altre associazioni.
Le Aggregazioni sono speciali associazioni che rappresentano una relazione ‘tutto-parti’.
Il lato del ‘tutto’ è spesso chiamato l’aggregato.
La molteplicità dal lato del tutto, quando è sottintesa, vale 0..1
Una associazione diventa una aggregazione se:
Per quanto le aggregazioni siano importante dal punto di vista della espressività del modello, spesso sono implementate in maniera identica rispetto ad associazioni di pari cardinalità.
Una composizione è una forma forte di aggregazione.
Se l’aggregato viene distrutto, anche le sue parti saranno distrutte (le parti non esistono senza il tutto).
Evidentemente, in questo dominio, non ha senso parlare di stanze fintantochè esse non siano state legate alla casa in cui si trovano. La cardinalità dell’aggregazione, se sottintesa, vale 1.
Consideriamo il seguente esempio:
Esso esprime il concetto che l’Automobile (ogni istanza di Automobile) ha una Carrozzeria ed un Motore.
La specifica prodotta indica un contenimento in senso lasco. Per quanto detto scegliamo la traduzione di tale relazione tramite l’uso dei puntatori.
//file Automobile.h
#include "Motore.h"
#include "Carrozzeria.h"
class Automobile {
public:
//il costruttore inizializza Automobile anche in assenza di Motore e Carrozzeria
Automobile(Stringa marca= "", Stringa mod="",..., Motore* mot=0, Carrozzeria* car=0);
...
private:
Carrozzeria* carrozzeria; //traduzione aggregazione
Motore* motore; //traduzione aggregazione
...
};
//file Automobile.cpp
//Costruttore di Automobile
Automobile:: Automobile(Stringa marca, Stringa mod,...,Motore* mot, Carrozzeria* car) :
marca(marca), modello(mod),motore(mot), carrozzeria(car);
Il programma principale dovrà dapprima creare un oggetto di tipo Carrozzeria e Motore ed infne l’oggetto di tipo Automobile. Ad esempio:
#include "Automobile.h"
main () { //usa classe Automobile
//definisce e inizializza oggetto di tipo Motore
Motore m("AZ123","Ferrari", 6,12,1000);
//definisce e inizializza oggetto di tipo Carrozzeria
Carrozzeria c("12345ASA", "RossoFerrari",1500);
//definisce e inizializza puntatore a motore
Motore* puntatoreMotore=&m;
//definisce e inizializza puntatore a carrozzeria
Carrozzeria* puntatoreCarrozzeria=&c;
//definisce e inizializza oggetto Automobile, fornendo puntatori
Automobile auto1("Ferrari", ..., puntatoreCarrozzeria, puntatoreMotore);
...
} //al termine vengono separatamente distrutti m,c e auto1
1. Introduzione
4. Casi d'uso
6. Class Diagram – parte prima
7. Class diagram – parte seconda
8. Class diagram – parte terza
9. Modellazione architetturale
10. Sequence Diagram
14. Progettazione Architetturale
15. Design Patterns – Parte prima
16. Design Patterns – Parte seconda
17. Progettazione dell'interfaccia utente
Ian Sommerville, Ingegneria del Software, capitolo 8, 14.
Martin Fowler, UML Distilled, capitolo 3, 5 (class diagram).
Carlo Savy, Da C++ a UML, capitolo 34.