Vai alla Home Page About me Courseware Federica Living Library Federica Federica Podstudio Virtual Campus 3D La Corte in Rete
 
Il Corso Le lezioni del Corso La Cattedra
 
Materiali di approfondimento Risorse Web Il Podcast di questa lezione

Stefano Russo » 2.La modellazione a oggetti e il linguaggio UML (richiami)


Argomenti

Richiami di ingegneria del software: la modellazione ad oggetti e UML

  • Il linguaggio UML: generalità
  • Diagramma dei casi d’uso (cenni)
  • Diagramma delle classi

UML (Unified Modeling Language)

L’UML è un linguaggio standard utilizzabile per progettare, rappresentare o documentare qualunque tipo di sistema (software, hardware, organizzativo). NON è un linguaggio di programmazione. E’ uno standard OMG (Object Management Group) dal novembre del 1997; i suoi autori sono:

  • Grady Booch;
  • Ivar Jacobson;
  • Jim Rumbaugh.

I diagrammi di UML

Ogni diagramma di UML é progettato per fornire a sviluppatori e clienti la vista di un sistema software da diverse prospettive e a vari gradi di astrazione. Diagrammi “logici”

  • Diagramma dei casi d’uso (use case diagram)
  • Diagramma delle classi (class diagram)
  • Diagramma di sequenza (sequence diagram)
  • Diagramma di collaborazione (collaboration diagram)
  • Diagramma di stato (state–chart diagram)
  • Diagramma delle attività (activity diagram)

Diagrammi di “implementazione”

  • Diagramma dei componenti (component diagram)
  • Diagramma di distribuzione (deployment diagram)

Diagramma dei Casi d’uso

Diagramma dei casi d’uso: Vendita per corrispondenza

Diagramma dei casi d'uso: Vendita per corrispondenza


Casi d’uso: a cosa servono

Rappresentano le modalità di utilizzo del sistema da parte di uno o più utilizzatori (attori). Descrivono l’interazione tra attori e sistema, senza rivelare l’organizzazione interna del sistema. Ciascun caso d’uso può essere descritto in forma testuale, comprensibile anche ai “non addetti ai lavori”. Possono essere definiti a livelli diversi (sistema o parti del sistema). Il ragionare sui casi d’uso aiuta a esplicitare i requisiti del sistema.

Ruolo dei Casi d’uso


Diagramma delle classi

Lo scopo di un diagramma delle classi è di rappresentare le classi e le relazioni tra esse all’interno di un modello (di analisi o di progettazione). Le relazioni tra classi definiscono un così detto modello statico del progetto. L’elemento fondamentale del diagramma delle classi é un’icona che rappresenta una classe, come indicato in figura.


Esempio di diagramma delle classi


Relazioni tra classi

Gli oggetti che costituiscono un’applicazione sono tipicamente istanze di classi che in generale non sono isolate, ma in relazione con altre classi mediante legami di varia natura, detti “relazioni“. Le principali relazioni tra le classi sono:

  • la relazione di gen-spec;
  • la relazione di contenimento;
  • la relazione di associazione.

Diagramma delle classi: la relazione gen-spec

Una relazione gen-spec rappresenta un legame di generalizzazione-specializzazionetra classi, che si ha quando una classe è un caso particolare di una o più altre classi, ovvero quando una classe è una generalizzazione di un o più altre classi. Un legame gen-spec è tipicamente espresso nei requisiti in linguaggio naturale da frasi del tipo:

  • “X è un Y”.
    • Es.: Un cane è un animale.
  • “Z può essere X o Y”
    • Es.: Un conto bancario può essere un conto corrente o un conto di deposito.

Le relazioni gen-spec danno luogo a strutture di ereditarietà. Il legame gen-spec è espresso in UML mediante una freccia dalla classe particolare (sottoclasse) a quella generale (superclasse).

Diagramma delle classi: relazione gen-spec


Ereditarietà

L’ereditarietà puo’ essere singola o multipla; si ha ereditarietà multipla quando una classe è una specializzazione di (deriva da) due o più classi. Si distingue a volte tra ereditarietà di interfaccia ed ereditarietà di implementazione: nella prima si eredita solo la specifica e non l’implementazione. UML non ha una notazione specifica per questo, ma utilizza una linea tratteggiata che termina con una freccia per indicare l’ereditarietà di interfaccia.

Diagramma delle Classi: la relazione di contenimento

La relazione di contenimento o aggregazione (o legame tutto-parti) tra classi esprime un legame di tipo contenuto-contenitore, ovvero un legame tra un insieme e le sue parti. Un legame di contenumento è tipicamente espresso nei requisiti in linguaggio naturale da frasi del tipo:

  • “X è fatto di Y e Z”, “X consiste di Y e Z”, “X è/fa parte di Y”.
    • Es.: “Il motore fa parte dell’auto”; “l’auto è fatta di carrozzeria, motore, impianto elettrico, …”, “il pane è fatto di farina”.

Si distingue tra contenimento forte (o stretto) e contenimento debole (o lasco). Si ha contenimento forte quando la parte non perde la sua identità e riconoscibilità quando entra a far parte del tutto.

  • Es.: Il motore fa parte dell’auto

Si ha contenimento debole quando la parte perde la sua identità e riconoscibilità quando entra a far parte del tutto.

  • Es: Il pane (“tutto”) è fatto di farina (“parte”)

Diagramma delle Classi: la relazione di contenimento

Il contenimento forte è rappresentato in UML con un rombo pieno. quello debole con un rombo vuoto.

Contenitore debole o lasco. C classe contenitore, X classe contenuta

Contenitore debole o lasco. C classe contenitore, X classe contenuta

Contenitore forte o stretto. C3 classe contenitore, X classe contenuta

Contenitore forte o stretto. C3 classe contenitore, X classe contenuta


Diagramma delle Classi: contenimento debole

La relazione di contenimento debole indica l’indipendenza del ciclo di vita dell’oggetto contenuto dall’oggetto contenitore. L’oggetto contenuto potrà quindi esistere anche indipendentemente dal contenitore. Questo comporta la non responsabilità da parte del contenitore per la creazione e distruzione dell’oggetto contenuto.

Il contenimento debole si realizza introducendo nella classe contenitore C un puntatore all’oggetto x contenuto. Il costruttore di C riceve in ingresso il puntatore all’oggetto contenuto.

L’utente della classe C ha la responsabilità di: a) creare l’oggetto contenuto; b) definire ed inizializzare un puntatore ad esso; c) costruire l’oggetto contenitore passando il puntatore al contenuto. Il contenimento debole si puo’ realizzare in due modi: a) il contenitore (C) ha una variabile membro privata di tipo puntatore ad un oggetto di tipo contenuto (X); b) il contenitore (C) ha una variabile membro privata di tipo riferimento ad un oggetto di tipo contenuto (X). In entrambi i casi il contenitore dovrà definire un costruttore che riceva in input il puntatore (o il riferimento) all’oggetto contenuto.

Diagramma delle Classi: contenimento forte

La relazione di contenimento forte indica che l’oggetto contenuto non ha una vita propria ma esiste in quanto parte dell’oggetto contenitore. Pertanto l’oggetto contenitore é anche responsabile della costruzione e distruzione dell’oggetto contenuto. Il contenimento forte si realizza introducendo nella classe contenitore C una variabile membro x della classe contenuto X.

Attraverso il costruttore di C viene costruito un oggetto c e viene richiamato (anche implicitamente, a cura del compilatore) il costruttore della classe X per l’inizializzazione dell’oggetto x contenuto in c.

L’utente della classe C ha la responsabilità di istanziare un oggetto di tipo contenitore, richiamando il suo costruttore con tutti i valori di inizializzazione necessari sia all’inizializzazione del contenitore che del contenuto. Il contenimento forte si puo’ realizzare nel modo seguente: a) aggiungere una variabile membro alla classe contenitore del tipo della classe contenuto; b) implementare il costruttore del contenuto in modo da richiamare il costruttore del contenitore.

La relazione di contenimento debole: un esempio

Consideriamo l’esempio riportato in figura. 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 per cui avremo:


Diagramma delle Classi: la relazione di associazione

I legami tra classi che non siano di tipo gen-spec nè di contenimento sono detti associazioni. Un’associazione esprime un legame semantico tra le classi. Essa è caratterizzata da:

  • un nome: esprime il legame semantico tra le classi associate;
  • un eventuale ruolo giocato dalle parti associate;
  • la molteplicitàdell’associazione: esprime la cardinalità delle connessioni tra oggetti “istanze” delle classi associate e puo’ essere di tipo:
    • uno a uno;
    • uno a molti;
    • molti a molti;
  • la direzionalità (uni o bidirezionale): specifica il verso di percorrenza della relazione.

NB: una associazione è intrinsecamente adirezionale (se A è associato a B, B è associato ad A; es.: legame matrimoniale tra uomo e donna. Pertanto la direzionalità indica solo una navigabilità nel diagramma (se da A si vuole risalire a B o viceversa, o entrambi i casi), ed attribuisce alla classe origine del percorso la responsabilità di tenere traccia dell’associazione.

Diagramma delle classi: associazione


Diagramma delle Classi: la relazione di associazione

Un’associazione può essere dotata di una classe associativa. Una classe associativa è caratterizzata da attributi e operazioni che non sono in sè connessi ad una specifica classe tra quelle poste in relazione, ma sono connessi all’associazione in quanto tale.

  • Es: La data di matrimonio non è in sé un attributo del marito o della moglie, ma del legame matrimoniale

Le relazioni di associazione si traducono in C++ con una o più variabili membro di tipo puntatore alla classe associata (secondo la molteplicità dell’associazione).

Diagramma delle classi: classe associativa


Esempio di progettazione a oggetti

Requisiti informali di utenteSi vuole progettare un sistema informativo per la gestione dei dipendenti di una azienda. L’automazione si riferisce esclusivamente alla:

  • registrazione nuovi dipendenti di ogni tipo;
  • stampa degli stipendi mensili.

Esempio di progettazione a oggetti

Descrizione dei dipendenti dell’aziendaTutti i dipendenti dell’azienda sono caratterizzati all’interno di essa dal Nome e dal Cognome. I dipendenti dell’azienda sono di 4 “categorie”:

  • Dirigente;
  • Dipendente a “Cottimo”;
  • Dipendente “Ordinari”;
  • Agente di vendita.

Esempio di progettazione a oggetti

Lo stipendio dei dipendenti dipende dal ruolo che essi giocano nell’azienda.

  1. Il dirigente percepisce uno stipendio settimanale “fisso” indipendentemente dalle ore di lavoro effettuate o quant’altro.
  2. Il dipendente a “Cottimo” percepisce uno stipendio composto da una parte base ed una variabile: la parte variabile dipende dalla “quantità” di prodotti che in un mese il dipendente riesce a vendere; ogni pezzo venduto comporta un guadagno extra per il Dipendente.
  3. Il dipendente Ordinario percepisce uno stipendio dipendente dalle ore di lavoro effettuate. Un’ora di lavoro viene pagata diversamente a seconda del numero complessivo di ore : entro 40 ore lavorative ogni ora viene pagata ad un prezzo, le ore in “eccesso” rappresentano uno straordinario e sono pagate diversamente.
  4. L’Agente di vendita percepisce uno stipendio mensile basato unicamente sulla quantità di contratti di vendita che riesce a stipulare. Il prezzo per ogni contratto è il medesimo.

Casi d’uso per il sistema


Descrizione dei casi d’uso

Caso d’uso: registrare un nuovo dipendente.

  1. L’utente del sistema (il contabile) seleziona la procedura di Inserimento.
  2. Il sistema richiede il tipo di dipendente da inserire.
  3. L’utente sceglie il tipo di dipendente da inserire.
  4. In relazione al tipo di dipendente scelto, il sistema richiede tutte le informazioni necessarie.
  5. L’utente inserisce le informazioni.
  6. Il sistema registra il dipendente.

Descrizione dei casi d’uso

Caso d’uso: stampare stipendio mensile (per tutti i dipendenti)

  1. L’utente del sistema (il contabile) seleziona la procedura di Stampa mensile.
  2. Il sistema stampa le informazioni complete per ogni dipendente.

Object Oriented Analysis: individuazione delle classi

Da un’analisi testuale dei requisiti informali e dei casi d’uso presentati si individuano le classi di oggetti di dominio:

  1. Dirigente;
  2. Dipendente a “cottimo”;
  3. Dipendente ordinario;
  4. Agente di vendita.

Tutte queste classi condividono delle caratteristiche (attributi) comuni: il nome, il cognome e lo stipendio mensile (attributi).

OOA: individuazione delle classi


OOA: individuazione delle classi

Altre caratteristiche invece sono proprie di ogni classe.

  1. La classe Dirigente ha uno stipendio mensile calcolato a partire da uno stipendio settimanale dato.
  2. La classe Dipendente Ordinario è caratterizzata dal numero di ore lavorate e dalla retribuzione per ora (sia “normale” che “straordinaria”)
  3. La classe Agente di Vendita è caratterizzata dal numero di contratti o commissioni effettuati e dalla relativa retribuzione.
  4. La classe Dipendente a Cottimo è caratterizzata dal NumeroDiPezziVenduti e dalla loro retribuzione (PagaPerPezzo).

Diagramma delle classi

Se si raggruppano le caratteristiche comuni in una classe astratta “Dipendente” e si derivano da essa tutte le classi, il risultato è una gerarchia di classi. Ciò che specializza una qualsiasi classe è il ruolo giocato nell’azienda, mentre le caratteristiche proprie di ogni classe sono invece inserite nelle classi a cui appartengono.

Diagramma delle classi


Diagramma delle classi

Da un’analisi iniziale ci si accorge che il valore dell’attributo Stipendio Mensile può essere derivato (calcolato) a partire dal valore di altri attributi. Senza pensare all’algoritmo si intuisce che lo StipendioMensile dell’Agente di Vendita è derivabile dal NumeroDiContrattiEffettuati e dalla PagaPerContratto. Per rappresentare ciò, l’attributo StipendioMensile è stato specificato come “derivabile” (simbolo”/”). Tutti gli attributi sono stati specificati come “pubblici” (segno “+”). Per un qualsiasi oggetto sarà possibile leggere e scrivere il valore di tutti gli attributi escluso lo StipendioMensile che potrà essere solo letto.

Diagramma delle classi

Nel diagramma precedente non è stato rispettato il principio dell’information hiding che consiste nel nascondere le strutture dati e nel dotare le classi di metodiper l’accesso. Rivisitando il precedente diagramma delle classi in questi termini si otterebbe un nuovo diagramma le cui modifiche indicano che:

  1. E’ possibile leggere l’identità (Nome e Cognome) solo tramite l’apposito metodo; in altre parole il nome ed il cognome di un dipendente non può essere variato. Esso sarà assegnato alla costruzione.
  2. E’ possibile incrementare le Ore Lavorate, i Pezzi Venduti e i Contratti Stipulati, man mano che si presenta l’evenienza. Non è più possibile fare la stessa cosa agendo sugli attributi delle classi, che diventano privati alla classe.
  3. E’ possibile, in un qualsiasi momento, richiedere il calcolo del Salario Mensile tramite il metodo apposito (l’attributo derivato si “trasforma naturalmente” in un metodo).

Diagramma delle classi


Object Oriented Design

Quest’ultimo diagramma (o quello precedente a seconda dei casi) potrebbe essere sufficiente per quel che riguarda la modellazione statica del dominio considerato. A questo punto occorre entrare nel dominio della soluzione. Le problematiche da considerare sono: a) Come condurre le procedure descritte nei casi d’uso? b) Come interfacciarsi con l’utente? c) Come realizzare la persistenza degli oggetti? La soluzione a tali problemi comporterà l’aggiunta di nuove classi e la ridefinizione di quelle trovate. Pertanto sia il diagramma delle classi che i diagrammi di interazione prodotti devono essere rivisitati. A valle di ciò si potrebbe dare una architettura al sistema in termini di package. Ovviamente per sistemi poco complessi questa ultima fase può essere superflua.

Object Oriented Design

a) Come condurre le procedure descritte nei casi d’uso?
In OO è molto utilizzata la metafora di Oggetto Coordinatore delle Procedure. Un oggetto Coordinatore si occupa del coordinamento dello scambio di messaggi tra gli oggetti di dominio e non (interfacce, servizi di persistenza…) per il compimento delle procedure richieste. Nel nostro caso si può pensare di racchiudere tutta la logica di controllo necessaria al compimento della procedura di “Registrazione di un nuovo dipendente” nel comportamento di un apposito oggetto “CoordinatoreRegistrazione”. Esso coordinerà tutte le operazioni necessarie (ad esempio):

  1. la creazione di un oggetto di interfaccia per la raccolta delle informazioni sul dipendente;
  2. il recupero di tali informazioni;
  3. la creazione di un oggetto di tipo dipendente;
  4. la sua memorizzazione tramite, ad esempio, l’uso di un oggetto che offra il servizio di persistenza.

Object Oriented Design

b) Come interfacciarsi con l’utente.
L’interfacciamento con l’utente può sicuramente essere realizzata tramite l’uso di oggetti grafici messi a disposizione dai vari ambienti di sviluppo. E’ possibile usare ad esempio oggetti grafici offerti dalle Classi di Microsoft Foundation Class o similari. Per questo esempio l’interfaccia può essere realizzata tramite semplici oggetti, costruiti ad hoc, che richiedano all’utente l’inserimento delle informazioni. Ad esempio possiamo avere una classe MainWindow che ha la responsabilità di acquisire una tra le tre scelte procedurali messi a disposizione dall’utente (una sorta di menù). Ed ancora una finestra InsertionWindow per l’inserimento delle informazioni necessarie alla creazione di nuovi impiegati e così via.

I materiali di supporto della lezione

Testo: Da C++ a UML:

Capitolo 32

Capitolo 33 §1 , §2.1 , §2.2

Capitolo 34 §§ 1, 2, 3, 4, 5

Capitolo 35

  • Contenuti protetti da Creative Commons
  • Feed RSS
  • Condividi su FriendFeed
  • Condividi su Facebook
  • Segnala su Twitter
  • Condividi su LinkedIn
Progetto "Campus Virtuale" dell'Università degli Studi di Napoli Federico II, realizzato con il cofinanziamento dell'Unione europea. Asse V - Società dell'informazione - Obiettivo Operativo 5.1 e-Government ed e-Inclusion

Fatal error: Call to undefined function federicaDebug() in /usr/local/apache/htdocs/html/footer.php on line 93