Sei sulla pagina 1di 116

Politecnico di Milano

Anno Accademico 2010/2011

Ingegneria del Software 2


Corso della Prof.ssa Elisabetta Di Nitto
Stefano Invernizzi

Facolt di Ingegneria dellInformazione

Corso di Laurea Magistrale in Ingegneria Informatica


Ingegneria del Software 2 Indice

Indice
Capitolo 1: Introduzione ____________________________________________________________________________ 5
Lingegneria del software: definizioni __________________________________________________________________________ 5
Lingegneria del software e le altre discipline ingegneristiche _______________________________________________________ 5
Ingegneria del software e programmazione _____________________________________________________________________ 7
Cenni alla storia dellingegneria del software ____________________________________________________________________ 7
Aspetti fondamentali dellingegneria del software ________________________________________________________________ 8

Capitolo 2: Prodotto e processo SW __________________________________________________________________ 9


Il processo ed il prodotto ____________________________________________________________________________________ 9
Le qualit del software ______________________________________________________________________________________ 9
Le qualit del processo _____________________________________________________________________________________ 11

Capitolo 3: Cicli di vita del software _________________________________________________________________ 12


Cicli di vita del software ____________________________________________________________________________________ 12
Il modello a cascata _______________________________________________________________________________________ 12
Prototipazione ___________________________________________________________________________________________ 15
Rilascio incrementale (incremental delivery) ____________________________________________________________________ 16
Il modello a spirale ________________________________________________________________________________________ 16
Sviluppo basato sui componenti (component-based development) __________________________________________________ 17
Rapid Application Development (RAD) ________________________________________________________________________ 18
Extreme Programming (XP) _________________________________________________________________________________ 19
Rational Unified Process (RUP)_______________________________________________________________________________ 21
Sincronizzazione e stabilizzazione (Sync-and-stabilize) ____________________________________________________________ 22
Lo sviluppo open source ____________________________________________________________________________________ 24

Capitolo 4: Il Capacity Maturity Model _______________________________________________________________ 25


Introduzione al Capacity Maturity Model (CMM) ________________________________________________________________ 25
Valutazione della maturit di unorganizzazione ________________________________________________________________ 26
Standard ISO 9000 ________________________________________________________________________________________ 30

Capitolo 5: Ingegneria dei requisiti __________________________________________________________________ 31


Lingegneria dei requisiti ___________________________________________________________________________________ 31
I System Context Diagrams _________________________________________________________________________________ 34
Gli obiettivi (goal) e le asserzioni _____________________________________________________________________________ 35
Il documento SRS _________________________________________________________________________________________ 36
Osservazioni _____________________________________________________________________________________________ 40
Come derivare i requisiti dagli obiettivi? _______________________________________________________________________ 40
La gestione del processo____________________________________________________________________________________ 42

3
Indice Ingegneria del Software 2

Capitolo 6: UML _________________________________________________________________________________ 44


Il concetto di modello ______________________________________________________________________________________ 44
I modelli dei sistemi software ________________________________________________________________________________ 45
UML: concetti generali _____________________________________________________________________________________ 45
Come utilizzare UML? ______________________________________________________________________________________ 46
I class diagram ___________________________________________________________________________________________ 46
Object diagram ___________________________________________________________________________________________ 52
Use case diagram _________________________________________________________________________________________ 52
Sequence diagram ________________________________________________________________________________________ 58
Activity diagram __________________________________________________________________________________________ 60
Component diagram _______________________________________________________________________________________ 64
Statechart _______________________________________________________________________________________________ 66
Utilizzare lUML per modellare i requisiti _______________________________________________________________________ 69

Capitolo 7: Specifica ______________________________________________________________________________ 71


Il concetto di specifica _____________________________________________________________________________________ 71
Introduzione ad Alloy ______________________________________________________________________________________ 72
La sintassi di Alloy _________________________________________________________________________________________ 75
Un esempio di utilizzo di Alloy _______________________________________________________________________________ 81
Osservazioni conclusive su Alloy______________________________________________________________________________ 82

Capitolo 8: Software design ________________________________________________________________________ 83


Software design & software architecture ______________________________________________________________________ 83
Il processo di design _______________________________________________________________________________________ 85
Gli stili architetturali _______________________________________________________________________________________ 86
I design pattern ___________________________________________________________________________________________ 96
I pattern architetturali ____________________________________________________________________________________ 101

Capitolo 9: Verifica e validazione __________________________________________________________________ 102


Introduzione e terminologia ________________________________________________________________________________ 102
Tempi e modalit della fase di verifica e validazione ____________________________________________________________ 103
Il processo di verifica e validazione __________________________________________________________________________ 104
Approcci alla verifica e alla validazione _______________________________________________________________________ 105
Il testing: introduzione ____________________________________________________________________________________ 108
Confronto tra testing strutturale e testing funzionale ___________________________________________________________ 110
Osservazioni varie sulla fase di test __________________________________________________________________________ 115

4
Ingegneria del Software 2 Capitolo 1: Introduzione

Capitolo 1: Introduzione
Lingegneria del software: definizioni
Possiamo dare diverse definizioni del termine Ingegneria del Software:

Definizione 1
Lingegneria del software il settore dellinformatica che si occupa della creazione di sistemi software talmente grandi
o complessi da dover essere realizzati da una o pi squadre di ingegneri. Tali progetti hanno una vita lunga e vengono
rilasciati in versioni diverse tra loro, e sono inoltre soggetti a modifiche che hanno lo scopo di correggere errori in essi
presenti o di migliorare o estendere le funzionalit del software stesso.

Definizione 2
Lingegneria del software lapproccio sistematico alle diverse fasi di vita del software, che includono lo sviluppo, la
fase di operation (messa in esecuzione del software), la manutenzione, il deployment (installazione del software), la
fase di training di coloro che utilizzeranno il software ed il ritiro del software stesso (tale fase richiede la messa in atto
di operazioni che consentano di lasciare in uno stato consistente lambiente in cui il software operava).

Definizione 3
Lingegneria del software una disciplina metodologica e manageriale che ha a che fare con la produzione sistematica
e la manutenzione di prodotti software, in modo che siano sviluppati e mantenuti in modo controllato e anticipato.

Definizione 4
Lingegneria del software una disciplina che ricerca soluzioni ai problemi che siano efficaci dal punto di vista dei
costi, applicando la conoscenza scientifica alla realizzazione di prodotti software al servizio delluomo.

Questa definizione mette in evidenza una serie di concetti base legati in generale allingegneria: lintenzione di
risolvere dei problemi pratici, la ricerca di soluzioni vantaggiose dal punto di vista economico, luso della conoscenza
scientifica, lobiettivo di costruire qualcosa, lintento di realizzare qualcosa che sia utile per luomo.

Lingegneria del software e le altre discipline ingegneristiche


Compiti ingegneristici
I compiti di un ingegnere possono essere suddivisi in due categorie:

Compiti di routine (programmazione di routine)


I compiti di routine includono la risoluzione di problemi famigliari, che pu avvenire utilizzando delle soluzioni
precedentemente realizzate e adottate. La programmazione di routine ha perci a che fare con problemi noti e di
conseguenza ha tempi e costi facilmente prevedibili.

Compiti innovativi (design innovativo)


I compiti innovativi di un ingegnere riguardano invece lo sviluppo di soluzioni nuove in risposta a problemi che
non sono famigliari o noti.

Nellingegneria del software molte attivit riguardano la categoria del design innovativo: nellingegneria del software
infatti non viene catturata e gestita lorganizzazione di ci che gi noto.

Tutte le discipline ingegneristiche mature prevedono che le conoscenze di design vengano conservate, organizzate e
condivise. Lingegneria del software si pone lobiettivo di fare questo anche nel campo software, che unarea
ingegneristica ancora non completamente matura.

5
Capitolo 1: Introduzione Ingegneria del Software 2

Evoluzione delle pratiche dellingegneria del software


La figura seguente ritrae in maniera schematica levoluzione prevista nellingegneria del software, a partire da
soluzioni ad-hoc (di design innovativo), fino ad arrivare alle pratiche ottimizzate, diventate ormai di routine:

Soluzioni ad-hoc

Nuovi problemi
Euristiche

Modelli e teorie

Codifica di procedure
sistematiche
Miglioramento delle
pratiche di routine

Figura 1: evoluzione delle pratiche dellingegneria del software

Differenze rispetto alle discipline ingegneristiche tradizionali


La precedente figura mette in evidenza la presenza di cicli, assenti invece nellevoluzione delle pratiche adottate dalle
altre discipline ingegneristiche (come ad esempio lingegneria civile). Tale caratteristica dovuta al fatto che il
contesto nel quale opera lIngegneria del software sempre diverso.

Si osserva inoltre che lingegneria del software viene ancora oggi praticata ed insegnata in maniera non sistematica e
che risulta ancora meno stabile ed organizzata rispetto alle discipline ingegneristiche tradizionali: al momento, non
esistono degli standard e delle specifiche per il design del software.

Possiamo perci affermare che, se da un lato vero che lingegneria del software considerata a tutti gli effetti una
disciplina ingegneristica ed ha molti punti in comune con le altre discipline di tale categoria, vero anche che ci sono
molti punti di divergenza, che possiamo mettere in evidenza con un banale esempio: mentre i ponti vengono
normalmente costruiti in tempo, entro i range di budget e perfettamente funzionanti (cio non cadono), spesso il
software viene costruito fuori dai tempi e dai budget prefissati, e pu presentare difetti pi o meno gravi al momento
del rilascio. Ci dovuto proprio alle differenze che andiamo ora ad elencare:

1. Le ingegnerie tradizionali prevedono una fase di design estremamente dettagliata, nella quale si valutano diverse
alternative mediante luso di modelli; dopo la scelta di un certo design, tale scelta viene congelata e la flessibilit
nel cambiamento di specifiche pressoch nulla; viceversa, nellingegneria del software si ha spesso a che fare
con applicazioni che riguardano i processi di business, i quali richiedono continue evoluzioni, perci non
possibile congelare le specifiche iniziali.
2. Discipline come lingegneria civile hanno ormai circa 3 millenni di vita, mentre lingegneria del software una
disciplina molto recente. Di conseguenza, le altre discipline possono contare su una larga base di conoscenze,
sulla base delle quali sono state costruite nel tempo delle teorie e delle metodologie, grazie anche allanalisi dei
fallimenti che storicamente si sono verificati; lingegneria del software non pu invece contare su tutto questo.

6
Ingegneria del Software 2 Capitolo 1: Introduzione

Ingegneria del software e programmazione


Le competenze che un ingegnere del software deve possedere sono ben diverse da quelle tipiche di un buon
programmatore: un programmatore sviluppa in maniera completa un programma, lavorando in maniera individuale su
un certo insieme di specifiche note. Un ingegnere del software deve invece essere in grado di identificare i requisiti e,
a partire da questi, sviluppare le specifiche, molto spesso lavorando allinterno di un team. In tal modo riesce a
progettare un componente che funzioner solo se combinato con altri componenti. Inoltre, lo sviluppo e la
manutenzione del componente vengono affidati ad altre persone, e il componente potr essere utilizzato allinterno di
pi sistemi diversi tra loro. Possiamo perci fare le seguenti affermazioni:

1. Siccome il software deve interagire con lambiente esterno, lingegnere del software deve essere in grado di
capire e analizzare tale ambiente. Dallambiente esterno verranno tratti i requisiti del software che verr
realizzato.
2. Dai requisiti ottenuti, occorre essere in grado di derivare una serie di specifiche dellapplicazione.
3. La conoscenza del dominio riveste un ruolo fondamentale nello sviluppo: se un ingegnere del software svolge la
propria attivit di design basandosi su assunzioni sbagliate riguardanti il dominio applicativo, potrebbero sorgere
dei veri e propri disastri.

Da questo consegue che le competenze dellingegnere del software sono le seguenti:

1. Competenze tecniche 4. Capacit di organizzazione dellimpresa


2. Competenze di gestione del progetto 5. Capacit di interazione con altre culture
3. Competenze cognitive 6. Conoscenze di dominio

Cenni alla storia dellingegneria del software


Larte della programmazione
Inizialmente il software veniva considerato come unarte (larte della programmazione): gli sviluppatori realizzavano
in maniera individuale delle applicazioni, solitamente di dimensioni piuttosto ridotte, utilizzando linguaggi di basso
livello e dovendo rispettare vincoli piuttosto stringenti di memoria e di prestazioni dei calcolatori. Tali applicazioni
avevano per utenti gli stessi sviluppatori che le realizzavano, venivano usate soprattutto per la risoluzione di problemi
matematici ed avevano un tempo di vita piuttosto breve: lesempio tipico di programmi di questo tipo rappresentato
dallapplicazione che un ricercatore poteva sviluppare ad-hoc per la risoluzione di un certo problema; nel momento in
cui si fosse presentato un nuovo problema, il ricercatore avrebbe provveduto a scrivere una nuova applicazione,
buttando via quella precedentemente realizzata.

La programmazione come artigianato


Quando linformatica ha trovato applicazione anche nella gestione delle informazioni, soprattutto con la nascita dei
sistemi informativi aziendali, le esigenze del nuovo software sono cambiate fortemente: da questo momento in poi, il
software ha avuto utenti ben distinti dagli sviluppatori, e sono nate delle vere e proprie software house.
Parallelamente, sono stati compiuti importanti passi in avanti da un punto di vista tecnologico, con la nascita di
linguaggi ad alto livello e il miglioramento delle caratteristiche fisiche dei calcolatori.

Tuttavia, i primi progetti software di grandi dimensioni si rivelarono dei veri e propri insuccessi, a causa di problemi
nella gestione del denaro e del tempo, errori nelle interazioni umane e gravi difetti nelle specifiche del software
stesso. In alcune situazioni estreme, tali problemi portarono anche alla morte di diverse persone, come accadde ad
esempio nel progetto Therac-25: unazienda sanitaria aveva richiesto la realizzazione di un software per la gestione di
una macchina di radioterapia, ma un fraintendimento tra coloro che realizzarono la macchina hardware e coloro che si
occuparono di sviluppare il software port alla morte di almeno 4 persone, vittime di una forte sovraesposizione alle
radiazioni che avrebbero dovuto curarle dal cancro. Nello specifico, lincomprensione era dovuta al fatto che nel
progettare il software si ipotizz che tutta una serie di controlli fossero svolti direttamente dallhardware, che invece li
aveva demandati allapplicazione.

7
Capitolo 1: Introduzione Ingegneria del Software 2

Lingegnerizzazione del processo di sviluppo del software


Tali fallimenti resero evidente la necessit di ingegnerizzare il processo di creazione del software, tramite:

1. La realizzazione di metodi e standard per lo sviluppo del software


2. La messa in atto di attivit di pianificazione e di management
3. Lautomazione del processo
4. Lintroduzione di qualit oggettive e verificabili
5. La divisione del software in componenti

Si passati ad una vera e propria industria. Il termine software engineering fu ufficialmente coniato nellottobre 1968.

da sottolineare che lingegneria del software si occupa solamente delle sviluppo di sistemi di grandi dimensioni e con
caratteristiche critiche (cio nei quali un malfunzionamento genera dei rischi per la vita umana o delle perdite,
soprattutto di carattere economico). Lutilizzo dellapproccio ingegneristico dovrebbe quindi migliorare la qualit dello
sviluppo di questo tipo di applicazioni.

Ad oggi il settore del software ha assunto una grande importanza: nel 1996 il software divent il terzo settore
industriale dopo quello automobilistico e quello dellelettronica; nonostante ci, occorre ricordare che dopo i primi
anni 2000 ci fu un certo ridimensionamento del settore.

Uno dei compiti fondamentali dellingegneria del software quello di comprendere e di gestire i cicli di vita del
software (software lifecycle), ovvero il flusso di fasi che porta dal problema al prodotto finale, comprendendo anche
tutte le attivit che ne consentono levoluzione, fino al momento del ritiro. bene per sottolineare che non tutti i
progetti software arrivano ad essere completati: circa il 30% dei progetti vengono annullati prima di essere portati a
termine. Inoltre, pi del 53% dei progetti software ha costi che sfiorano il doppio rispetto alle stime iniziali.

Lingegneria del software cerca quindi di limitare questi fallimenti e questi inconvenienti nello sviluppo del prodotto
software stesso.

Aspetti fondamentali dellingegneria del software


Gli aspetti fondamentali dellingegneria del software sono:

1. Rigore e formalit
2. Separazione degli ambiti di interesse
3. Modularit
4. Astrazione
5. Anticipazione dei cambiamenti
6. Generalit
7. Incrementalit

8
Ingegneria del Software 2 Capitolo 2: Prodotto e processo SW

Capitolo 2: Prodotto e processo SW


Il processo ed il prodotto
Il concetto di prodotto ed il concetto di processo
Lobiettivo di un ingegnere del software quello di sviluppare dei prodotti software, cio delle applicazioni (il
prodotto perci, come nel linguaggio quotidiano, il risultato finale). La modalit attraverso la quale otteniamo tale
prodotto prende il nome di processo. Limportanza del processo fondamentale, cos come quella del prodotto;
possiamo inoltre affermare che sia il processo che il prodotto hanno una serie di qualit e, come si pu facilmente
comprendere:

1. Le qualit del prodotto dipendono strettamente da quelle del processo: se il processo confusionario o casuale,
molto probabilmente il prodotto ottenuto sar di bassa qualit.
2. Le qualit interne del software (ovvero quelle che riguardano la sua struttura) influenzano fortemente le qualit
esterne (quelle legate al suo funzionamento).

Differenze tra i prodotti tradizionali ed il software


Il prodotto software, come possiamo facilmente comprendere, presenta forti differenze rispetto alle tipologie
tradizionali di prodotti:

1. Si tratta di un prodotto intangibile, perci difficile da valutare e da descrivere;


2. malleabile, ovvero si evolve continuamente nel tempo;
3. Lo sviluppo del prodotto software human intensive, ovvero richiede unattivit creativa delluomo durante la
sua realizzazione. Gli altri prodotti prevedono invece unattivit creativa solo in un momento iniziale, mentre la
creazione finale del prodotto avviene solitamente in maniera automatizzata.

Le qualit del software


Le qualit principali del software
Le principali qualit del software sono:

1. Correttezza 6. Usabilit
2. Affidabilit 7. Manutenibilit
3. Robustezza 8. Riusabilit
4. Prestazioni 9. Portabilit
5. Scalabilit 10. Interoperabilit
Vediamo ora di analizzarle una dopo laltra.

Correttezza (correctness)
Il software deve essere corretto, ovvero deve funzionare secondo le aspettative. Pi formalmente, il software
corretto se soddisfa le specifiche.

Se le specifiche sono indicate in maniera formale, la correttezza pu essere definita in maniera formale e pu essere
provata come un teorema (utilizzando strumenti noti come theorem-prover) oppure, al contrario, si pu dimostrare
che il software non corretto mediante lindividuazione di controesempi. Questo possibile perch i programmi sono
degli oggetti formali: il loro significato definito in modo formale e rigoroso, il compilatore trasforma quindi in
maniera univoca il programma sorgente, e non si ha alcuna ambiguit nella definizione del programma stesso.

In ogni caso, lapproccio migliore quello che prevede di cercare di realizzare un software corretto a priori, attraverso
ladozione di un processo adeguato e luso di strumenti adeguati (es.: linguaggi ad alto livello). Per fare ci per
necessario ancora una volta che le specifiche vengano definite in maniera formale.

9
Capitolo 2: Prodotto e processo SW Ingegneria del Software 2

La correttezza presenta per alcuni importanti limiti:

1. Tutto ci che stato finora detto vale a patto che le specifiche siano esatte e complete: infatti possibile che le
specifiche non catturino tutti i requisiti dellutente, o che siano fondate su requisiti errati, e perci un software
corretto (cio che soddisfa tutte le specifche) potrebbe anche non soddisfare lutente.
2. Inoltre, la correttezza una qualit assoluta: non esiste un grado di correttezza, ma possibile solamente dire
se un software corretto oppure no.

Affidabilit (reliablity)
In maniera informale, un software affidabile quando lutente si pu fidare del software stesso, ovvero questultimo
non creer danni allutente che lo usa.

Da un punto di vista matematico, laffidabilit pu essere definita come la probabilit di assenza di comportamenti
errati in un certo periodo di tempo.

Se le specifiche sono corrette (cio rispecchiano tutti i requisiti attesi dagli utenti), tutto il software corretto anche
affidabile, ma non vale il viceversa: un software affidabile potrebbe anche non essere corretto). Si ricordi per che le
specifiche possono anche essere sbagliate. Proprio in virt del fatto che laffidabilit una richiesta pi debole
rispetto alla correttezza, spesso si d una maggiore priorit allaffidabilit del software rispetto alla sua correttezza.

Robustezza (robustness)
Il software si dice robusto se il suo comportamento ragionevole anche in presenza di circostanze impreviste. Questo
significa che il software deve comportarsi in maniera ragionevole anche di fronte a guasti dellhardware, input
scorretti, o situazioni analoghe.

Prestazioni (performance)
Il software ha delle buone prestazioni se usa in maniera efficiente le risorse, come ad esempio la memoria, il
processore e le interfacce di comunicazione.

Le prestazioni possono essere valutate in maniera oggettiva, attraverso strumenti diversi, come lanalisi di
complessit, e la valutazione delle performance per mezzo di modelli o simulazioni. Le performance possono
influenzare lusabilit e la scalabilit e possono dipendere da aspetti tecnologici.

Scalabilit (scalability)
La scalabilit del software la sua capacit di soddisfare la crescita di richieste degradando le prestazioni in maniera
ragionevole, senza incorrere in situazioni instabili o di crash. Generalmente, si considera ragionevole il degrado di
prestazioni quando esso avviene in maniera lineare.

Naturalmente, scalabilit e performance sono correlate.

Usabilita (usability)
Un software viene definito usabile quando gli utenti che ci si aspetta dovranno utilizzarlo considerano semplice
lutilizzo del software stesso. I sistemi usabili sono detti talvolta anche ergonomici o user-friendly.

Per valutare lusabilit del software quindi fondamentale definire in maniera accurata quelli che saranno gli utenti
che ci si aspetta che useranno lapplicazione.

Nonostante questo, la valutazione dellusabilit rimane piuttosto soggettiva e difficile da valutare. Una modalit tipica
mediante la quale si pu valutare lusabilit consiste nel far provare il sistema o il prototipo del sistema stesso ad un
certo insieme di utenti appartenenti al gruppo degli expected-users.

Lusabilit dipende principalmente dallinterfaccia con lutente (testuale o grafica).

10
Ingegneria del Software 2 Capitolo 2: Prodotto e processo SW

Manutenibilit (mainainability)
La manutenibilit la capacit del software di poter essere trasformato, mediante la correzione di errori, lo sviluppo
di evoluzioni del software stesso, e la realizzazione di cambiamenti in generale.

Affinch il software abbia la qualit di manutenibilit, necessario che sia dotato di unarchitettura adatta e che il
codice risulti facilmente comprensibile.

Riusabilit (reusability)
La riusabilit del software consiste nella possibilit di riutilizzare delle porzioni del software in contesti diversi. Per
certi versi quindi simile alla manutenibilit, ma in questo caso si fa riferimento ai componenti: un software
mantenibile generalmente anche di facile riuso.

Portabilit (portability)
La portabilit del software la capacit del software stesso di adattarsi a diversi ambienti operativi. Per fare ci
talvolta necessario modificare il software stesso, e per tale ragione si tratta di unaltra qualit piuttosto simile alla
manutenibilit.

Interoperabilit (interoperability)
Linteroperabilit la capacit di coesistenza e di cooperazione del progetto software con le altre applicazioni.

Le qualit del processo


Le qualit principali del processo
Le principali qualit del processo sono:

1. Produttivit
2. Tempestivit

Analizziamole ora nel dettaglio.

Produttivit (productivity)
La produttivit del processo generalmente calcolata come il rapporto tra le unit di prodotti ottenute e lo sforzo
affrontato per ottenerle. Nel caso dellingegneria del software, le unit di sforzo sono generalmente considerate come
i mesi-persona necessari per la realizzazione del prodotto, mentre le unit di prodotto ottenute possono essere
valutate come le linee di codice scritte, oppure le funzionalit sviluppate.

Tempestivit (timeliness)
La tempestivit labilit del processo di rispondere ai cambiamenti delle richieste in una maniera puntuale e rapida.
Tale caratteristica importante perch le esigenze del cliente crescono in continuazione, e perci il processo deve
essere in grado di adattarsi ad esse, tendendo a raggiungere le richieste stesse.

Figura 2: crescita delle richieste degli utenti e delle funzionalit implementate dal sistema

11
Capitolo 3: Cicli di vita del software Ingegneria del Software 2

Capitolo 3: Cicli di vita del software


Cicli di vita del software
Modelli di cicli di vita del software
L'espressione ciclo di vita del software si riferisce al modo in cui una metodologia di sviluppo o un modello di processo
scompongono l'attivit di realizzazione di prodotti software in sottoattivit fra loro coordinate, il cui risultato finale il
prodotto stesso e tutta la documentazione a esso associata. Nel corso degli anni sono stati sviluppati diversi modelli di
ciclo di vita del software.

Il modello code&fix
I primi sviluppatori solitamente non adottavano alcun modello di riferimento, ma procedevano semplicemente
secondo lapproccio code&fix, che prevede semplicemente di codificare in maniera pi o meno istintiva, provvedendo
poi a correggere il codice in caso di problemi.

Naturalmente per quando si ha un committente diverso dallutilizzatore lapproccio code&fix non pu essere
considerato sufficiente.

Il modello a cascata
Obiettivi del modello a cascata
Il modello tradizionale di ciclo di vita del software il waterfall model o modello a cascata, nel quale vengono
identificate tutte le fasi e le attivit del processo di sviluppo del software e nel quale si impone un avanzamento
lineare da una fase a quella successiva. Il modello non prevede quindi alcun tipo di ciclo: il ritorno ad una fase
precedente considerato dannoso, e si crede invece che sia opportuno pianificare e controllare tutto sin dallinizio.

Unaltra importante caratteristica di questo modello la standardizzazione di tutti i prodotti risultanti da ciascuna
delle singole fasi del processo. Si pu perci affermare che lobiettivo principale di questo modello era quello di
considerare il software come una qualsiasi altra attivit di produzione industriale.

Schema del modello a cascata


Le versioni esistenti del modello a cascata sono in realt diverse. Di seguito riportato lo schema relativo ad una di
queste:

Studio di Analisi dei requisiti Codifica e Integrazione e


Design Deployment Manutenzione
fattibilit e specifica unit test test di sistema

Fasi alte Fasi basse

Figura 3: ciclo di vita del software secondo il modello a cascata

Analizziamo singolarmente le singole fasi di tale ciclo di vita del software.

12
Ingegneria del Software 2 Capitolo 3: Cicli di vita del software

Studio di fattibilit (feasibility study)


Lo studio di fattibilit comprende le seguenti attivit:

1. Analisi del rapporto costo / benefici.


2. Determinare se il caso di avviare il progetto oppure no (considerando ad esempio la possibilit di acquistare il
prodotto finale gi realizzato da altri), valutando le diverse alternative possibili e individuando le risorse
necessarie.

Al termine della fase viene prodotto il documento dello studio di fattibilit, che contiene una descrizione dei problemi
preliminari, un insieme di scenari che descrivano le possibili soluzioni, i costi e la pianificazione nelle diverse
alternative individuate.

Analisi dei requisiti e specifica


Durante la fase di analisi dei requisiti e specifica si analizza il dominio nel quale lapplicazione dovr operare,
identificando cos tutti i requisiti che lo caratterizzano. Da tali requisiti si derivano poi la specifiche del software,
mediante linterazione con lutente. Ci richiede naturalmente una piena comprensione delle propriet del dominio in
analisi.

Il documento che viene prodotto al termine della fase noto come RASD (Requirements Analysis and Specification
Document), nel quale necessario specificare chi utilizzer il sistema (who), il motivo per il quale il sistema viene
sviluppato e per il quale lutente dovrebbe usarlo (why), cosa il sistema fornir (what), dove il sistema verr usato
(where) e quando e per quanto tempo potr essere usato (when).

necessario che il RASD risulti preciso, completo e consistente. Tale documento potrebbe includere anche un
manuale preliminare per lutente e una pianificazione dei test per il sistema.

Design
Nella fase di design viene definita larchitettura del software, individuando quali sono i componenti (moduli) che lo
costituiscono, quali sono le relazioni tra i componenti e quali interazioni avvengono tra essi.

Lobiettivo quello di consentire uno sviluppo concorrente, separando le responsabilit: in questo modo i singoli
componenti verranno realizzati indipendentemente luno dagli altri.

Il documento prodotto al termine della fase il documento di design.

Codifica e unit test


In questa fase ogni singolo modulo viene implementato utilizzando il linguaggio di programmazione scelto. Ogni
modulo viene testato isolatamente da colui che ha sviluppato il modulo stesso (si parla per questo di unit test, ovvero
test dellunit). Ogni modulo includer inoltre la propria documentazione.

Integrazione e test di sistema


I moduli vengono integrati in un sistema (o in sottosistemi), e si procede con lattivit di test del sistema (o dei
sottosistemi). Questa fase e la precedente possono essere integrate in uno schema di implementazione incrementale.

Il test del sistema generale, necessario per verificare le propriet di insieme, viene talvolta diviso in due fasi: alfa test e
beta test.

Deployment
La fase di deployment ha lobiettivo di distribuire lapplicazione e gestire le diverse installazioni e configurazioni dal
lato client.

13
Capitolo 3: Cicli di vita del software Ingegneria del Software 2

Manutenzione
Tutti i cambiamenti che seguono la messa in funzione del sistema appartengono alla fase di manutenzione. Il termine
in realt piuttosto improprio: in realt infatti il software non si usura, e se si verificano dei malfunzionamenti, i
problemi che ne sono alla base erano esistenti sin dallinizio.

Questa fase particolarmente critica, in quanto si stima che oltre il 50% dei costi totali per lo sviluppo di un software
riguardino la manutenzione (secondo alcuni studi tale cifra raggiunge addirittura l80%). I tipi di manutenzione sono:

Manutenzione correttiva
Consiste nel riparare i difetti che vengono individuati allinterno del software. circa il 20% del totale e i suoi
costi sono a carico di chi sviluppa il software.

Si noti che in generale gli errori che riguardano le prime fasi del processo di sviluppo vengono individuati molto
tardi, e che il costo di rimozione degli errori aumenta man mano che passa il tempo (eliminare errori da sistemi
maturi ha costi molto superiori rispetto alleliminazione di errori da sistemi nuovi).

Inoltre, molto spesso la rimozione di errori comporta lintroduzione di nuovi errori, perci i sistemi di grandi
dimensioni tendono a stabilizzare il loro numero di errori attorno ad un certo numero che rimane pi o meno
costante, dopo un certo periodo di tempo dal loro rilascio. Si stima che il software che viene rilasciato contenga
mediamente circa il 10% degli errori che sono stati individuati durante la fase di testing. La fase di testing infatti
copre tipicamente solo il 50% circa del codice.

Manutenzione evolutiva
La manutenzione adattativa, perfettiva e preventiva possono essere considerate insieme come categorie di
manutenzione di tipo evolutivo. Levoluzione, pu essere necessaria per cambiamenti del contesto nel quale
lapplicazione opera, per cambiamenti dei requisiti (nuove richieste degli utenti, che emergono solo dopo
lintroduzione del sistema), per errori nelle specifiche o perch alcuni requisiti non erano noti inizialmente.

Per gestire la manutenzione di tipo evolutivo necessario innanzitutto tenere conto dei cambiamenti facilmente
prevedibili, sin dalle fasi iniziali di sviluppo del software. Inoltre, il software deve essere realizzato con
unarchitettura che faciliti i cambiamenti futuri, in modo economico e affidabile: questo uno dei principali
obiettivi dellingegneria del software. Il costo della manutenzione evolutiva a carico del committente.

a) Manutenzione adattativa: consiste nelladattare il software ai cambiamenti dellambiente (lhardware, i


sistemi operativi, le regole di business, le leggi, ). Un esempio stato il dover adattare le applicazioni
allintroduzione delleuro. circa il 20% del totale.

b) Manutenzione perfettiva: consiste nel soddisfare requisiti nuovi o modificati da parte degli utenti. circa il
50% del totale.

c) Manutenzione preventiva: consiste nel mettere in atto azioni che mirino ad aumentare la manutenibilit del
software. circa il 5% del totale.

Talvolta la distinzione tra manutenzione evolutiva e correttiva potrebbe non essere netta ed evidente, perch le
specifiche sono spesso ambigue e incomplete. Questo causa frequenti problemi, perch le specifiche sono parte dei
contratti tra i clienti e gli sviluppatori. Congelare troppo presto le specifiche potrebbe rivelarsi cos un problema,
perch probabilmente le specifiche risulteranno inizialmente sbagliate.

I cambiamenti del software, secondo le buone pratiche dellingegneria, devono sempre essere prima messi in atto
modificando il design, e solo in seguito devono riguardare limplementazione. I cambiamenti devono inoltre essere
applicati in modo consistente in tutti i documenti prodotti nello sviluppo del software.

Siccome i cambiamenti non sono quasi mai anticipati e pianificati, potrebbero causare seri problemi.

14
Ingegneria del Software 2 Capitolo 3: Cicli di vita del software

Osservazioni conclusive sul modello a cascata


Il modello a cascata talvolta dannoso, perch richiede che il dominio venga compreso completamente sin dallinizio
e che i requisiti siano noti e stabili. Tutto ci per accade solo raramente, perci i ricicli non possono essere eliminati,
come invece vorrebbe il modello a cascata.

Il problema principale del modello a cascata che si tratta sostanzialmente di un modello a scatola nera, che non
fornisce trasparenza: la trasparenza per necessaria, perch consente di controllare la presenza di errori in anticipo,
apportando eventualmente le modifiche necessario, grazie a dei feedback ottenuti durante il processo stesso. La
trasparenza facilita perci la flessibilit.

Al termine di ogni fase si dovrebbe quindi eseguire unoperazione di validazione e verifica:

Validazione
La validazione consiste nel verificare che, dal punto di vista dellutente, il prodotto che si sta realizzando
effettivamente quello desiderato. La validazione perci indipendente dalle specifiche, che potrebbero non
rappresentare in maniera corretta o completa le esigenze dellutente.

Verifica
La verifica consiste invece nel verificare che si sita procedendo nel modo giusto nel processo di sviluppo del
software: si verifica cio la correttezza (ovvero, come gi discusso, laderenza alle specifiche).

Per rispondere a queste esigenze, sono stati sviluppati modelli di cicli di vita del software leggermente diversi, che
consentano di avere dei feedback e di procedere in maniera incrementale. Due esempi sono la prototipazione e il
rilascio incrementale, che si basano ancora sul modello a cascata.

Prototipazione
Concetto di prototipo
Un prototipo un modello approssimativo di unapplicazione, utilizzato per avere un feedback o per provare alcuni
concetti (ovvero, per effettuare delle verifiche di fattibilit di alcune idee). Il prototipo pu anche essere solo un
disegno grafico: non deve necessariamente essere di tipo software.

I prototipi vengono usati nelle fasi preliminari di sviluppo del software. Cosa prototipare dipende da quelli che sono gli
aspetti critici dellapplicazione (ad esempio, linterfaccia grafica, nel caso in cui sia particolarmente importante
lusabilit). Se il prototipo viene realizzato durante la fase di design, solitamente viene usato per verificare che le idee
progettuali funzionino; se invece viene realizzato in una delle fasi precedenti, generalmente lo scopo del prototipo
quello di avere un feedback dallutente.

Approccio throw-away e approccio evolutivo


Gli approcci possibili secondo i quali la prototipazione pu essere messa in atto sono fondamentalmente due:

Approccio throw-away
Prevede che il prototipo venga buttato via e non utilizzato per lo sviluppo vero e proprio del sistema software.

Approccio evolutivo
Prevede che il prototipo venga poi trasformato fino a diventare il sistema finale.

Naturalmente, entrambi gli approcci possono essere validi: di solito si usa lapproccio throw-away se il prototipo
stato realizzato solo per mostrare qualcosa allutente, me si usa lapproccio evolutivo se il prototipo riguarda aspetti di
progettazione.

15
Capitolo 3: Cicli di vita del software Ingegneria del Software 2

Rilascio incrementale (incremental delivery)


Il rilascio incrementale: idee di base
Il rilascio incrementale prevede che il processo di sviluppo del software venga spezzettato in sottoprocessi, destinati
ciascuno ad una diversa funzionalit: lidea di base quella che in questo modo si fornisce anticipatamente un certo
insieme di funzionalit, e perci si avr anticipatamente un feedback da parte dellutente, riguardante tale
sottoinsieme di funzionalit.

Il rilascio incrementale viene effettuato partendo dai sottoinsiemi di funzionalit critiche, sui quali particolarmente
importante avere dei feedback da parte degli utenti.

Analisi Design Codifica Test Rilascio del primo incremento

Analisi Design Codifica Test Rilascio del secondo incremento

Analisi Design Codifica Test Rilascio del terzo incremento

Figura 4: rilascio incrementale

Lapproccio incrementale ancor pi importante per i nuovi tipi di prodotti. Per tale ragione, vengono rese disponibili
delle versioni beta, che possano essere provate dagli utenti. In questo un grande aiuto proviene da Internet, che un
grande mezzo per mettere in mostra e distribuire i diversi incrementi del software.

Il modello a spirale
Introduzione al modello a spirale
Il modello a spirale un modello ideato da Barry Boehm, che di fatto rappresenta una generalizzazione dellapproccio
incrementale. Possiamo anzi affermare che il modello a spirale un meta-modello, perch consente di descrivere
anche gli altri modelli di tipo evolutivo.

Il modello a spirale pone una forte enfasi sullanalisi dei requisiti e dei rischi. Esso prevede una continua iterazione tra
diverse task region:

1. Comunicazione con il cliente


2. Pianificazione
3. Analisi dei rischi
4. Ingegnerizzazione (strutturazione)
5. Costruzione e rilascio
6. Valutazione del cliente

Ogni task region ulteriormente scomposta in vari compiti (task); il numero dei task ed i loro obiettivi vengono
definiti in base alle caratteristiche del progetto. Ogni task region inoltre deve essere di per s un ciclo di vita.

Il modello a spirale considera centrale la natura evolutiva intrinseca del software. Il modello deve essere per
specializzato per uno specifico software che di desidera realizzare. Ad oggi, il modello a spirale non ha ancora
trovato un ampio utilizzo.

16
Ingegneria del Software 2 Capitolo 3: Cicli di vita del software

La figura seguente mostra il modello a spirale.

Figura 5: modello a spirale

Sviluppo basato sui componenti (component-based development)


Lo sviluppo basato sui componenti pu in realt essere considerato unapplicazione del modello a spirare e
dellapproccio incrementale. Il termine componente in questo contesto viene usato con il significato di unit
riutilizzabile.

In sostanza, ogni iterazione della spirale consente il rilascio di un nuovo componente, mediante lesecuzione dei
seguenti tasks (che sono quindi quelli che costituiscono ogni iterazione della spirale stessa):

1. Identificazione dei componenti necessari


2. Ricerca dei componenti necessari allinterno di librerie, repository, catologhi,
3. Possibilmente, sviluppo di nuovi componenti
4. Rilascio di un nuovo incremento del prodotto

Lo scopo di questo approccio quello di limitare lo sforzo per lo sviluppo di nuovi componenti, riutilizzando il pi
possibile i componenti gi esistenti.

17
Capitolo 3: Cicli di vita del software Ingegneria del Software 2

Rapid Application Development (RAD)


Concetti di base
Il termine RAD un termine utilizzato per indicare una metodologia di sviluppo del software che prevede un utilizzo
minimo della pianificazione, al fine di ottenere rapidamente la prototipazione del prodotto finale. La pianificazione
quindi alternata alla fase di implementazione e grazie alla mancanza di una fase intensiva e lunga di progettazione, si
arriva alla scrittura del software in maniera pi rapida ed pi semplice modificare i requisiti in corso dopera.

Tale approccio prevede che si usino insieme le tecniche dello sviluppo incrementale e della prototipazione. Il modello
RAD usato soprattutto per sviluppare sistemi informativi, le cui caratteristiche consentono un approccio con scarsa
pianificazione, anche grazie al fatto che gli obiettivi del progetto sono ben noti a priori.

Passi fondamentali
I passi principali previsti dallapproccio RAD sono i seguenti:

Business modeling
Il flusso di informazioni tra le diverse funzioni di business viene modellato in modo da identificare le persone, le
informazioni e i processi che caratterizzano il business in esame.

Data modeling
In questa fase si crea un modello nel quale vengono categorizzate e raffinate le definizione delle persone e delle
informazioni di interesse. Si definiscono inoltre le relazioni tra persone e informazioni di interesse per il business
oggetto di studio.

Process modeling
Si creano delle descrizioni dei processi che consentono di aggiungere, modificare, cancellare o recuperare i dati.

Application generation
Utilizzando linguaggi di generazione di quarta generazione (4GL, fourth generation languages), il modulo viene
costruito. Di fatto la generazione dellapplicazione avviene in maniera automatica o semiautomatica.

Testing
I componenti appena creati necessitano di cicli di testing dettagliati; inoltre necessario eseguire dei controlli di
qualit anche sui componenti riutilizzati.

Turnover
Questa la fase pi importante del modello RAD. Nella fase di turnover, ci si assicura che il cliente sia
pienamente soddisfatto dalle operazioni che il sistema gli consente di eseguire.

Vantaggi e svantaggi
I vantaggi principali sono:

1. I risultati sono visibili entro breve tempo;


2. possibile scomporre il sistema in sottosistemi che possono essere sviluppati entro i termini di tempo prefissati.

Per contro, questa metodologia non applicabile in situazioni nelle quali i requisiti non sono ben chiari a priori.

18
Ingegneria del Software 2 Capitolo 3: Cicli di vita del software

Extreme Programming (XP)


Concetti di base
Per rispondere alle continue esigenze di rendere pi flessibile il processo di sviluppo, sono stati introdotti i cosiddetti
agile methods, tra i quali uno dei pi importanti il modello extreme programming. Il modello XP consente uno
sviluppo incrementale che fornisce dei continui feedback da parte degli utenti. Ad intervalli di poche settimane si ha
infatti un confronto con il committente, durante il quale viene stabilito lo step successivo da eseguire.

Visti gli obiettivi che si prefigge, lextreme programming sta oggi attirando su di s forte attenzione: la flessibilit viene
infatti portata a livelli estremi. La premessa sulla quale si basa lextreme programming che risulta impossibile
stabilire in maniera esatta le specifiche del software in modo anticipato. Lapproccio viene cos paragonato a quello
della guida di unauto: si ha la necessit di continui aggiustamenti.

La distinzione tra il design e limplementazione risulta naturalmente molto labile, e a volte non esiste del tutto. I
principi base dellXP model sono 4:

1. Comunicazione: occorre agevolare la comunicazione allinterno del progetto, nella giusta misura.
2. Semplicit: bisogna sempre cercare di individuare la soluzione pi semplice, purch funzioni.
3. Feedback: necessario ottenere continui feedback dai clienti, ma anche attraverso test interni.
4. Coraggio: bisogna gettare via il lavoro precedente, quando questo si rende necessario.

Come mettere in atto il modello XP?


Le attivit fondamentali che si hanno allinterno del modello XP sono la codifica, il testing, lascolto ed il design.

Le pratiche fondamentali di cui si fa uso nel modello XP sono:

Pratiche di pianificazione
La pianificazione viene gestita nel modo seguente: ad ogni iterazione, si determina lo scope della release
successiva, si definisce il piano di lavoro e, non appena la realt rende superato il precedente piano, si procede
ad una nuova attivit di pianificazione.

Gli utenti definiscono gli obiettivi che desiderano vengano raggiunti, e per comunicarli utilizzano delle storie. Gli
sviluppatori quindi stimano lo sforzo necessario per ogni storia, e congiuntamente con gli utenti definiscono le
priorit.

Rilasci
I rilasci avvengono a breve distanza di tempo, mettendo a disposizione, per esempio, solo degli insiemi limitati di
funzioni.

Uso di metafore
Il sistema viene spesso caratterizzato per mezzo di metafore, o comunque con un certo livello di astrazione, in
modo tale da definire una visione del sistema e di creare un vocabolario di termini da usare (ad esempio, si pu
caratterizzare il sistema mediante frasi come il calcolo delle pensioni avviene in modo simile a quanto accade
con un foglio di calcolo).

Design semplificato
In ogni dato istante, si eseguono tutti i test, senza duplicare la logica. Ogni intenzione importante viene
dichiarata. Si definisce il minor numero possibile di classi e metodi.

Refactoring
Quando si implementa una certa caratteristica, si devono sempre considerare i possibili cambiamenti e
miglioramenti.

19
Capitolo 3: Cicli di vita del software Ingegneria del Software 2

Testing
Si eseguono testing continuamente e in maniera automatica, spesso utilizzando tools automatici.

Programmazione a coppie
Il codice viene scritto solitamente da gruppi di persone molto piccoli (solitamente un team composto da 2 sole
persone), costituiti da sviluppatori molto esperti che lavorano allo stesso terminale (in modo da tenere alta
lattenzione).

Propriet colletiva del codice


Chiunque veda la possibilit di apportare miglioramenti, pu modificare il codice. Per fare ci, preferibile
adottare unorganizzazione del codice semplice e rispettare le convenzioni di programmazione pi diffuse.

Integrazione continua
Lintegrazione avviene in continuazione, senza prevedere ununica fase di integrazione finale dei vari
componenti.

40 ore di lavoro settimanali


Ai programmatori vengono richieste 40 ore di programmazione settimanali, perch il lavoro deve essere
considerato piacere e creativit, e non uno stress.

Partecipazione del cliente


Il cliente deve partecipare allo sviluppo del progetto, e perci deve partecipare alle discussioni insieme al team di
sviluppo.

Standard di codifica
Si devono rispettare alcuni standard di codifica: si devono seguire le convenzioni pi comuni riguardanti la
scrittura del codice, e si deve sempre evitare di duplicare il codice.

Vantaggi dellXP
Secondo i sostenitori dellXP, il vantaggio fondamentale di questo approccio dato da una drastica riduzione dei costi
legati ai cambiamenti. Tuttavia, bene notare che tale dato non ancora del tutto provato, perch il modello XP
molto recente.

Costo dei Costo dei


cambiamenti Approccio cambiamenti
tradizionale

Approccio XP

Istante in cui il cambiamento avviene Istante in cui il cambiamento avviene


(dallavvio del progetto) (dallavvio del progetto)

Figura 6: confronto tra il costo dei cambiamenti con lapproccio tradizionale e con lapproccio XP

Valutazioni preliminari
Alcune delle pratiche introdotte dal modello XP sembrano essere particolarmente efficaci; tuttavia, la loro efficacia
dipende fortemente dal tipo di progetto che si deve sviluppare, e risulta elevata soprattutto se il progetto di
dimensioni ridotte, presenta dei requisiti molto volatili, ed orientato allutente finale.

20
Ingegneria del Software 2 Capitolo 3: Cicli di vita del software

Rational Unified Process (RUP)


Cos RUP?
Il RUP un framework a supporto del processo iterativo di sviluppo del software. Il termine Rational che compare
nellacronimo il nome dellazienda che ha dato vista a questo strumento, oggi diventata parte di IBM.

Lapproccio pu essere considerato unevoluzione di una precedente metodologia per lo sviluppo di software
orientato agli oggetti, nota con Objectory method.

RUP allo stesso tempo un framework e un prodotto commercializzato da Rational:

Si tratta di un framework, o processo generico, che pu essere personalizzato in base allo specifico sistema
software che si deve realizzare, allorganizzazione, al dominio dellapplicazione, al livello di competenza e alle
dimensioni del progetto.
Si tratta di un prodotto che offre una serie di strumenti per automatizzare le varie fasi previste da questo
approccio per lo sviluppo del software.

RUP in sostanza un insieme di linee guida e di strumenti di supporto per la progettazione del software. In
particolare, le linee guide prevedono lutilizzo di UML come linguaggio di descrizione, si basano sulle best practices e
focalizzano la loro attenzione sullarchitettura del sistema, imponendo la creazione di modelli in ogni fase (si parla
perci di approccio model-driven).

Gli strumenti utilizzati come supporto per la progettazione del software sono noti con lacronimo CASE (Computer-
Aided Software Engineering) e si tratta di applicazioni che automatizzano le fasi di analisi, design e programmazione
del progetto software.

Caratteristiche fondamentali
1. Lapproccio di RUP di tipo iterativo ed incrementale, in modo tale da gestire la complessit e da consentire
levoluzione dei requisiti.
2. Inoltre, la metodologia RUP pone lenfasi sulla modellizzazione anzich sulluso del linguaggio informale: in questo
modo viene aumentata la leggibilit e la modificabilit ed possibile sfruttare il supporto di strumenti automatici.
3. Il modello incentrato sullarchitettura del software, che viene definita sin dalle primissime fasi del progetto. Si
cerca inoltre di scomporre il sistema per consentire lo sviluppo parallelo, il riuso e la manutenibilit del sistema.

Fasi dellapproccio RUP


1. Inception: si identificano i casi di business e lambito del progetto. In sostanza quindi si inizia a pensare allo
sviluppo del nuovo sistema software. Si definisce al termine di questa fase un documento di vision, contenente le
caratteristiche fondamentali del sistema.
2. Elaboration: si effettua la pianificazione del progetto, definendo tutte le sue caratteristiche ed il design
architetturale.
3. Construction: si sviluppa il sistema.
4. Transizione: si mette in esecuzione il sistema.

Architettura Funzionalit Rilascio del


Vision di base iniziali prodotto

Inception Elaboration Construction Transition

Figura 7: fasi della metodologa RUP

21
Capitolo 3: Cicli di vita del software Ingegneria del Software 2

Iterazione
Oltre alle 4 fasi analizzate, vengono definiti anche diversi workflow (requisiti, analisi, design, implementazione e
testing). Le 4 fasi vengono eseguite nellordine precedentemente descritto, ma ciascuna pu essere iterata pi volte
consecutivamente. In ogni iterazione, i diversi workflow hanno delle rilevanze diverse, che sono messe in evidenza
dalla figura seguente.

Figura 8: workflow e iterazioni allinterno del modello RUP

Sincronizzazione e stabilizzazione (Sync-and-stabilize)


Lapproccio sync-and-stabilize
Lapproccio sync-and-stabilize stato adottato da Microsoft ed noto anche come daily build. Esso stato concepito
per supportare lo sviluppo di prodotti caratterizzati da una forte complessit, ai quali lavorano team di dimensioni
medie o grandi, con uno sviluppo basato sui componenti, orientati allintroduzione di innovazione durante il corso del
progetto stesso.

I principi di base sono:

1. Lo sviluppo in parallelo, portato avanti da un piccolo numero di team di sviluppo.


2. Sincronizzazioni molto frequenti dei risultati prodotti dai diversi team.
3. Stabilizzazione periodica del prodotto.

Il termine sync-and-stabilize fa riferimento al fatto che alla fine di ogni giornata, ogni lavoratore inserisce i propri
aggiornamenti in un respository, dando cos il via ad una serie di test (sincronizzazione); inoltre, periodicamente si
identificano le parti pi stabili del sistema, le quali verranno messe in commercio (stabilizzazione).

22
Ingegneria del Software 2 Capitolo 3: Cicli di vita del software

Fasi principali
Le fasi principali dellapproccio sync-and-stabilize sono:

Pianificazione
Si definisce la visione del progetto, si effettua la pianificazione delle attivit del progetto e si identificano le sue
caratteristiche fondamentali. Si producono i seguenti output:

a) Il vision statement, sviluppato dal product manager e contenente gli obiettivi del progetto, ma anche una
lista di caratteristiche che il prodotto finale avr, con le relative priorit. Questo documento guider poi
lintero progetto.

b) Lo specification document, sviluppato dal program manager e dagli sviluppatori, contenente le specifiche
funzionali e tutte le caratteristiche richieste, ma anche la definizione del design architetturale.
Naturalmente, il set di caratteristiche evolver poi durante il corso del progetto.

c) Un documento di pianificazione delle fasi successive, nel quale vengono identificati i sottoprogetti (di solito 3
o 4), da sviluppare in maniera sequenziale e dedicati ciascuno ad un diverso insieme di caratteristiche. In
questo documento vengono anche definiti i tempi per la realizzazione dei vari sottoprogetti, indicando
anche dei buffer time, cio degli intervalli tra una fase e la successiva, che servono per tenere conto di
eventuali problemi. Tipicamente il primo sottoprogetto quello che si occupa di realizzare le funzionalit pi
importanti e critiche.

Tipicamente, un team ha un program manager, da 3 a 8 sviluppatori ed un tester per ogni sviluppatore.

Sviluppo
I sottoprogetti precedentemente identificati vengono portati avanti uno dopo laltro. Per ciascuno, si hanno le
fasi seguenti:

a) Sviluppo delle funzionalit


b) Integrazione
c) Testing
d) Correzione degli errori (bugs)

Durante lo sviluppo, il progetto viene compilato a frequenza giornaliere a settimanale. In questo modo si
possono identificare preventivamente gli errori e i problemi di integrazione, si pu monitorare il grado di
completamento del progetto e si possono rendere evidenti gli obiettivi raggiunti.

Stabilizzazione
Si effettuano dei test interni ed esterni e si prepara il rilascio del progetto (ovvero del software da distribuire e
della relativa documentazione), che viene poi messo in funzione (deployment). Questa fase coordinata dal
project manager.

Vantaggi e svantaggi
In questo approccio i documenti chiave sono il documento di vision e di design architetturale, che vengono scritti nelle
fasi iniziali dello sviluppo. Tuttavia, difficile anticipare lanalisi delle funzionalit da implementare sin dallinizio del
progetto. Per questo motivo, non sono previsti documenti di design dettagliato e contenenti le specifiche dettagliate
del software.

La costruzione giornaliera del software offre alcuni vantaggi importanti: si ha sempre una versione aggiornata del
software, i test vengono sviluppati parallelamente allattivit di sviluppo e si ha una visione concreta del progetto e del
suo livello di completamento.

23
Capitolo 3: Cicli di vita del software Ingegneria del Software 2

Lo sviluppo open source


Gli obiettivi dellopen source
Lo sviluppo open source del software ha caratteristiche molto diverse dallo sviluppo tradizionale: esso coinvolge
infatti tantissime persone fortemente distribuite a livello mondiale, che non si conoscono e collaborano tra loro
volontariamente solo per lo sviluppo del software, senza alcun guadagno economico di tipo diretto.

Lobiettivo fondamentale dello sviluppo open source quello di produrre del software gratuitamente disponibile per
chiunque lo desideri, fornendo direttamente il codice sorgente dellapplicazione.

Trattandosi di uno sviluppo fortemente distribuito, la comunicazione si basa su strumenti legati ad Internet (come ad
esempio le e-mail, i gruppo di discussione, le newslist, ).

In ogni caso, bene evidenziare che nel software open source esiste sempre un designer principale (o comunque un
certo gruppo con un numero limitato di persone). Tale persona o gruppo di persone si occupa di definire il nucleo
fondamentale dellapplicazione (ovvero la sua architettura) e valuta gli sviluppi messi a disposizione dagli altri
programmatori.

24
Ingegneria del Software 2 Capitolo 4: Il Capacity Maturity Model

Capitolo 4: Il Capacity Maturity Model


Introduzione al Capacity Maturity Model (CMM)
Che cos il CMM?
Il Capability Maturity Model (CMM), oggi noto come CMMI un approccio introdotto al fine di valutare la bont ad
alto livello del processo di sviluppo. In sostanza quindi si tratta di un metodo per valutare la qualit dellorganizzazione
che produce software, in modo tale da individuare le aree che necessitano di interventi di miglioramento.

Storicamente, questo approccio stato introdotto nel 1986, quando il Dipartimento della Difesa americano e la NASA
hanno attribuito al SEI (Software Engineering Institute) il compito di effettuare le valutazioni di qualit di aziende che
producono software; il SEI si cos preoccupato di definire dapprima quali sono i parametri per poter definire
immatura una certa organizzazione software e quindi, sulla base di questo, stato possibile definire quali sono le
organizzazioni mature. Il motivo principale per il quale tale approccio stato introdotto che si intendeva individuare
una serie di criteri in base ai quali scegliere i fornitori di software pi capaci, in modo da rivolgersi ad essi per le
iniziative strategiche di difesa.

Cenni alla storia del CMM


1. Nel 1986, nasce lapproccio CMM.
2. Nel 1987 viene definita la struttura generale del modello e viene rilasciato il primo questionario.
3. Tra il 1987 e il 1991 il modello viene sperimentato e validato.
4. Nel 1991 nasce il CMM v.1.0, che era basato sulla conoscenza del processo di produzione del software acquisita
negli anni precedenti e sul feedback degli utenti.
5. Fino al 1993 stata portata avanti una nuova attivit di revisione.
6. Nel 1993 nata la v.1.1 del CMM.
7. Tra il 1996 e il 1998 stato costruito il modello CMM v.2.0.
8. Oggi esistono diversi modelli:
a) Il modello CMMI (Capability Maturity Model Integration), che si occupa del miglioramento del processo. In
particolare, esistono diversi modelli CMMI: il modello SW-CMM (Software CMM, che riguarda il processo di
creazione del software), il modello SE-CMM (System Engineering CMM, che riguarda il processo di
ingegnerizzazione dei sistemi) ed il modello IPD-CMM (Integrated Product Development CMM, che riguarda il
processo di creazione di sviluppo di prodotti integrati).
b) Il P-CMMI (People Capability Maturity Model Integration), che si occupa di giudicare il livello di maturit
dellazienda nella gestione delle proprie risorse umane.
c) Il SA-CMM (Software Acquisition Capability Maturity Model), che giudica il livello di maturit nel processo di
acquisizione del software da parte di unorganizzazione.

25
Capitolo 4: Il Capacity Maturity Model Ingegneria del Software 2

Valutazione della maturit di unorganizzazione


Il concetto di immaturit
Come accennato, per prima cosa il CMM ha dovuto individuare le caratteristiche tipiche delle organizzazioni
immature; tali caratteristiche sono:

1. Limprovvisazione nel processo di sviluppo;


2. Il carattere reattivo dei manager, i quali si occupano di risolvere i problemi man mano che si presentano;
3. Lincapacit di valutare correttamente i tempi ed i costi del progetto, che porta lazienda a non rispettare le
scadenze, i budget e i livelli di qualit prefissati;
4. Limpossibilit di prevedere e giudicare la qualit di un prodotto.

Il concetto di maturit: caratteristiche delle organizzazioni mature


1. La capacit di gestire processi di sviluppo e manutenzione parte del patrimonio aziendale, e non delegata ai
singoli;
2. Si segue un modello di processo accuratamente definito e noto a tutti;
3. Il modello di processo viene continuamente migliorato, attraverso unattivit di manutenzione;
4. I manager sono in grado di verificare la qualit dei prodotti e il livello di soddisfazione dei clienti;
5. Si effettuano stime realistiche, sulla base dei dati storici.

Alcune definizioni
Software process capability
Descrive che cosa ci si pu aspettare da un dato processo software.

Software process performance


Rappresenta i risultati effettivi ottenuti da un dato processo software.

Software process maturity


Indica il livello a cui un processo viene definito, gestito, misurato, controllato ed attuato. Se il processo software
maturo, possiamo prevederne le capability e possiamo incrementare nel tempo le performance.

I livelli di maturit
Il SEI ha definito 5 diversi livelli di maturit per unorganizzazione che produce software:

Livello 5:
Continuo miglioramento Ottimizzato
del processo
Livello 4:
Gestito
Processo
prevedibile
Livello 3:
Definito
Definizione di standard,
Processo consistente
Livello 2:
Ripetibile

Processo
metodico Livello 1:
Iniziale

Figura 9: i 5 livelli di maturit definiti dal SEI allinterno del CMM

26
Ingegneria del Software 2 Capitolo 4: Il Capacity Maturity Model

Vediamo ora di analizzare nel dettaglio ciascuno di tali livelli:

Livello iniziale (processo improssivato)


A questo livello, lorganizzazione giudicata completamente immatura.

Il processo viene definito ad-hoc per ogni singolo progetto ed caotico. Pochi processi sono stati definiti ed i
successi dipendono esclusivamente dalle capacit e dagli sforzi personali.

Non esiste un ambiente stabile, non vengono praticate le buone tecniche di gestione dei progetti. Al
profilarsi di una crisi (approssimarsi della scadenza, superamento del budget), le procedure pianificate vengono
abbandonate e tutte le attivit di controllo di qualit vengono eliminate.

Di conseguenza, le software process capability di una organizzazione a livello 1 non sono predicibili, non
possibile stimare con precisione la durata ed il costo dei progetti, le funzionalit che verranno implementate e la
qualit che si potr raggiungere nel prodotto.

Livello ripetibile (processo creato sulla base dei precedenti con caratteristiche simili)
Al livello ripetibile esiste un minimo di supporto alla gestione del processo, che consente in alcuni casi di ripetere
i successi aziendali (a patto che il contesto applicativo non sia troppo diverso da quello precedentemente
affrontato). Sono quindi presenti le tecniche base di project management: costi, tempi e funzionalit vengono
tenuti sotto controllo. La pianificazione di un nuovo progetto viene condotta sulla base dellesperienza
accumulata in progetti simili.

Le tecniche di management consentono di stabilire degli obiettivi ragionevoli sulla base del confronto con
esperienze precedenti. I manager controllano lavanzamento di costi, tempi e funzionalit: conflitti con gli
obiettivi posti vengono identificati ed affrontati. Vengono inoltre attuate le procedure atte a garantire la
consistenza ed integrit di tutti i semi-lavorati.

Livello definito (processo standard dellorganizzazione predefinito e derivazione dei singoli processi da esso)
Se unorganizzazione si trova al livello definito, allora allinterno dellorganizzazione esiste un processo
documentato e standardizzato che definisce sia le attivit tecniche che quelle di gestione in modo organico
(organizations standard software process). La responsabilit di gestire il processo standard esplicitamente
affidata ad alcuni individui.

Inoltre, tutti i progetti di sviluppo e manutenzione seguono un processo derivato secondo regole prestabilite da
quello standard (projects defined software process). Tale processo definisce ad esempio i criteri di
completamento, gli standard e le procedure di lavoro e le tecniche di verifica da adottare.

In unorganizzazione a livello definito, il management ha una buona visibilit del processo per tutti i progetti ed
esiste un programma di training che copre tutti i ruoli presenti nellorganizzazione.

Livello gestito (processo definito e valutato attraverso opportune misure)


Lorganizzazione al livello gestito se si occupa di raccogliere delle misure relative alla qualit del processo e dei
prodotti, in modo da valutarli e controllarli quantitativamente.

Le misure vengono raccolte, mantenute ed analizzate a livello aziendale (software process database). Inoltre
possibile stabilire degli obiettivi quantitativi sulla qualit del processo e dei prodotti. I margini di variabilit dei
risultati ottenibili per un progetto sono ridotti ed possibile predire la qualit dei prodotti, e realizzare prodotti
di alta qualit.

27
Capitolo 4: Il Capacity Maturity Model Ingegneria del Software 2

Livello ottimizzante (miglioramento del processo basato sulle misure di valutazione della sua qualit)
In unorganizzazione a livello ottimizzante, i riscontri quantitativi dati dallattuazione del processo e dalla
realizzazione di progetti pilota forniscono indicazioni su come migliorare continuamente il processo standard,
attraverso lidentificazione dei punti di forza e delle carenze del processo, in modo poi da prevenire i difetti,
anzich eliminarli: i difetti riscontrati vengono analizzati in modo da poterne identificare (e rimuovere) le cause
allinterno del processo di sviluppo.

Possiamo perci affermare che le organizzazioni a livello 5 tentano continuamente di migliorare il proprio
processo, in modo incrementale: si migliora il processo esistente introducendo in modo controllato delle
innovazioni, dei nuovi metodi e delle nuove tecnologie.

Da quanto finora detto risulta abbastanza evidente che i livelli di maturit inferiori costituiscono delle basi
indispensabili su cui fondare i livelli superiori, di conseguenza opportuno che unorganizzazione raggiunga un certo
livello di maturit in maniera graduale, attraversandoli tutti a partire dal pi basso. Del resto, sarebbe inutile, ad
esempio, tentare di misurare un processo (livello 4) se non ancora stato neppure definito il processo stesso.

Perch valutare la maturit{ di unorganizzazione?


I motivi per i quali la valutazione della maturit di unorganizzazione utile sono diversi:

1. Software Capability Evaluation (valutazione delle capacit software)


Si pu valutare attraverso il CMM la maturit di un fornitore, in modo tale da sfruttare i risultate di tale analisi per
poter scegliere opportunamente a quale fornitore rivolgersi.
Inoltre, si pu utilizzare il CMM per monitorare delle attivit gi in corso.
2. Software Process Assessment (pianificazione del processo software)
Si determina lo stato attuale del processo software di unorganizzazione, in modo da identificarne le carenze pi
importanti. In questo modo si potr poi ottenere il supporto organizzativo al miglioramento del processo.
3. Interim profile (valutazione interna dei progressi)
Il CMM un modo non dispendioso per valutare concisamente i progressi ottenuti dal processo di miglioramento.
Viene effettuato ad intervalli regolari fra due fasi successive di pianificazione del processo, in modo da poter
valutare i risultati delle modifiche apportate al processo del software stesso.

Adottare il CMMI comporta inoltre degli importanti benefici in termini di costi, tempi, qualit e soddisfazione dei
clienti, nonch un incremento del cosiddetto ROI (Return on Investment).

28
Ingegneria del Software 2 Capitolo 4: Il Capacity Maturity Model

Le fasi di un assessment
Lassessment del processo software avviene secondo le fasi seguenti.

1. La prima fase consiste nellidentificare un team che si occupi di tale operazione. Il team deve aver ricevuto una
formazione sui principi fondamentali del CMM e deve essere costituito da professionisti con conoscenze ed
esperienze nellingegneria del software e nel management.
2. Dopodich, il team selezionato si occuper di effettuare dei questionari di maturit, secondo il modello imposto
dal CMM.
3. In tal modo sar possibile passare alla fase successiva, che consiste nellanalisi dei dati cos raccolti
nellidentificazione delle aree chiave del processo, ovvero di quelle aree che devono ancora essere esplorate
perch potrebbero essere migliorate.
4. A questo punto, il team di valutazione in grado di effettuare una visita sul luogo dellorganizzazione in analisi. Il
team condurr cos delle interviste sul luogo e si occuper di analizzare la documentazione dellorganizzazione
riguardante il processo del software. In tale fase, il team sar guidato dalle valutazioni precedentemente
effettuate.
5. Alla fine di questa fase, viene prodotto un documento nel quale vengono elencati i punti forti e le debolezze del
processo software dellazienda.
6. Infine, il team si occupa di preparare un key process area profile, nel quale vengono evidenziate le aree nelle quali
lorganizzazione in grado di ottenere gli obiettivi prefissati e quelle in cui invece non in grado di raggiungerli.
possibile che unarea, pur avendo ancora delle debolezze, sia in grado di raggiungere gli obiettivi prefissati.

Figura 10: le fasi di un assessment

29
Capitolo 4: Il Capacity Maturity Model Ingegneria del Software 2

Standard ISO 9000


Cosa sono gli standard ISO 9000?
Gli standard ISO 9000 sono delle normative e linee guida sviluppate dallISO (International Organization for
Standardization) che definiscono i requisiti per l'implementazione, in una organizzazione, di un sistema di gestione
della qualit, al fine di condurre i processi aziendali, migliorare l'efficacia e l'efficienza nella realizzazione del prodotto
e nell'erogazione del servizio, ottenere ed incrementare la soddisfazione del cliente.

Si tratta perci di norme che descrivono i requisiti di un sistema di qualit e definiscono gli attributi minimi che deve
avere una organizzazione per poter soddisfare determinati impegni contrattuali.

Le norme ISO 9000 riguardano prodotti di ogni tipo. Gli standard fondamentali in vigore dal 2000 sono 3:

ISO 9000:2000 Fundamentals and vocabulary (Fondamenti e vocabolario)


Si tratta di una norma che descrive il vocabolario ed i principi essenziali dei sistemi di gestione per la qualit e
della loro organizzazione.

ISO 9001:2000 Requirements (Requisiti)


una norma che definisce i requisiti di un sistema di gestione per la qualit per una organizzazione.

ISO 9004:2000 Guidelines for performance improvements (Lapproccio della gestione per la qualit)
Non si tratta di una norma, ma di una linea guida per favorire in una organizzazione il conseguimento del
successo durevole per mezzo della gestione per la qualit.

La certificazione
Le aziende che seguono le norme della serie ISO 9000 possono ottenere dallISO la relativa certificazione, che di
conseguenza rappresenta un attestato della qualit del processo adottato dallorganizzazione. Per ottenere tale
certificazione, lorganizzazione deve:

1. Definire, documentare e mantenere le procedure ed istruzioni operative.


2. Verificare che le procedure e le istruzioni definite vengano seguite, conservandone le prove.

I requisiti da soddisfare
I requisiti che lorganizzazione deve soddisfare per ottenere la certificazione ISO 9000 sono di diversi tipi:

1. Systematic requirements (requisiti sistematici)


Ad esempio, bisogna realizzare dei documenti che riguardano il sistema di controllo della qualit.
2. Management requirements (requisiti di gestione)
Ad esempio, occorre definire delle politiche interne, bisogna soddisfare il cliente,
3. Resource requirements (requisiti sulle risorse)
Ad esempio, necessario che il personale dellorganizzazione sia di qualit.
4. Realization requirements (requisiti di realizzazione)
Ad esempio, bisogna controllare la pianificazione della realizzazione del prodotto.
5. Remedial requirements (requisiti delle misure di rimedio)
Ad esempio, bisogna monitorare la qualit.

Confontro tra ISO 9000 e CMM


La normativa ISO 9000 e lapproccio CMM riguardano entrambi il controllo di qualit di un processo, ma hanno
differenze significative: la pi importante che la certificazione ISO 9000 si limita a imporre dei requisiti minimi di
accettabilit, mentre il CMM impone un miglioramento continuo del processo (di conseguenza, lISO 9000 ha
granularit meno fine).

I due approcci sono per sinergici: si pu ad esempio utilizzare il CMM come linea guida per raggiungere gli obiettivi
imposti per ottenere la certificazione ISO 9000.

30
Ingegneria del Software 2 Capitolo 5: Ingegneria dei requisiti

Capitolo 5: Ingegneria dei requisiti


Lingegneria dei requisiti
Definizione
Lingegneria dei requisiti un insieme di attivit che hanno a che fare con lidentificazione e la comunicazione dello
scopo e dei requisiti di un sistema software

Di conseguenza, possiamo affermare che lingegneria dei requisiti fa da ponte tra le necessit dei committenti e degli
utenti allinterno del mondo reale e le capacit ed opportunit messe a disposizione dalle tecnologie software.

Esigenze del Tecnologie


Requirement Engineering (RE)
mondo reale software

Figura 11: Lingegneria dei requisiti come ponte tra mondo reale e tecnologie software

Lingegneria dei requisiti, in altri termini, si occupa di studiare le relazioni tra il mondo reale e il mondo software. Per
meglio capire questo concetto, indicheremo in seguito con il termine macchina la porzione di sistema che deve essere
sviluppata e mondo (o ambiente) quella parte del mondo reale che ha a che fare con il sistema da sviluppare.
Naturalmente, lo scopo della macchina sempre strettamente legato al mondo reale. Se definiamo linsieme dei
fenomeni del mondo (ovvero linsieme di tutti quegli eventi che accadono nellambiente) e linsieme dei fenomeni del
sistema (cio linsieme di tutti quei fenomeni che accadono allinterno della macchina), risulta quindi ovvio che
lintersezione tra tali insiemi non pu essere vuota.

Fenomeni Fenomeni Fenomeni della


del mondo condivisi macchina

Figura 12: Fenomeni del mondo, fenomeni della macchina e fenomeni condivisi

In altri termini, devono esistere dei fenomeni condivisi, ovvero dei fenomeni che siano o controllati dal mondo e
osservati dalla macchina, oppure controllati dalla macchina ed osservati dal mondo.

Lingegneria dei requisiti deve essere in grado di determinare quali sono i fenomeni condivisi, che rappresentano
linterfaccia tra il mondo e la macchina: questo infatti significa individuare le caratteristiche che il sistema deve avere
per poter fornire un beneficio al mondo esterno. I modelli utilizzati per rappresentare i requisiti fanno solitamente
riferimento al mondo esterno.

31
Capitolo 5: Ingegneria dei requisiti Ingegneria del Software 2

Limportanza dellingegneria dei requisiti


Lingegneria dei requisiti ha un ruolo molto importante, per diverse ragioni:

1. I requisiti troppo poveri e scarsamente definiti sono molto diffusi, ma necessario ingegnerizzarli e rivederli e
correggerli continuamente.
2. Lingegneria dei requisiti una fase complessa e critica.
3. Individuare errori che riguardano i requisiti del sistema quando si ormai giunti alle fasi avanzate del processo
software causa costi molto elevati (specialmente se ci accade dopo il rilascio) e significativi rallentamenti: da un
punto di vista economico, il costo pu essere anche 200 volte superiore rispetto a quello che sarebbe necessario
affrontare se gli errori nei requisiti venissero immediatamente identificati. Lingegneria dei requisiti pu fornire
un supporto per limitare questi fenomeni.

Nel corso degli anni, diverse indagini hanno evidenziato come la definizione inaccurata, erronea, incompleta o tardiva
dei requisiti sia una delle cause fondamentali che conducono un progetto ad essere realizzato con gravi mancanze, o
addirittura che portano alla sua cancellazione.

Altre indagini hanno evidenziato come gli errori nella specifica e nella gestione dei requisiti siano la causa principale
dei problemi del software.

Si pu perci affermare che lattivit di identificazione e analisi dei requisiti determina con un peso circa pari al 40%
lesito di successo o insuccesso di un sistema software.

Complessit{ dellingegneria dei requisiti


I fattori che rendono complessa lingegneria dei requisiti sono molteplici:

1. Complessit e vastezza dellambiente


Spesso i sistemi nei quali il software deve essere inserito risultano essere molto complessi e richiedono
linterazione del software con altri componenti software, ma anche con persone, computer, dispositivi hardware
(come ad esempio sensori),
2. Diversi sistemi da analizzare
I sistemi da analizzare sono in realt pi duno: occorre tenere conto del sistema cos come prima che si realizzi
il nuovo sistema software (system-as-is; SAI) e il sistema che si dovr realizzare (system-to-be, S2B), tenendo
conto delle diverse alternative possibili e della sua futura evoluzione.
3. Diversi livelli di astrazione
Gli obiettivi possono essere definiti a diversi livelli di astrazione.
4. Diversi ambiti di cui tener conto
I requisiti possono essere di tipo funzionale, di qualit, di sviluppo, e di conseguenza possibile che le qualit
desiderata vadano in conflitto tra loro. Ci rende necessaria lintroduzione di diversi livelli di priorit tra i requisiti.
5. Persone diverse con cui interagire
Durante la fase di analisi e specifica dei requisiti necessario interagire con persone molto diverse tra di loro
(clienti, sviluppatori, utenti, esperti del dominio dellapplicazione, ). Tali categorie di persone hanno ovviamente
dei background molto diversi tra loro, e questo conduce ad una elevata difficolt nellindividuazione di un modo
di comunicare che possa essere compreso da tutti.

32
Ingegneria del Software 2 Capitolo 5: Ingegneria dei requisiti

Le dimensioni dellingegneria dei requisiti


Lingegneria dei requisiti ha 3 dimensioni: why, what e who.

Dimensione Why?
La dimensione why? Consiste nello svolgere le seguenti attivit:

a. Capire lo stato attuale del sistema (SAI) e come deve essere il nuovo sistema (S2B).
b. Analizzare le diverse alternative possibili per soddisfare gli obiettivi del sistema che si deve realizzare.
c. Ottenere un guadagno dalla comprensione del dominio applicativo e dalle possibilit messe a disposizione
dalle nuove tecnologie.

La dimensione why coinvolge diverse parti (categorie di individui).

Dimensione What?
La dimensione what? mette in relazione i servizi funzionali che il system-to-be deve fornire con gli obiettivi
identificati nel corso della why dimension.

Dimensione Who?
La dimensione who? si occupa di assegnare le responsabilit per il raggiungimento degli obiettivi prefissati.

Le attivit{ dellingegneria dei requisiti


Lingegneria dei requisiti si occupa di svolgere le seguenti attivit:

1. Raccolta delle informazioni


Attraverso interviste al committente e agli utenti, ma anche attraverso lanalisi dei sistemi gi esistenti e talvolta
anche attraverso linterazione con tecnici dellaspetto di dominio dellapplicazione, si individuano gli obiettivi del
progetto, il contesto, lambiente e si raccolgono le conoscenze di dominio e i requisiti.
2. Modellizzazione e analisi
Lingegneria dei requisiti si occupa di descrivere le informazioni raccolte con un approccio di modellazione
sufficientemente preciso. I modelli cos prodotti vengono poi analizzati, cercando di rilevare eventuali incoerenze.
I modelli hanno un ruolo centrale, perch sono la sintesi delle informazioni raccolte e la base per la
comunicazione dei requisiti con le varie personalit coinvolte.
3. Comunicazione dei requisiti
Il modello ottenuto deve poi essere comunicato a tutte le parti coinvolte, utilizzando dei linguaggi opportuni e
diversi a seconda degli interlocutori. La comunicazione avviene per mezzo di prototipi del sistema, documenti
come lSRS,
4. Negoziazione e raggiungimento di un consenso sui requisiti
Occorre gestire i rischi ed i conflitti tra i vari requisiti. Per tale motivo, bisogna riuscire a capire quali requisiti sono
quelli su cui focalizzarsi e quali invece possono essere trascurati. Ci accade mediante una negoziazione tra i
progettisti e i committenti.
5. Gestione ed evoluzione dei requisiti
I requisiti devono essere gestiti per tutta la fase di sviluppo, in modo tale che se ne possa conservare la
tracciabilit. Occorre inoltre gestire i cambiamenti dei requisiti, controllando limpatto che ognuno di questi
cambiamenti potr avere.

33
Capitolo 5: Ingegneria dei requisiti Ingegneria del Software 2

I System Context Diagrams


Cosa sono i system context diagrams
I system context diagrams sono dei modelli che possono essere utilizzati per mostrare le parti pi importanti del
mondo e le loro interfacce con la macchina.

Elementi del context diagram


Agenti
Gli agenti sono delle entit attive, ovvero in grado di controllare dei fenomeni del mondo. Un agente pu essere
umano, di tipo software, oppure pu essere un dispositivo hardware.

Gli agenti vengono rappresentati mediante un rettangolo allinterno del quale indicato il nome dellagente
stesso:

Agente

Figura 13: Rappresentazione di un agente allinterno di un system context diagram

La macchina
La macchina (ovvero il S2B) viene rappresentata in maniera molto simile allagente, ma con i bordi laterali doppi:

Macchina

Figura 14: Rappresentazione della macchina in un system context diagram

I fenomeni
I fenomeni sono rappresentati mediante delle frecce che partono da un agente (o dalla macchina) ed arrivano ad
un altro agente (o alla macchina). Lagente da cui la freccia ha origine colui che controlla il fenomeno (cio colui
che lo provoca), mentre lagente sul quale la freccia arriva lagente che lo monitora. Sulla freccia inoltre
indicato il nome del fenomeno.

Agente A Fenomeno Agente B

Figura 15: Rappresentazione di un fenomeno allinterno di un system context diagram

Di conseguenza, per ogni agente definito un insieme di fenomeni da esso controllati e un insieme di fenomeni
da esso monitorati.

Esempio di context diagram

Figura 16: Un esempio di system context diagram

34
Ingegneria del Software 2 Capitolo 5: Ingegneria dei requisiti

Gli obiettivi (goal) e le asserzioni


Le asserzioni
Per definire i requisiti del sistema, occorre per prima cosa definire delle asserzioni, che possono essere di diverso tipo:

Asserzioni descrittive o indicative


Le asserzioni legate a leggi naturali o vincoli fisici. Ad esempio:

Asserzioni prescrittive
Le asserzioni prescrittive affermano delle propriet desiderabili che possono essere vere oppure no, a seconda di
come il sistema funziona. Esprimono quindi dei desideri e devono essere messe in atto dai componenti del
sistema. Ad esempio:

Goal, propriet di dominio e requisiti


Vediamo di introdurre alcuni concetti fondamentali. Gli esempi utilizzati sono relativi ad un sistema di gestione delle
ambulanze.

Goal
Gli obiettivi (goal) sono delle asserzioni prescrittive formulate in termini di fenomeni del mondo.

Esempio: Per ogni chiamata urgente che segnala un incidente, unambulanza deve arrivare sul luogo
dellincidente entro 14 minuti.

Propriet di dominio
Le propriet di dominio sono delle asserzioni descrittive che si assume siano vere nel mondo.

Esempio: La posizione delle ambulanze nota con precisione mediante il sistema GPS.

Requisiti
I requisiti sono delle asserzioni prescrittive formulate in termini di fenomeni condivisi.

Esempio: Quando viene codificata una chiamata che segnala un nuovo incidente lADS (Automated
Dispatching Software, ovvero il sistema) deve mobilitare lambulanza disponibile pi vicina
lincidente, sulla base delle informazioni messe a disposizione dal GPS delle ambulanze.

Si noti che lingegneria dei requisiti ancora relativamente giovane, e perci non esiste ancora una terminologia
universalmente adottata. Ad esempio, alcuni autori usano il termine requirement (requisito) anzich il termine goal ed
il termine specification (specifica) al posto di requirement.

Altri autori invece usano i termini requisito di sistema (per goal) e requisito software (al posto del nostro requisito).

35
Capitolo 5: Ingegneria dei requisiti Ingegneria del Software 2

Provare la correttezza
Per provare la correttezza di requisiti, goal e propriet di dominio bisogna:

1. Verificare che linsieme D delle propriet di dominio rappresenti propriet e assunzioni valide nel mondo in
analisi.
2. Verificare che linsieme degli obiettivi G catturi tutte le esigenze degli stakeholders.
3. Assicurarsi che linsieme dei requisiti R soddisfi tutti gli obiettivi di G allinterno del dominio le cui propriet sono
definite da D. In altri termini, occorre verificare che dalla verit di tutte le formule di R e di D segua la verit di
tutte le formule logiche di G:

Il confine tra il mondo e la macchina solitamente non ben definito allinizio dello sviluppo del progetto: lingegneria
dei requisiti ha lo scopo di identificare i goal reali del progetto e di esplorare le varie alternative per soddisfare tali
obiettivi, attraverso diverse coppie (R, D) oppure attraverso interfacce alternative tra il mondo e la macchina. Per ogni
alternativa si deve poi valutare il rischio, allo scopo di scegliere poi quella pi appropriata.

Il documento SRS
Che cos il documento SRS?
Il documento SRS (Software Requirements Specifications) un documento allinterno del quale vengono catturati tutti
i requisiti del sistema che si vuole realizzare.

LSRS viene realizzato per diversi motivi:

1. Ha lo scopo di aiutare a capire e comunicare i requisiti del sistema, spiegando sia il dominio applicativo, sia il
sistema che si vuole realizzare.
2. Spesso ha un valore contrattuale ed legato ad aspetti legali (ci che scritto nellSRS rappresenta un impegno
formale e vincolante da parte di chi desidera fornire il software).
3. Rappresenta la base per la pianificazione del progetto e per la stima della sua durata e dei suoi costi.
4. Rappresenta la base per effettuare le attivit di test, verifica e validazione. LSRS dovrebbe infatti contenere
informazioni sufficienti per verificare se il sistema finale effettivamente soddisfa i requisiti contenuti nellSRS
stesso.
5. una base per il controllo dei cambiamenti dei requisiti e, di conseguenza, del software.

A chi si rivolge lSRS?


Il documento SRS rivolto ad un insieme piuttosto vasto di figure diverse, con caratteristiche molto distanti tra loro:

1. Clienti e utenti, interessati soprattutto agli obiettivi che riguardano la validazione del sistema e alla descrizione di
alto livello delle funzionalit che il sistema fornir.
2. Analisti del sistema e dei requisiti, che devono scrivere le specifiche di altri sistemi correlati a quello descritto
nellSRS stesso.
3. Sviluppatori e programmatori, che devono fare in modo che limplementazione del software soddisfi i requisiti.
4. Tester, che dovranno verificare se i requisiti sono soddisfatti dallimplementazione del software.
5. I manager del progetto, che devono analizzare, misurare e controllare il processo di sviluppo.

36
Ingegneria del Software 2 Capitolo 5: Ingegneria dei requisiti

Chi scrive lSRS?


LSRS potrebbe essere scritto da categorie diverse di persone:

Chi richiede il sistema software


In questo caso, lSRS deve essere abbastanza generale per raccogliere un buon numero di offerte di
implementazione, ma non troppo, cos da escludere le offerte non ragionevoli. LSRS inoltre una vera e propria
richiesta di proposte di implementazione, che verranno poi fornite dagli sviluppatori.

Chi fornir il sistema software


LSRS in tal caso una proposta di implementazione di un sistema, abbastanza specifica per dimostrarne la
fattibilit, ma anche abbastanza generale, in modo che lorganizzazione che deve fornire il software e che sta
scrivendo lSRS non si impegni in modo eccessivo, imponendo requisiti difficili da implementare.

Uno sviluppatore selezionato


In questa situazione, lSRS riflette il modo in cui lo sviluppatore ha compreso le esigenze del cliente e costituisce
la base per la valutazione delle prestazioni contrattuali.

Una persona indipendente ed esterna


Ovvero, una parte terza rispetto alle due parti interessate dal contratto.

Lo standard dellIEEE suggerisce che lSRS venga scritto congiuntamente da chi richiede il sistema e chi intende
fornirlo.

I contenuti dellSRS
Il documento SRS dovrebbe contenere le seguenti informazioni:

Funzionalit
Lelenco delle funzionalit che il software dovr supportare (ci che il software far).

Interfacce esterne
Il modo attraverso il quale il software interagisce con le persone, con lhardware del sistema, ma anche con
componenti hardware e software esterni.

Performance
La velocit del software, la disponibilit, i tempi di risposta, il tempo di ripristino delle diverse funzionalit dopo
un fallimento,

Attributi
Occorre definire la portabilit, la correttezza, la manutenibilit, la sicurezza, del software.

Vincoli di design sullimplementazione


Bisogna elencare gli standard da utilizzare, la lingua dellimplementazione, le politiche per lintegrit del
database, i limiti delle risorse, lambiente operativo, .

37
Capitolo 5: Ingegneria dei requisiti Ingegneria del Software 2

La struttura dellSRS secondo lo standard IEEE


LIEEE ha definito una struttura standard per il documento SRS, che prevede le seguenti sezioni:

1. Introduction
1.1. Purpose
1.2. Scope identificazione del prodotto e del dominio applicativo
1.3. Definitions, acronyms, abbreviations
1.4. Reference documents
1.5. Overview descrizione dei contenuti e della struttura dellSRS
2. Overall Description
2.1. Product perspective descrizione di tutte le interface esterne e dei vincoli hardware
2.2. Product functions riassunto delle funzionalit pi importanti
2.3. User characteristics
2.4. Constraints qualsiasi vincolo che limiti le opzioni a disposizione degli sviluppatori
2.5. Assumptions and Dependencies
3. Specific Requirements
3.1. External Interface Requirements
3.1.1. User Interfaces
3.1.2. Hardware Interfaces
3.1.3. Software Interfaces
3.1.4. Communication Interfaces
3.2. Functional Requirements pu essere organizzata per modalit, tipologia di utenti, caratteristica,
3.2.1. User Class 1
3.2.1.1. Functional Requirement 1.1

3.2.2. User Class 2
3.2.2.1. Functional Requirement 1.1

...
3.3. Performance Requirements
3.4. Design Constraints
3.4.1. Standards compliance
3.4.2. Hardware limitations

3.5. Software System Attributes
3.5.1. Reliability
3.5.2. Availability
3.5.3. Security
3.5.4. Maintainability
3.5.5. Portability
3.6. Other Requirements
Appendices
Index

38
Ingegneria del Software 2 Capitolo 5: Ingegneria dei requisiti

Qualit di un SRS
Vediamo ora quali sono le caratteristiche di un buon SRS:

Completezza
Il documento SRS deve essere completo:

a) Per quanto riguarda gli obiettivi (goal). Bisogna infatti individuare tutti gli obiettivi rilevanti, compresi quelli
che riguardano la qualit. Bisogna inoltre individuare tutte le propriet di dominio, e tutte in maniera
corretta.
Altrimenti, anche se la condizione:

soddisfatta, i requisiti non saranno dei buoni requisiti.


b) Per quanto riguarda gli input: il comportamento del software deve essere definito per ogni possibile input.
c) Deve inoltre avere la cosiddetta completezza strutturale (non ci devono essere caratteristiche ancora da
discutere).

Pertinenza
1. Ogni requisito o assunzione di dominio deve essere necessario per il raggiungimento di un certo obiettivo.
2. Ogni obiettivo davvero necessario per gli stakeholder.
3. NellSRS non vengono specificate informazioni che non riguardano i requisiti (come ad esempio informazioni
relative al design).

Consistenza
Non devono esserci contraddizioni tra i vari obiettivi, propriet di dominio e/o requisiti.

Mancanza di ambiguit
1. Il dizionario non deve essere ambiguo: ogni termine deve essere definito e utilizzato coerentemente.
2. Le asserzioni non devono lasciar spazio ad interpretazioni diverse tra loro.
3. Ogni requisito deve essere verificabile mediante un opportuno processo.
4. La separazione tra le responsabilit del S2B e quelle dellambiente deve essere chiaramente definita.

Fattibilit
Gli obiettivi e i requisiti definiti allinterno dellSRS devono essere realizzabili allinterno dei limiti di budget e di
tempo che sono stati imposti alla realizzazione del progetto.

Comprensibilit
Il documento SRS deve essere comprensibile da tutte le parti interessate.

Tracciabilit
1. Occorre indicare da dove provengono gli obiettivi, i requisiti e le assunzioni;
2. Si deve evidenziare quali sono i requisiti e le assunzioni che stanno al di sotto degli obiettivi;
3. necessario facilitare i riferimenti ai requisiti nella documentazione futura.

Buona struttura del documento


Il documento deve avere una struttura che ne faciliti la comprensione. Ogni elemento deve essere perci definite
prima di essere utilizzato. Inoltre, opportuno ad esempio evidenziare i collegamenti tra obiettivi, requisiti e
assunzioni.

Modificabilit
Il documento SRS deve essere facilmente adattato, esteso o contratto attraverso delle modifiche locali. Limpatto
che consegue dalla modifica di un singolo elemento dovrebbe essere facilmente valutabile.

39
Capitolo 5: Ingegneria dei requisiti Ingegneria del Software 2

Possibili errori allinterno di un SRS


Gli errori nei quali si pu incappare durante la scrittura di un SRS sono strettamente correlati alle qualit elencate:

1. Incompletezza (requisiti o obiettivi mancanti, comportamento non definito per alcuni input).
2. Requisiti inadeguati.
3. Contraddizioni.
4. Ambiguit (termini ambigui o non definiti, ambiguit espressiva nella descrizione di obiettivi, requisiti e
assunzioni, scrittura di requisiti non verificabili, ambiguit nella divisione delle responsabilit).
5. Obiettivi e requisiti non raggiungibili.
6. Presenza di rumori (presenza di elementi che non hanno a che fare con i requisiti, o di elementi inutili, inseriti
solo per conformit rispetto allo standard del documento SRS, oppure presenza di elementi ridondanti).
7. Specifica di elementi che hanno a che fare con il design e con limplementazione.
8. Mancanza di chiarezza (terminologia inventata inutilmente, presenza di frasi scritte male, )
9. Scarsa strutturazione (riferimenti ad elementi definiti in seguito, elementi definiti allultimo momento tra
parentesi, riferimenti incrociati difficili da seguire).
10. Mancanza di tracciabilit.

Osservazioni
1. La specifica dei requisiti sar necessariamente imperfetta: lingegneria dei requisiti si occupa di fornire dei modelli
che rappresentano il mondo in maniera approssimativa, e perci conterranno degli elementi poco accurati e delle
consistenze, e ometteranno delle informazioni. Attraverso lanalisi, il rischio che questi problemi comportino dei
seri rischi deve essere il pi possibile ridotto.
2. Perfezionare una specifica potrebbe essere non conveniente dal punto di vista economico: lanalisi dei requisiti ha
un costo e, a seconda del progetto in analisi, il rapporto tra costi e benefici diverso. Tuttavia, questo non deve
essere usato come scusa per non investire nellingegneria dei requisiti, perch abbiamo visto che ci potrebbe
comportare il fallimento del progetto.
3. Lo sviluppo del software non un processo sequenziale, perci lanalisi dei requisiti continua attraverso tutto il
processo di sviluppo. Inoltre, non sempre necessario scrivere anticipatamente tutti i requisiti.
4. Riscrivere i requisiti in ogni fase dello sviluppo potrebbe essere utile. Tuttavia, lindividuazione di alcuni requisiti in
ritardo potrebbe portare alla necessit di ripensare il design, e di conseguenza potrebbe significare maggiori costi
in termini di tempo, sforamento dei tempi previsti, o anche la cancellazione del progetto.
5. I requisiti non dovrebbero mai essere considerati fissi. Il loro cambiamento inevitabile, e perci deve essere
pianificato. inoltre opportuno individuare un modo per inserire periodicamente i cambiamenti.

Come derivare i requisiti dagli obiettivi?


Vediamo ora mediante un semplice esempio come possibile ricavare i requisiti dagli obiettivi. Lesempio fa
riferimento ad un tornello per il controllo dellingresso ad uno zoo.

Passo 1: descrizione di natura optativa degli obiettivi


Per prima cosa, si fornisce una descrizione di natura optativa degli obiettivi. In particolare, in questo caso si tratter di
obiettivi di safety (che mirano cio a fare in modo che non accada nulla di male allinterno del sistema):

Goal 1: In ogni istante di tempo, il numero di persone entrate attraverso il tornello non deve superare il numero di
monete depositate.

Goal 2: Il sistema non deve impedire laccesso a chi inserisce nel tornello la moneta necessaria per entrare.

40
Ingegneria del Software 2 Capitolo 5: Ingegneria dei requisiti

Passo 2: analisi del dominio


A questo punto, occorre identificare gli eventi rilevanti rispetto agli obiettivi posti. Nellesempio che stiamo
analizzando, tali eventi saranno:

1. Levento push, che si verifica quando viene fatto ruotare il tornello.


2. Levento lock, ovvero lemissione del segnale che blocca il tornello.
3. Levento unlock, cio lemissione del segnale che sblocca il tornello.
4. Levento enter, che si verifica quando lutente oltrepassa il tornello.
5. Levento coin, che corrisponde allinserimento di una monetina.

Dopodich, necessario stabilire quali di questi eventi sono condivisi tra la macchina e il mondo, e definire se sono
controllati dalla macchina oppure dal mondo.

Gli eventi push, enter e coin sono controllati dal mondo e osservati dalla macchina.
Gli eventi lock e unlock sono controllati dalla macchina e osservati dal mondo.

Lunico fenomeno non condiviso tra la macchina e lambiente levento enter, perch la macchina non in grado di
osservarlo.

Passo 3: asserzioni o propriet di dominio


Il terzo passaggio rappresentato dallindividuazione delle asserzioni o propriet di dominio, che caratterizzano il
mondo reale.

D1: Gli eventi push ed enter avvengono alternativamente, ed il primo a verificarsi levento push.

D2: Levento push sempre seguito dallevento enter.

D3: Lutente pu generare levento push solo se la macchina non in stato locked.

Passo 4: formulazione dei requisiti


A questo punto dobbiamo formulare i requisiti, partendo dagli obiettivi e dalle asserzioni di dominio, ricordando che
lobiettivo ultimo quello di ottenere un insieme di requisiti R tale che:

Ad esempio, nella situazione che stiamo analizzando, da Da D1 e G1 otteniamo:

In ogni momento t, se osserviamo prima dellistante un numero di eventi di push e un


numero di eventi di coin, allora avremo .

Da cui ricaviamo i seguenti requisiti:

R1: Gli eventi lock e unlock devono essere alternati e il primo a verificarsi deve essere levento lock.

R2: Se il tornello locked e si ha (il numero di eventi di push e il numero di eventi di coin verificatisi fino a
quel momento sono tra loro uguali), allora il tornello non pu diventare unlocked.

R3: Se il tornello unlocked e si ha , la macchina deve essere portata in stato locked.

Il secondo goal verr invece trasformato nel seguente requisito:

R4: Se la macchina si trova in stato unlocked e , la macchina non passa allo stato locked. Se invece la
macchina in stato locked e , allora la macchina deve passare allo stato unlocked.

Si pu infine verificare che i requisiti, insieme alle propriet di dominio assicurano che valgano i goal prefissati.

41
Capitolo 5: Ingegneria dei requisiti Ingegneria del Software 2

La gestione del processo


Introduzione
Dopo la trattazione teorica che abbiamo finora portato avanti, passiamo ad analizzare le modalit attraverso le quali il
processo viene gestito nella pratica. Le attivit che vengono svolte sono di due tipologie diverse:

Attivit di requirements elicitation (ovvero raccolta dei requisiti)


Si tratta di tutte quelle attivit che portano allidentificazione dei requisiti, e che comprendono:

a) Lidentificazione degli attori.


b) Lidentificazione degli scenari (cio delle modalit di interazione tra le persone e il sistema nelle diverse
circostanze).
c) Identificazione dei casi duso (che avviene sulla base degli scenari e che rappresenta unastrazione
corrispondente ad un certo insieme di scenari).

Attivit di analysis (ovvero di analisi)


Questa seconda categoria di attivit comprende tutte quelle azioni che portano ad ottenere una specifica.

Raccolta dei requisiti


Identificazione degli attori
Identificare gli attori significa individuare:

a) Quali gruppi di utenti verranno supportati dal sistema nel loro lavoro?
b) Quali gruppi di utenti riceveranno dei benefici (anche indiretti) dal sistema?
c) Quali gruppi di utenti interagiranno direttamente con il sistema?
d) Quali gruppi di utenti interagiranno con le funzionalit secondarie del sistema (come quelle di manutenzione
ed amministrazione)?
e) Quali elementi hardware e software interagiranno con il sistema?

Identificazione degli scenari


Uno scenario una descrizione a parole di ci che una persona fa e di come si deve comportare per utilizzare un
sistema informatico o unapplicazione. Si tratta in altri termini di una descrizione concreta e informale di una
singola funzionalit usata da un singolo attore.

Un esempio di scenario il seguente:

Nome: Lo studente Rossi si iscrive allesame di I.S.2 con il professore Di Nitto.


Attori: Rossi, Di Nitto.
Event flow: Rossi apre linterfaccia,

Si noti quindi che lo scenario descrive una singola istanza del tipo di azione in analisi, e non tutte le possibili
situazioni che si possono verificare, e si focalizza su uno specifico attore, non su tutte le categorie di attori, e
neppure su tutti gli attori di una specifica categoria.

Gli scenari possono essere di vario tipo. I principali sono:

a) Scenario As-Is
Si tratta di una descrizione del sistema cos come si trova prima che si realizzi il nuovo sistema (descrive cio
la situazione corrente).
b) Scenario visionario
Descrive ci che accadr quando il sistema verr utilizzato e fa capire al committente come ci si aspetta che
il sistema funzioner.

42
Ingegneria del Software 2 Capitolo 5: Ingegneria dei requisiti

Per identificare gli scenari si adottano delle euristiche, che prevedono che ci si pongano le seguenti domande:

a) Quali sono i tasks principali del sistema?


b) Quali dati verranno creati, visualizzati, memorizzati, modificati o rimossi dagli attori allinterno del sistema?
c) Quali sono i cambiamenti e gli eventi dei quali gli attori devono essere informati?
d) Di che tipo di scenario si tratta?

Per raccogliere tali dati, si possono utilizzare dei questionari da sottoporre agli utenti, oppure si pu
semplicemente scegliere di osservare il mondo e/o di intervistare gli utenti del sistema.

Identificazione degli use-case


Una volta ottenuti gli scenari, occorre cercare di mettere in atto un meccanismo di astrazione che consenta di
ottenere i casi duso, ciascuno dei quali specifica tutte le situazioni che possono verificarsi nel tentativo di
accedere ad una certa funzionalit del sistema. Per ogni sistema si avr un certo numero di use case, che
rappresentano le funzionalit principali e gli attori che tali funzionalit vedono o si aspettano di vedere.

Di conseguenza, le informazioni fondamentali che sono contenute in use case sono:

a) Il nome dello use case.


b) Lelenco degli attori partecipanti.
c) La condizione di ingresso.
d) Il flusso degli eventi che caratterizzano lo use case.
e) La condizione duscita.
f) Le eccezioni e la loro gestione.
g) I requisiti speciali (es.: propriet non funzionali, ma temporali, altri vincoli, ).

Si noti che nella definizione degli use-case opportuno seguire alcune semplici regole:

1. Ogni use case viene avviato da un attore esterno.


2. Ogni use case identificato da un nome, che rappresentato preferibilmente da un verbo in forma attiva.
3. Gli attori devono avere un nome che ne identifichi la tipologia.
4. I confini del sistema devono essere chiari e ben definiti.
5. Si devono distinguere i passi che devono essere compiuti dallattore da quelli del sistema.
6. Devono essere chiare le relazioni causali tra i vari passi.
7. Uno use-case deve essere descritto in un massimo di 2 o 3 pagine.

In generale, nella definizione dello use case opportuno iniziare dalla definizione del nome, passare poi
allidentificazione degli attori e solo in seguito occuparsi della descrizione del flusso degli eventi, utilizzando il
linguaggio naturale.

Analisi
Dopo lattivit di raccolta dei requisiti, necessaria lattivit di analisi, che consiste nella formalizzazione delle
informazioni raccolte mediante dei diagrammi UML.

1. Gli use case vengono formalizzati mediante degli use-case diagrams.


2. Le entit fondamentali vengono formalizzate mediante dei class diagrams.
3. Le relazioni tra gli use case e gli oggetti reali vengono mappate mediante dei sequence diagrams,
4. I comportamenti che dipendono da uno stato vengono rappresentati tramite degli statecharts.

Nel capitolo successivo introdurremo in maniera formale la notazione UML.

43
Capitolo 6: UML Ingegneria del Software 2

Capitolo 6: UML
Il concetto di modello
Per prima cosa, riprendiamo brevemente il concetto di modello, che uno dei concetti fondamentali dellingegneria e
che gi stato utilizzato in passato nel corso della nostra trattazione.

Definizione
Un modello una rappresentazione di qualcosa, mediante un certo mezzo. Il modello cattura gli aspetti importanti di
ci che esso stesso rappresenta e semplifica o omette gli altri aspetti. Il modello dunque la proiezione di qualcosa in
qualcosaltro, realizzato partendo dallosservazione della realt, individuando gli elementi di interesse e proiettando
solo tali elementi allinterno di una rappresentazione della realt di partenza.

Caratteristiche del modello


In un modello vengono associati agli elementi della realt delle opportune astrazioni del modello . Mediante una
funzione dinterpretazione si pu passare dagli oggetti reali alle relative astrazioni. Alle relazioni tra elementi della
realt corrispondono delle relazioni tra le relative astrazioni.

Se il modello ben costruito, il seguente diagramma sar commutativo:

Figura 17: Diagramma che rappresenta un buon modello

Scopo del modello


I modelli vengono utilizzati perch consentono di astrarre dai dettagli della realt, in modo tale da poter ottenere
conclusioni complesse nella realt mediante dei semplici passi allinterno del modello.

I modelli consentono inoltre di ottenere una comprensione del passato o del presente e di effettuare delle previsioni
riguardanti il futuro.

Linguaggio di modellazione
Un linguaggio di modellazione un linguaggio artificiale che viene utilizzato per esprimere informazioni o conoscenze
o per rappresentare sistemi secondo una struttura che definita mediante un insieme consistente di regole.

Il linguaggio di modellazione caratterizzato da una particolare notazione e da una certa semantica, che attribuisce un
significato alle frasi di tale linguaggio (ovvero ai modelli espressi nel linguaggio stesso).

Semantica e notazione
La semantica cattura il significato di un modello. Essa viene utilizzata per generare il codice a partire dal modello
stesso, ma anche per valutare il modello, per controllarne la validit, .

La notazione invece linsieme di regole che permettono di scrivere il modello, consentendo cio di organizzare le
informazioni semantiche in modo che possano essere visualizzate ed editate.

44
Ingegneria del Software 2 Capitolo 6: UML

Aspetti critici derivanti dalluso dei modelli


Nellutilizzare i modelli si deve per tener conto anche di alcuni possibili problemi:

1. Lastrazione pu a volte scontrarsi con la necessit di esprimere molti dettagli; bisogna perci scegliere con molta
cura, durante la stesura del modello, quali sono gli aspetti che devono essere ignorati e quali no.
2. Il modello pu descrivere sia ci che il sistema deve fare (modello per la specifica), sia come lo deve fare (modello
per limplementazione). Bisogna scegliere con criterio quale tipo di modello usare.
3. I modelli sono delle descrizioni, e non delle istanze (che vengono invece usate come esempi).
4. Le diverse viste di uno stesso modello devono essere coerenti.
5. Talvolta diverse interpretazioni di un modello sono possibili. In questo caso bisogna intervenire per specificare
qual linterpretazione corretta.

I modelli dei sistemi software


A questo punto possiamo vedere come il concetto di modello possa essere utilizzato per i nostri scopi.

Modello di un sistema software


Un modello di un sistema software una rappresentazione del sistema, realizzata secondo uno specifico punto di
vista, espressa in un opportuno linguaggio di modellazione e pi semplice da gestire rispetto al sistema reale (almeno
per quanto riguarda uno specifico scopo).

Perch utilizzare dei modelli software?


Nellingegneria del software, i modelli vengono utilizzati per una serie di scopi diversi:

1. Per catturare e indicare in maniera precisa i requisiti e le conoscenze di dominio.


2. Sono un supporto alla fase di design (progettazione dellarchitettura) del sistema software.
3. Danno una visione semplificata di sistemi complessi.
4. Permettono di valutare e simulare il comportamento di un sistema.
5. Vengono usati per generare una serie di diverse configurazioni possibili di un sistema.

UML: concetti generali


Che cos UML?
LUML (acronimo di Unified Modelling Language) un linguaggio di modellazione grafico a carattere generale (non
destinato solo allIngegneria del software), utilizzato per la specifica, la progettazione, la visualizzazione e la
documentazione di sistemi discreti (soprattutto di tipo software).

UML stato progettato in modo da essere supportato da tool software appositi. Esso ha una struttura statica che
consente per di rappresentare un comportamento dinamico.

Le diverse viste supportate da UML


UML comprende 13 diverse tipologie di diagrammi, che possono essere classificati in:

Diagrammi (o viste) strutturali


Si tratta di diagrammi che descrivono la struttura del sistema. Appartengono a questa categoria i Class diagrams,
gli Object diagrams, i Component diagrams, .

Diagrammi (o viste) comportamentali


Si tratta di diagrammi che descrivono il comportamento del sistema. Appartengono a questa categoria gli State
diagrams, gli Activity diagrams, gli Use case diagrams, ... .

Diagrammi (o viste) interattivi


Descrivono come si interagisce col sistema. Ad esempio, i Sequence diagrams appartengono a questa categoria.
Si tratta in realt di particolari diagrammi comportamentali.

45
Capitolo 6: UML Ingegneria del Software 2

La tassonomia dei diagrammi UML rappresentata dalla seguente figura:

Figura 18: Tassonomia dei diagrammi UML

Come utilizzare UML?


UML pu essere utilizzato fondamentalmente in 2 modi diversi, anche se opportuno evidenziare che la distinzione
spesso molto confusa:

UML come strumento per realizzare abbozzi (sketch)


In questo caso, la caratteristica fondamentale che viene sfruttata quella della selettivit: si realizzano dei diagrammi
UML che rappresentano solo delle porzioni del codice che si andr a realizzare, al fine di comunicare, spesso in modo
informale e dinamico, le diverse idee e alternative a disposizione. Questo luso di UML che viene pi
frequentemente fatto.

UML come strumento per realizzare modelli dettagliati (blueprint)


In altri casi, i diagrammi UML vengono realizzati cercando di ottenere la massima completezza, al fine di realizzare un
modello che fornisca una descrizione dettagliata comprendente tutte le decisioni che sono state prese. In alcuni casi si
sceglie di utilizzare UML in questo modo solo per particolari aree dellintero progetto. Se si adotta questo approccio, la
programmazione verr poi ridotta ad una procedura quasi meccanica.

I class diagram
Che cosa sono i class diagram?
I diagrammi delle classi (o class diagram) sono i diagrammi base di UML. Esso sono strettamente legati ai concetti della
programmazione orientata agli oggetti, e vengono usati per rappresentare in maniera le classi che costituiscono il
software, con i relativi attributi ed operazioni; tali classi verranno poi istanziate in oggetti. Il loro obiettivo quello di
fornire una rappresentazione statica del sistema. I diagrammi delle classi possono anche essere usati per
rappresentare dei concetti non di tipo software, e comunque non hanno legami con un particolare linguaggio di
programmazione.

Il diagramma delle classi specifica, mediante le associazioni, i vincoli che legano tra loro le classi. Si osserva inoltre che
pu essere definito a diversi livelli (analisi, disegno di dettaglio).

46
Ingegneria del Software 2 Capitolo 6: UML

Rappresentazione delle classi


La classe
Una classe viene rappresentata allinterno di un class diagram mediante un rettangolo, che a sua volta suddiviso in
tre parti, come mostrato in figura:

Figura 19: Rappresentazione di una classe allinterno di un class diagram

Il nome permette di identificare lelemento del quale stiamo parlando, gli attributi consistono nellelenco degli
elementi che ci consentono di definire i singoli oggetti appartenenti a tale classe e i metodi descrivono il loro
comportamento. La rappresentazione della classe pu anche essere accompagnata da un commento, riportato a lato,
allinterno di un riquadro che rappresenta in maniera stilizzata un foglietto. Ad esempio, potremo avere:

Figura 20: Esempio di classe rappresentata mediante la notazione dei class diagram

Accanto al nome della classe possiamo anche indicare in parentesi graffe le sue propriet (ad esempio, possiamo
indicare abstract se si tratta di una classe astratta).

Gli attributi
Come mostrato nel precedente esempio, gli attributi vengono elencati con un particolare formato, che il seguente:

<Visibilit> <Nome Attributo>: <Tipo Attributo> <molteplicit> = <Valore di default> {<Stringa di propriet>}

Dove il campo <Visibilit> pu assumere i valori indicati in tabella, con il significato riportato a lato:

Notazione Significato
Indica che lattributo ha visibilit private.
+ Indica che lattributo ha visibilit public.
# Indica che lattributo ha visibilit protected.
~ Indica che lattributo ha visibilit friendly.
Tabella 1: Notazione adottata per indicare la visibilit allinterno dei class diagram UML

La stringa di propriet pu ad esempio assumere valori come changeable, froze, addonly, . La molteplicit pu
invece assumere dei valori del tipo [0..1], per indicare che la molteplicit compresa tra 0 e 1, [1], per indicare che la
molteplicit uno (se lo si omette, si considera sottinteso che si abbia [1]), oppure [*], che significa che la molteplicit
0, 1, o un qualsiasi numero maggiore di 1.

Il significato dei restanti campi invece molto intuitivo. Naturalmente, se non si ha alcun valore di default, la parte ad
esso relativa viene semplicemente omessa.

invece opportuno osservare che tramite la notazione UML anche possibile mettere in evidenza quando un
attributo costante: in tal caso infatti lattributo sottolineato.

47
Capitolo 6: UML Ingegneria del Software 2

I metodi (o operazioni)
Il formato attraverso il quale vengono specificati i metodi invece il seguente:

<Visibilit> <Nome Metodo>(<Lista di Parametri>): <Tipo di ritorno> {Stringa di propriet}

Dove il campo <Visibilit> pu assumere gli stessi valori (e con lo stesso significato) che abbiamo gi elencato quando
abbiamo descritto la notazione per gli attributi. Gli altri campi hanno invece un significato intuitivo. per bene
descrivere in maniera dettagliata il formato attraverso il quale viene specificata la lista di parametri: i parametri sono
separati da virgola, e per ciascuno di essi scriveremo:

<Direzione> <Nome Parametro> : <Tipo Parametro>

Il campo <Direzione> facoltativo, e pu assumere i valori in, out oppure inout (con ovvio significato). Quando tale
campo omesso, si sottintende che il parametro sia semplicemente un parametro in input.

Le relazioni
Attraverso i class diagram possono anche essere messe in evidenza le relazioni tra le classi. Tali relazioni sono di due
tipi: generalizzazione e associazione. Particolari tipi di associazione sono poi la composizione e laggregazione.

Generalizzazione
Rappresentazione della generalizzazione
Il concetto UML di generalizzazione corrisponde a quello di ereditariet, tipico dei linguaggi di programmazione ad
oggetti. La generalizzazione si rappresenta in UML come mostrato nellesempio seguente:

Figura 21: Esempio di generalizzazione

Dove si indica che Triciclo eredita da Bicicletta e che Bicicletta eredita da VeicoloTerrestre e da VeicoloAPedali.
Sappiamo che questultima situazione in Java non pu esistere, perch non si ha ereditariet multipla; occorre tuttavia
ricordare che UML non legato a Java e che in altri linguaggi di programmazione possibile realizzare lereditariet
multipla.

Nelle classi che ereditano da unaltra, naturalmente, verranno indicati solamente metodi ed attributi aggiuntivi e non
quelli ereditati dalla superclasse (in quanto sono impliciti).

Rappresentazione della interfacce


Le interfacce in UML possono essere rappresentate in due diversi modi. Il primo modo prevede semplicemente che si
usi la stessa rappresentazione adottata per le classi, ma escludendo la parte relativa agli attributi e aggiungendo la
scritta <<interface>> appena prima del nome, come nel seguente esempio:

Figura 22: Esempio di rappresentazione di interfacce mediante una delle possibili notazioni UML

48
Ingegneria del Software 2 Capitolo 6: UML

Come mostrato nellesempio, limplementazione di una classe indicata cos come la generalizzazione (ereditariet),
ma con linea tratteggiata. Analogamente, le associazioni che coinvolgono linterfaccia (come quella tra
FiguraGeometrica e List) sono indicate con una linea tratteggiata.

Esiste poi una seconda rappresentazione semplificata, che la seguente, e che stata introdotta pi tardi rispetto alla
prima, con lobiettivo di sostituirla:

Figura 23: Esempio di rappresentazione di interfacce mediante una delle possibili notazioni UML

Tale rappresentazione per meno chiara, perch non indica esplicitamente i metodi definiti nellinterfaccia.

Associazioni
Le associazioni sono delle relazioni tra classi, di qualsiasi tipo purch non di generalizzazione. Ad esempio, possiamo
pensare ad una classe Persona e ad una classe Azienda: possibile che una persona sia messa in relazione allazienda
perch lavora per essa, perci avremo unassociazione tra Persona e Azienda.

Come rappresentare le associazioni


Le associazioni vengono rappresentate mediante delle linee che congiungono le classi interessate dallassociazione
stessa. Su tale linea viene inoltre indicata una parola per descrivere la tipologia di associazione (solitamente un verbo:
nel precedente esempio, potremmo usare lavorare).

Inoltre, si pu opzionalmente indicare una descrizione dei ruoli svolti dalle singole classi allinterno dellassociazione,
mediante un nome (come mostrato nella figura seguente, dove tali termini sono dipendenti e azienda).

Gli estremi della classe prevedono che si indichi una cardinalit (o molteplicit): su ogni estremo troveremo
unindicazione del tipo: 1 (esattamente 1), oppure 0..1 (zero o 1), oppure 1..*, (uno o pi), 0..* (zero, uno o pi di
uno), n (dove n un numero qualsiasi, indica esattamente n), n1-n2 (dove n1 e n2 sono numeri qualsiasi, purch n2 >
n1: indica minimo n1, massimo n2). La figura seguente mostra un esempio.

Figura 24: Esempio di utilizzo della relazione di associazioni tra classi in un UML class diagram

Nel precedente diagramma, le cardinalit indicano che zero o pi persone possono lavorare per una stessa azienda,
ma una persona lavora esattamente per unazienda (non ci sono disoccupati!).

possibile anche che ci sia unassociazione riflessiva (come nellesempio a lato), ovvero nella quale entrambe le
estremit ricadono sulla stessa classe.

Figura 25: Esempio di associazione riflessiva in un UML class diagram

49
Capitolo 6: UML Ingegneria del Software 2

Come si traducono le associazioni: luso delle frecce


Le associazioni si traducono concretamente attraverso linserimento di opportuni attributi. In particolare, ogni
estremo un attributo implicito: se la cardinalit 0..1 oppure 1, allora lattributo sar semplicemente una variabile
di tipo di riferimento allaltra classe interessata dallassociazione, altrimenti si tratter di un array o di una collezione.

Tuttavia, inserire un attributo aggiuntivo da entrambe le parti ridondante: ci potrebbe comunque rivelarsi comodo,
per facilitare ad esempio le operazioni di ricerca, ma talvolta lo si vuole evitare. In questo caso, si inserisce sulla linea
che rappresenta lassociazione una freccia. La classe verso la quale rivolta la freccia non conterr attributi aggiuntivi
per memorizzare lassociazione.

Ad esempio:

Figura 25: Esempio di traduzione di unassociazione allinterno di un class diagram in codice Java

Le aggregazioni e le composizioni
Le aggregazioni
Come accennato, le aggregazioni sono una forma particolare di associazione; in particolare, si tratta di associazioni
nelle quali una classe in relazione con unaltra perch una di esse rappresenta una parte dellaltra. Diciamo quindi
che si mettono in relazione un oggetto con una sua parte.

In sintesi quindi le aggregazioni servono per indicare quando un oggetto costruito da altri oggetti.

Le aggregazioni vengono rappresentate mediate delle linee (come le normali associazioni), alle quali per non
associato un verbo (perch scontato il tipo di relazione tra le due classi); si utilizza per un rombo bianco in
prossimit della classe che rappresenta loggetto completo. Si indicano comunque le cardinalit, come nelle normali
associazioni.

Figura 26: Esempio di aggregazione

50
Ingegneria del Software 2 Capitolo 6: UML

Le composizioni
Le composizioni poi sono un caso particolare di aggregazione: una composizione infatti unaggregazione forte,
ovvero unaggregazione nella quale le parti componenti non esistono senza il contenitore. Ci significa che la
creazione e la distruzione dei componenti avvengono allinterno del contenitore e che i singoli componenti non
possono essere parti di altri oggetti. Quindi, se si distrugge una parte, non si distrugge il tutto, ma se si distrugge il
tutto, si distruggono anche tutte le parti.

In Java le composizioni di fatto non vengono usate. In ogni caso, aggregazioni e composizioni vengono poi tradotte allo
stesso modo al momento di stendere il codice.

La rappresentazione di una composizione del tutto analoga a quella dellaggregazione, con lunica differenza che il
rombo in questo caso annerito.

Figura 27: Esempio di composizione

I package
In UML, cos come in Java, esiste il concetto di package. Un package un meccanismo generale per organizzare degli
elementi in gruppi omogenei. Un package pu contenere altri package, e inoltre possono esserci delle relazioni tra i
vari package.

Si osserva per che il concetto di package in UML diverso da quello in Java: in UML possiamo infatti instaurare anche
relazioni di dipendenza e di generalizzazione (ereditariet) tra package. Ad

Di seguito riportato un esempio di rappresentazione di package, dove sono mostrate anche una relazione di
generalizzazione e una di dipendenza (tipicamente ci significa che il package JavaCompiler accede al package Java).

Figura 28: Esempio di uso dei package

Componenti
I componenti sono invece utili per decomporre il sistema in esame. Essi sono cos rappresentati:

Figura 29: Esempio di uso dei componenti

I quadrati ai margini del componente rappresentano delle porte, che implementano delle interfacce e dei protocolli
opportuni per la comunicazione con lesterno.

51
Capitolo 6: UML Ingegneria del Software 2

Object diagram
Gli object diagram sono molto simili ai class diagram, ma prevedono che si risolvano le molteplicit, scegliendo cio il
numero di oggetti da istanziare. Gli oggetti vengono rappresentati mediante dei rettangoli. Allinterno del rettangolo
indicato il nome dellistanza, seguito dal suo tipo, separato dal nome mediante i due punti.

Figura 30: Esempio di object diagram

Use case diagram


Cosa sono?
I diagrammi dei casi duso (use case diagram) sono dei diagrammi che definiscono le funzionalit offerte dal sistema e
le modalit attraverso le quali il sistema agisce e reagisce.

In particolare, i diagrammi dei casi duso descrivono:

1. Il sistema;
2. Lambiente;
3. Le relazioni tra il sistema e lambiente.

Lo use case diagram viene realizzato prima del class diagram, al fine di catturare i requisiti e le funzionalit necessarie
(indicando per solo quelle visibili). Il sistema pu essere definito a diversi livelli di granularit.

In particolare, lo use case diagram consente di:

1. Organizzare i requisiti in macro-funzionalit.


2. Definire relazioni tra le diverse funzionalit.
3. Definire il ruolo assunto dai vari attori.
4. Definire le interazioni tra gli utenti e il sistema.

La terminologia usata in questi diagrammi la terminologia del dominio applicativo, non quella del sistema
informatico.

Gli elementi dello use case diagram


Sulla base di quanto abbiamo appena detto, uno use case diagram costituito dai seguenti elementi:

1. Il sistema;
2. Gli use case;
3. Gli attori;
4. Le relazioni tra gli attori e gli use case;
5. Le relazioni tra use case e use case.

52
Ingegneria del Software 2 Capitolo 6: UML

Il sistema e gli use case


Gli use case elencano le funzionalit a disposizione, che vengono fornite dal sistema. In uno use case diagram il
sistema identificato da un rettangolo che racchiude gli use case relativi alle funzionalit fornite. Il rettangolo
accompagnato da una label, allinterno della quale indicato il nome del sistema stesso.

SISTEMA
Ambiente
esterno

Figura 31: Rappresentazione del sistema allinterno di uno use case diagram

Il rettangolo che rappresenta il sistema quindi separa ci che allinterno del sistema stesso da ci che invece
appartiene al mondo esterno.

Allinterno del sistema vengono indicati gli use case, ciascuno dei quali rappresenta una particolare funzionalit messa
a disposizione dal sistema stesso. Il punto di vista con il quale devono essere definiti gli use case sempre quello
dellutilizzatore. Ogni use case rappresentato mediante un ovale allinterno del quale viene indicato il nome dello
use case stesso.

SISTEMA

nome use case

Figura 32: Rappresentazione di uno use case allinterno di uno use case diagram

Attori
Come accennato, gli attori sono gli utilizzatori del sistema. Ogni attore rappresentato mediante il seguente simbolo,
con unetichetta nella quale riportato il nome (o una descrizione) dellattore stesso:

Attore

Figura 33: Rappresentazione di un attore

Pi nel dettaglio, possiamo dire che un attore unentit esterna (una persona, ma potrebbe anche essere un sistema
hardware esterno) che interagisce con il sistema, assumendo un certo ruolo e che:

1. Controlla le funzionalit del sistema informativo;


2. Fornisce input o riceve output dal sistema.

Da quanto detto, consegue che:

1. Possono esserci diversi attori con lo stesso ruolo, ma anche diversi ruoli con lo stesso attore;
2. Diversi attori possono esercitare su uno stesso use case.

Gli attori possono essere il mezzo per individuare gli use case (si individua cio una lista di attori). Nellinterazione tra
attore e sistema, lattore pu rivestire un ruolo attivo (cio richiede delle funzionalit) oppure passivo (cio il
sistema che, per svolgere una sua funzione, ha bisogno dellattore).

53
Capitolo 6: UML Ingegneria del Software 2

Relazioni tra gli elementi di uno use case diagram


Abbiamo introdotto gi tutti gli elementi che possono comparire in uno use case diagram. Tuttavia, la parte forse pi
significativa di uno use case diagram rappresentata dai legami che esistono tra tali elementi, e che possono essere di
tre tipi:

1. Legami tra diversi use case dello stesso sistema;


2. Legami tra uno use case ed un attore;
3. Legami tra attori.

Legami tra attori e use case: associazione


Iniziamo analizzando il modo in cui possono essere legati tra loro un attore ed uno use case. Tale relazione, detta
associazione, una relazione di uso: lattore nei confronti dello use case pu essere il beneficiario, il controllore,
pu essere informato, .

Lassociazione si rappresenta mediante un semplice segmento:

SISTEMA

nome use
case
Attore

Figura 34: Rappresentazione di unassociazione tra un attore e uno use case

Lassociazione pu anche avere un verso, che rappresentato orientando il segmento mediante una freccia. In
particolare, la freccia va verso lo use case se lattore il soggetto attivo dellassociazione (cio lattore a richiedere la
funzionalit), mentre ha verso opposto se lattore soggetto passivo (cio lo use case che richiede lintervento
dellattore). Ad esempio:

PRENOTAZIONE VIAGGIO

Ricercare
viaggio

Prenotare
viaggio

Cliente

Pagare
viaggio

Figura 35: Rappresentazione di unassociazione orientata tra un attore e uno use case

54
Ingegneria del Software 2 Capitolo 6: UML

Legami tra diversi use case


Nel precedente esempio, abbiamo definito un sistema con 3 funzionalit completamente scollegate tra loro, senza che
sia definito alcun ordine tra di esse (si noti che negli use case non interviene mai la variabile tempo). Tuttavia, tale
situazione non modella efficacemente la realt. Possiamo allora introdurre delle relazioni tra gli use case, le quali
mettano in evidenza dei legami tra di essi. Questi tipi di legami possono essere di vario tipo:

Inclusione
Linclusione, rappresentata dallo stereotipo includes, si rappresenta come:

SISTEMA

Nome use includes Nome use


case 1 case 2

Figura 36: Rappresentazione di una relazione di inclusione tra due use case

In questo tipo di legame, lo use case dal quale ha origine la freccia ha bisogno, per poter essere completato,
dellesecuzione della funzionalit descritta dallo use case al quale arriva la freccia. In altri termini, lo use case
sorgente utilizza quello di arrivo.

La relazione di inclusione stata introdotta perch spesso esistono use case che rappresentano delle attivit
ricorrenti, condivise tra use case pi complessi; per evitare di ripetere in ogni use case la descrizione dellattivit
comune, la si mette a fattor comune, indicando che viene inclusa in uno o pi use case pi complessi (il meccanismo
quindi analogo a quello della chiamata ad una sottoprocedura).

Un altro motivo per il quale linclusione viene utilizzata che la funzionalit corrispondente ad uno use case troppo
complessa per essere risolta in maniera immediata, perci viene tale funzionalit viene descritta come laggregazione
tra un insieme di funzionalit pi semplici. Tale procedimento detto decomposizione funzionale. Gli use case
corrispondenti alla funzionalit originaria e alle sue sottofunzionalit sono legati perci da una relazione di inclusione.

Figura 37: Esempio di utilizzo della relazione di inclusione

Estensione
La relazione di estensione tra due use case si verifica quando si dispone gi di uno use case, che per deve essere
esteso, mediante cio laggiunta di ulteriori operazioni da compiere. Lo use case di partenza completo di per s,
ma in alcuni scenari necessita di essere esteso come mostrato dallo use case che lo estende. Di conseguenza, risulta
chiaro che lo use case di base pu essere eseguito anche senza lesecuzione dellaltro use case. Lestensione
rappresenta quindi solo una variazione dal comportamento standard.

55
Capitolo 6: UML Ingegneria del Software 2

Lestensione rappresentata dallo stereotipo extends. Si noti che lo use case di base deve fornire dei punti di
estensione e che lo use case di estensione pu aggiungere comportamento a quello di base solo per quanto riguarda
le funzionalit del punto di estensione.

Figura 38: Esempio di utilizzo della relazione di estensione

Per comprendere il concetto di punto di estensione, consideriamo la seguente figura:

extends
1 2
A A

B B

C C

Figura 39: Estensione e punto di estensione

In questo caso, abbiamo un oggetto 1 e un oggetto 2, il cui comportamento diverso. Tuttavia, entrambi hanno lo
stesso obiettivo, solo che 2 lo raggiunge in maniera parzialmente diversa rispetto ad 1 (anzich eseguire C, esegue C).
Diciamo quindi (in base a come abbiamo orientato la freccia) che 2 lestensione di 1, mentre 1 lesteso. In UML
dovremmo rappresentare questa situazione nella maniera seguente:

SISTEMA
1 C

extends
C

Figura 40: Rappresentazione completa di una relazione di estensione tra use case

Dove 1 il nome dello use case, mentre C il punto di estensione (cio lelemento che pu essere sostituito).
Tuttavia, per maggiore semplicit, si usa spesso la notazione seguente, in cui si finge che il punto di estensione
coincida con lintera attivit.

SISTEMA
1
extends

Figura 41: Rappresentazione semplificata di una relazione di estensione tra use case

56
Ingegneria del Software 2 Capitolo 6: UML

Generalizzazione tra use case


anche possibile definire una relazione di generalizzazione tra due use case. In questo caso, lo use case figlio eredita
tutti gli attributi, scenari definiti nello use case padre (ricalca il concetto di ereditariet della programmazione ad
oggetti). Inoltre, lo use case figlio partecipa a tutte le relazioni in cui coinvolto lo use case padre e pu prevedere
nuovi scenari non previsti nello use case padre. Uno use case pu ereditare da n altri use case e pu essere il padre di
n altri use case.

La generalizzazione si utilizza quando si identifica un comportamento comune tra due use case e lo si vuole
fattorizzare. Di seguito mostrato un esempio di generalizzazione.

CheckPassword

ValidateUser

CheckFingerprint

Figura 42: Esempio di generalizzazione tra use case

Legami tra attori: generalizzazione


Lunico possibile legame tra due attori quello di generalizzazione. La generalizzazione tra attori si rappresenta nel
modo seguente:

Padre Figlio

Figura 43: Rappresentazione della generalizzazione tra attori

Lattore figlio eredita tutte le caratteristiche dellattore padre e pu partecipare a tutti gli use case a cui partecipa
lattore padre.

Descrizione degli use case


Oltre al semplice diagramma nel quale sono indicati tutti gli specifici casi duso, necessario indicare, per ogni use
case,una relativa descrizione, con associati ad essa uno o pi scenari. Le informazioni che devono essere elencate
allinterno della descrizione dello use case sono state gi discusse nel precedente capitolo.

57
Capitolo 6: UML Ingegneria del Software 2

Sequence diagram
Cosa sono?
I sequence diagram (diagrammi di sequenza) sono dei particolari interaction diagrams di UML, i quali consentono,
come suggerisce il nome stesso, di rappresentare linterazione tra oggetti, materializzando cos degli scenari specifici.
In particolare, essi evidenziano il modo in cui uno scenario (ovvero uno specifico percorso in un caso duso) viene
risolto dalla collaborazione tra un insieme di oggetti. Per fare, ci, specifica la sequenza dei messaggi scambiati tra gli
oggetti. I diagrammi di sequenza possono specificare nodi decisionali e iterazioni.

Da quanto appena detto segue che in questo caso, a differenza di quanto accade con gli use case diagram, si parla di
istanze specifiche del sistema e ci si sofferma ad analizzare la cooperazione non tanto tra categorie di elementi, ma tra
specifici partecipanti (oggetti, o attori, ).

Tali diagrammi sono utili per vari motivi:

1. In fase di analisi, consentono di modellare un flusso di eventi allinterno di uno use casse.
2. In fase di design, permetto dono di identificare quali partecipanti faranno parte della soluzione finale.
3. In fase di validazione, servono per validare linterazione tra i partecipanti scelti.

I diagrammi di sequenza sono di tipo bidimensionale: orizzontalmente vengono rappresentati i partecipanti

Come si realizzano i diagrammi di sequenza


I diagrammi di sequenza prevedono che ci sia una linea verticale, che rappresenta la linea del tempo, mentre in
orizzontale sono disposti i vari oggetti. Oltre agli oggetti, viene rappresentato anche lutente (il cliente), mediante la
stessa notazione adottata per rappresentare gli attori in uno use case diagram.

Quando ad un oggetto corrisponde una linea verticale tratteggiata, significa che quelloggetto esiste, ma passivo
(cio non fa nulla); se invece la linea verticale doppia, significa che loggetto attivo. Infine, se la linea non
presente, significa che loggetto non ancora stato creato, oppure stato distrutto (sappiamo che in Java gli oggetti
non vengono realmente distrutti, perch ci penser poi il garbage collector, per possiamo considerare tale istante, a
livello logico, come listante in cui si perde il riferimento a quelloggetto).

Le interazioni tra oggetti vengono rappresentate mediante frecce, sulle quali riportato un nome o un verbo che
specifica il tipo di interazione. Il significato delle frecce descritto in tabella:

Tipo di freccia Significato

Invio di un messaggio sincrono.

Invio di un messaggio asincrono.

Invio di una risposta ad un messaggio.

X Invio di un messaggio di distruzione di un oggetto.

partecipante
Invio di un messaggio di creazione di un oggetto.

Tabella 2: Significato dei diversi tipi di freccia che si presentano allinterno di un sequence diagram

58
Ingegneria del Software 2 Capitolo 6: UML

Ad esempio, se vogliamo rappresentare la sequenze per la prenotazione di un volo, disegneremo il diagramma


mostrato in figura 44. La figura 45 mostra un secondo esempio di sequence diagram.

Figura 44: Esempio n. 1 di sequence diagram Figura 45: Esempio n. 2 di sequence diagram

Potrebbe per rivelarsi utile anche definire dei cicli, oppure delle alternative, . Per tale scopo sono stati introdotti i
frame dinterazione, che consentono appunto di specificare questo tipo di situazioni.

Alcuni dei pi usati frame di interazione sono i seguenti:

Indica unalternativa del tipo (o o): se verificata una condizione si fa una certa cosa, altrimenti se ne
alt
fa unaltra.
Indica unazione opzionale, che viene cio svolta solo se verificata una certa condizione (in caso
opt
contrario non si fa nulla).
Indica literazione di una certa operazione. La condizione di iterazione espressa da una descrizione a
loop
parole affiancata alla parola loop.
ref Indica unoperazione che descritta allinterno di un diverso diagramma.

par Indica che pi frammenti vengono eseguiti in parallelo. Il frame perci diviso a met.

neg Serve per evidenziare uninterazione non valida.


Tabella 3: Elenco dei principali frame usati nei sequence diagram

Allinterno di ogni frame si specifica poi a parole una breve descrizione che indica la condizione entro la quale certe
operazioni vengono eseguite e/o iterate. Ad esempio, possiamo usare i frame di interazione per correggere il
precedente esempio in modo tale che si eviti che nellintervallo tra la verifica di disponibilit e leffettiva prenotazione,
la disponibilit dellauto venga a mancare: tale situazione creerebbe ovviamente un errore. Possiamo allora disegnare
il seguente diagramma di sequenza:

Figura 46: Esempio di utilizzo dei frame allinterno dei sequence diagram

59
Capitolo 6: UML Ingegneria del Software 2

Activity diagram
Cosa sono?
Gli activity diagram sono molto simili ad un semplice diagramma di flusso (flow diagram): essi sono diagrammi
comportamentali che rappresentano un flusso di attivit (come ci suggerisce il loro nome), cio levoluzione del
workflow del sistema. In particolare, tali diagrammi vengono usati per descrivere il comportamento dinamico di un
sistema, fornendo la sequenza di operazioni che definiscono unattivit pi complessa. Pi precisamente, lactivity
diagram rappresenta il flusso di controllo di attivit computazionali per lesecuzione di una serie di calcoli o di un
workflow.

Lactivity diagram pu descrivere sia flussi di controllo interni al sistema, sia la comunicazione tra elementi diversi.
Inoltre, in grado di mettere in evidenza i task eseguiti in parallelo e di descrivere i flussi di dati tra attivit e oggetti.

Un activity diagram pu essere associato:

1. Ad una classe.
2. Allimplementazione di una operazione.
3. Ad uno Use case.

Gli elementi fondamentali degli activity diagram sono le attivit, le swim lane e le scelte (diamond).

Attivit
Unattivit (activity) o azione (action) un lavoro svolto da un oggetto in maniera continuativa. Le attivit possono
essere:

Attivit atomiche (action state)


Sono attivit eseguibili in maniera atomica, cio che non possono essere decomposte in una sequenza di attivit,
n possono essere interrotte.

Attivit non atomiche (activity state)


Sono attivit non eseguibili in maniera atomica: possono cio essere decomposte in una sequenza di attivit e
possono anche essere interrotte durante la loro esecuzione. Unattivit di questo tipo pu a sua volta essere
descritta mediante un activity diagram.

In entrambi i casi il simbolo usato un rettangolo con gli angoli smussati:

Nome attivit

Figura 47: Rappresentazione di unattivit allinterno di un activity diagram

Se lattivit contraddistinta da un * in alto a sinistra, significa che lattivit pu essere ripetuta pi volte. Lattivit ha
un inizio ed una fine, ed il controllo di tutto il flusso rimane allattivit per tutto il tempo che intercorre tra linizio
dellattivit e la sua fine (tempo che pu anche essere molto lungo).

Il passaggio del controllo da unattivit ad unaltra detto transizione. Ovviamente, la transizione avviene quando
termina lattivit sorgente e d il controllo allattivit di destinazione. Ogni attivit ha una transizione in ingresso ed
una transizione in uscita, entrambe rappresentate mediante frecce (quella in ingresso una freccia entrante
nellattivit, quella in uscita uscente):

Nome attivit

Figura 48: Rappresentazione di unattivit e delle relative transizioni allinterno di un activity diagram

60
Ingegneria del Software 2 Capitolo 6: UML

Inizio e fine del diagramma


Allinterno dellactivity diagram esistono anche due attivit fittizie, che sono linizio e la fine del diagramma stesso.
Linizio rappresentato mediante un cerchio pieno, mentre la fine rappresentata da un cerchio pieno allinterno di
un cerchio vuoto pi grande. Lattivit di inizio ha solo una transizione di uscita, mentre quella duscita ha solo una
transizione dingresso.

Figura 49: Attivit di inizio dellactivity diagram


Figura 50: Attivit di fine dellactivity diagram

Branch (divisione) & merge (fusion)


Un branch (o scelta, o diamond) un punto a partire dal quale il flusso di controllo si divide in due o pi cammini. Si
tratta quindi di unattivit particolare, con una sola transizione dingresso e almeno due transizioni duscita. Ad ogni
freccia duscita associata una condizione. Tali condizioni devono essere mutuamente esclusive, e si deve sempre fare
in modo che esattamente una di tali condizioni sia vera. Lunica transizione che avviene veramente quella associata
alla condizione verificata in quella particolare istanza del diagramma.

anche possibile che un ramo duscita non abbia ad esso associata alcuna condizione (o che vi sia scritto else): in tal
caso, quel ramo viene eseguito quando nessuna delle altre condizioni risulta verificata.

Il branch perci una struttura del tutto analoga ad un if (ad una condizionale) in un linguaggio di programmazione. Il
simbolo usato il seguente (nellesempio abbiamo 2 cammini possibili).

Il branch deve poi essere seguito da un simbolo di fusione (merge). Il merge il punto in cui i diversi cammini si
riuniscono. In pratica, quando arriva il primo percorso in ingresso al merge, si va avanti, passando il controllo
allattivit di destinazione dellunica transizione duscita del merge stesso.

[A] [else]

Figura 51: Rappresentazione di un branch nella notazione dei Figura 53: Rappresentazione di un merge nella notazione dei
sequence diagram sequence diagram

Di seguito sono riportati due esempi, il secondo dei quali mette in evidenza come sia possibile realizzare uniterazione
utilizzando il branch & merge e una semplice transizione che ritorna indietro:

Figura 54: Esempio n. 1 di sequence diagram con branch Figura 55: Esempio n. 2 di sequence diagram con branch

61
Capitolo 6: UML Ingegneria del Software 2

Fork & Join


Il flusso pu anche essere diviso mediante un altro tipo di costrutto, il fork. Tale costrutto per divide il flusso di
controllo in due o pi flussi indipendenti (threads), che proseguono in parallelo. Tutti i flussi vengono quindi attivati (e
non solo uno, come accadeva con il branch), a patto che le eventuali condizioni ad essi associate siano verificate (le
condizioni non devono essere mutuamente esclusive, ma comunque devono essere costruite in modo che almeno una
di tali condizioni risulti essere vera).

[C1] [C2]

Figura 56: Rappresentazione di un fork allinterno di un activity diagram

Ogni fork deve poi essere accompagnato da un simbolo di join, che rappresenta la sincronizzazione di due o pi flussi
in uno solo. Il join prevede quindi che si attenda il completamento di tutti i processi sulle linee di ingresso (a patto che
siano stati attivati), e solo quando tutti sono giunti al simbolo di join, si procede con lattivit successiva. Il simbolo del
join il seguente:

Figura 57: Rappresentazione di un join allinterno di un activity diagram

Si seguito sono riportati due esempi di uso del meccanismo fork/join:

Figura 58: Esempio n. 1 di sequence diagram con fork Figura 59: Esempio n. 2 di sequence diagram con fork

62
Ingegneria del Software 2 Capitolo 6: UML

Swimlane
possibile anche separare diverse swimlane in modo tale da separare le diverse responsabilit in relazione alle varie
operazioni da svolgere nel workflow. Le swimlane sono semplici divisioni verticali che corrispondono sostanzialmente
ad attori diversi del sistema. Nellesempio in figura, si hanno due swimlane: Student e System.

Figura 60: Esempio di activity diagram con due swimlane

Segnali
Inoltre, allinterno degli activity diagram pu essere rappresentato lo scambio di segnali. Ci avviene mediante dei
simboli di attivit particolari, come mostrati nelle figure seguenti:

Segnale Segnale

Figura 61: Simbolo per linvio di segnali nellactivity diagram Figura 62: Ricezione di segnali nellactivity diagram

Activity diagram robusto


Un activity diagram si dice robusto se tutti i costrutti sono correttamente annidati. Un activity diagram robusto ha
sempre uno ed un solo simbolo di fine. Il precedente diagramma dovrebbe allora diventare:

Le figure seguenti mostrano un activity diagram non robusto ed il corrispondente diagramma robusto (dal punto di
vista semantico, i due diagrammi sono equivalenti).

Attivit 1
Attivit 1
[A] [else]

[A] [else]
Attivit 2

Attivit 2

Figura 63: Esempio di activity diagram non robusto Figura 64: Esempio di activity diagram robusto

63
Capitolo 6: UML Ingegneria del Software 2

Osservazioni sugli activity diagram e sulla divisione del flusso


Si noti che in realt non sembre un branch seguito da un merge, e non sempre un fork seguito da un join: il
costrutto branch/merge e il fork/join possono infatti essere mescolati, come mostrato nei seguenti esempi:

A
A

[C1] [else]

B C
B C

Figura 65: Esempio di activity diagram con fork e merge Figura 66: Esempio di activity diagram con branch e join

Nellesempio di sinistra, le attivit B e C vengono avviate contemporaneamente e poi, appena termina la prima, si
termina lintero processo. Nellesempio di destra invece la semantica ambigua: teoricamente infatti si dovrebbe
attendere la terminazione di entrambi i rami in ingresso al join, ma questo equivale ad attendere per un tempo
infinito (essendoci infatti un branch, solo uno di tali rami verr attivato). Si potrebbe per anche voler intendere che si
deve aspettare la terminazione dei soli rami attivati (e quindi in questo caso la semantica equivalente a quella che si
avrebbe con un merge al posto del join).

Component diagram
Cosa sono?
Un component diagram un diagramma UML che mostra quali sono i diversi componenti che costituiscono un
sistema e quali sono le loro dipendenze reciproche.

Un componente un modulo fisico di codice, spesso corrispondente ad un package. Tuttavia, possibile che i
componenti e i package non coincidano, perch il concetto di package non fisico, mentre quello di componente s.
Ad esempio, una classe pu essere presente in diversi componenti, ma pu essere definita in un solo package.

Possiamo quindi dire che un componente una parte modulare del sistema, che nasconde al proprio interno la
realizzazione di una funzionalit e che pu essere usato da altri componenti, comportandosi cio come una black-box.
Ogni componente auto contenuto e interagisce con gli altri mediante opportune interfacce di utilizzo. Si noti quindi
che la differenza tra il concetto di componente e quello di classe spesso piuttosto sottile. Inoltre,
nellimplementazione possibile che un componente non compaia, perch implementato semplicemente come una
serie di classi. Se due componenti soddisfano la stessa interfaccia, allora possono essere sostituiti luno con laltro.

Le dipendenze tra componenti mettono in evidenza come i cambiamenti apportati ad un componente possono
causare cambiamenti negli altri componenti. Le dipendenze che possono essere usate sono molteplici (tra queste, si
hanno per esempio dipendenze di comunicazione e di compilazione).

I componenti possono essere decomposti gerarchicamente in altri componenti.

64
Ingegneria del Software 2 Capitolo 6: UML

I componenti
Un componente rappresentato graficamente mediante il simbolo in figura.

<<component>>

Nome componente

Figura 67: Rappresentazione di un componente

Ogni componente logicamente organizzato in interfacce e porte. Il componente pu fornire e richiedere interfacce.
Linterfaccia la definizione di un insieme di metodi (almeno uno), con laggiunta di eventuali attributi, che
idealmente definisce un insieme di comportamenti coesi. Un interfaccia fornita rappresentata mediante la
cosiddetta lollipop notation, ovvero mediante il simbolo rotondo mostrato in figura 68. Uninterfaccia richiesta
invece rappresentata attraverso la socket notation, che prevede di disegnare una semicirconferenza (fig. 69).

Figura 68: Lollipop notation


Figura 69: Socket notation
Le porte consentono invece di rappresentare un punto di interazione tra un componente e lambiente esterno. Le
porte sono rappresentate semplicemente come dei quadrati al margine del componente. Alla porta pu essere
associato un nome.

<<component>>

Nome componente
Porta

Figura 70: Rappresentazione di un porta allinterno di un componente

Le porte possono soddisfare la comunicazione di tipo unidirezionale oppure bidirezionale:

1. Le porte unidirezionali di output sono collegate solamente ad interfacce offerte dal componente stesso;
2. Le porte unidirezionali di input sono collegate solo a interfacce richieste dal componente stesso.
3. Le porte bidirezionali sono collegate sia ad interfacce richieste, sia ad interfacce offerte.

I componenti sono collegati tra loro mediante luso delle interfacce e delle relazioni di delegazione.

Figura 71: Esempio di component diagram

Come si osserva dalla figura 71, un componente pu contenere al proprio interno degli altri componenti. Si tratta in
questo caso di classi composite, nelle quali viene messo in evidenza il ruolo di tutte le singole istanze che vi
compaiono.

65
Capitolo 6: UML Ingegneria del Software 2

Statechart
Cosa sono?
Gli state chart sono dei diagrammi a stati che consentono di rappresentare levoluzione di un sistema. Si tratta dunque
di diagrammi comportamentali.

In particolare, il comportamento del sistema viene descritto in relazione allo stato del sistema stesso, in maniera
indipendente dalle modalit attraverso le quali avviene linterazione con lesterno. Per ogni diversa classe di oggetti si
avr uno state chart. Si noti per che sono state definite diverse semantiche per questi diagrammi.

Il concetto di statechart molto simile a quello di automa a stati finiti.

Automi a stati finiti


Uno automa a stati finiti formalmente definito come una terna del tipo , dove:

un insieme finito di stati;


un insieme finito di possibili input da fornire al sistema;
la funzione di transizione tra uno stato ed un altro del sistema.

Esistono diverse classi di automi a stati finiti: si hanno infatti automi deterministici e non deterministici, automi
riconoscitori e traduttori, . Per tali concetti, si rimanda ai corsi di Informatica Teorica.

Gli automi a stati finiti si prestano molto bene ad essere rappresentati in maniera grafica: ogni stato identificato da
un pallino allinterno del quale indicato il relativo nome, mentre le transizioni da uno stato ad uno stato
appartenenti ad sono rappresentate con una freccia dal cerchio che rappresenta al cerchio che corrisponde a ,
sulla quale viene esplicitato linput che determina la transizione stessa.

Push switch

OFF
ON

Push switch

Figura 72: Esempio di automa a stati finiti, che rappresenta il funzionamento di una lampada

Problemi degli automi a stati finiti e soluzioni adottate negli statecharts


Gli automi a stati finiti presentano alcuni problemi: innanzitutto, essi dispongono solo di una memoria finita.

Un altro importante problema dato dal fatto che il numero di stati aumenta in maniera considerevole allaumentare
della complessit dellautoma. Considerando infatti un certo numero di automi a stati finiti di partenza, se costruiamo
un nuovo automa che ne sia la composizione, il numero di stati risultante sar dato dal prodotto tra i numeri di stati
dei singoli automi di partenza (si ha quindi una crescita esponenziale, e non lineare).

Per risolvere questo problema, gli statecharts, pur rifacendosi molto da vicino agli automi a stati finiti, hanno
introdotto tutta una serie di strumenti che consentono di rappresentare gli automi in maniera modulare e gerarchica.

66
Ingegneria del Software 2 Capitolo 6: UML

Notazione grafica adottata dagli statecharts


Negli statecharts, ogni stato indicato mediante un rettangolo con gli angoli smussati, allinterno del quale indicato
il nome del relativo stato.

Lo stato iniziale viene inoltre indicato mediante una freccia entrante, che ha origine da un cerchio annerito.

Stato Stato

Figura 73: rappresentazione di uno stato Figura 74: Stato iniziale in uno Figura 75: rappresentazione di uno stato
in uno statechart statechart finale in uno statechart
Di seguito mostrato un primo semplice esempio di statechart.

Figura 76: Esempio di statechart

Per ridurre il numero di stati, si possono utilizzare i cosiddetti sottostati: allinterno di uno stato si rappresenta di
fatto un nuovo statechart. Quando si giunge allo stato in esecuzione, viene di fatto avviata lesecuzione dello state
chart interno, congelando di fatto quella del precedente e partendo dallo stato iniziale. Lo stato contenente il
diagramma innestato potrebbe inoltre contenere delle altre transizioni, che vengono attivate al verificarsi di un
particolare evento, indipendentemente dallo stato in cui ci si trova allinterno dello state chart interno.

Uno stato S pu inoltre avere un history substate, ovvero un sottostato che viene utilizzato perch ogni transizione in
ingresso nellhistory substate equivale a dire che si ritorna nel sottostato di S nel quale ci si trovava prima di passare
ad un nuovo stato. Lhistory substate viene indicato mediante un pallino con allinterno la lettera H.

Figura 77: Esempio di state chart con sottostati Figura 78: Esempio di state chart con history substate

67
Capitolo 6: UML Ingegneria del Software 2

Sottostati concorrenti
Uno stato pu essere suddiviso in sottostati diversi che evolvono in maniera concorrente, ovvero in parallelo tra loro.
Questo viene rappresentato mediante la suddivisione dello stato in diverse aree; allinterno di ognuna di queste aree
presente un diverso state chart, che rappresenta una delle attivit concorrenti in esecuzione.

Figura 79: Esempio di statechart con uno stato con sottostati concorrenti

Uso delle condizioni e delle azioni


Su una transizione, oltre al nome di un evento, pu essere indicata anche una condizione, racchiusa tra parentesi
quadre, che deve essere verificata affinch la transizione avvenga realmente.

Inoltre, possibile indicare unazione, separata dalla parte restante dei dati della transizione mediante il simbolo di
slash (/). La struttura perci:

Evento [Condizione] / Azione

Nessuna delle 3 parti obbligatoria. Si noti che:

Levento pu essere di diversi tipi:


a) Evento di chiamata (una chiamata sincrona proveniente da un certo oggetto).
b) Evento di cambiamento (il valore di unespressione booleane varia).
c) Evento di segnale (ricezione di un segnale asincrono).
d) Evento di tempo (si arriva ad un certo istante assoluto).
Lazione ci che viene fatto durante la transizione. Pu essere unazione semplice, oppure unazione pi
complessa, descritta mediante un altro diagramma UML di tipo comportamentale.
I segnali sono descritti mediante classi con lo stereotipo <<signal>>. Essi possono essere tra loro legati da relazioni
di generalizzazione.

Figura 80: Esempi di segnali

68
Ingegneria del Software 2 Capitolo 6: UML

Utilizzare lUML per modellare i requisiti


Use case diagram
Se si vogliono modellare i requisiti, il primo passo da compiere la stesura di uno use case diagram, nel quale viene
definito linsieme di tutte le funzionalit del sistema.

Le regole per la stesura del diagramma sono gi state definite nei precedenti paragrafi. Inoltre, ad ogni use case deve
essere associata una descrizione testuale, come gi accennato in precedenza.

Dagli use case agli oggetti


Partendo da uno use case, che definisce le funzionalit di alto livello del sistema, si individuano di volta in volta le
funzionalit di livello inferiore, ovvero descritte con un maggior livello di dettaglio. Il procedimento viene ripetuto fino
ad arrivare a definire le singole operazioni, sulla base delle quali potranno essere definiti gli oggetti partecipanti.

Class diagram
I class diagram definiti al livello di specifica dei requisiti sono dei diagrammi che rappresentano un modello
concettuale del dominio applicativo, e non sono dei diagrammi che modellano la struttura in classi del software object
oriented che verr poi realizzato: talvolta le classi in essi definite non saranno presenti nel software che verr
realizzato, e in ogni caso non vengono indicati i metodi delle entit definite nel modello.

Ogni classe deve avere una descrizione in linguaggio naturale che definisce le condizioni che la classe stessa deve
rispettare per trovarsi in un certo stato. Ogni attributo inoltre deve avere una descrizione in linguaggio naturale che ne
definisca il significato allinterno del mondo reale. Infine, la descrizione della classe contiene un invariante di dominio,
che specifica a parole le propriet di dominio della classe stessa.

Per individuare gli oggetti, si possono seguire alcune semplici regole:

1. necessario conoscere il dominio applicativo, perci necessario osservare il cliente ed interagire con esso;
2. Occorre applicare lintuizione e le conoscenze generali a propria disposizione;
3. Si analizza il flusso di eventi e si analizzano gli oggetti che partecipano nei singoli use case;
4. Si deve cercare di stabilire una tassonomia;
5. Si deve analizzare in maniera sintattica la descrizione del problema, lo scenario o il flusso di eventi.
6. I termini utilizzati allinterno di questo class diagram saranno solitamente nomi per quanto riguarda le classi,
mentre le operazioni devono avere dei nomi rappresentati da verbi.
7. Nella stesura degli use case diagram, spesso utile applicare i design pattern.

Nella stesura del class diagram, opportuno tener sempre presente che il suo scopo quello di descrivere le propriet
statiche di un sistema. Inoltre, i destinatari degli use case possono essere multipli:

1. Gli esperti del dominio applicativo li usano per modellare la realt di riferimento;
2. Gli sviluppatori li usano durante la fase di sviluppo, analisi, design e implementazione.
3. Il cliente e lutente finale solitamente non sono interessati ai class diagram e focalizzano la loro attenzione
soprattutto sulle funzionalit del sistema.

69
Capitolo 6: UML Ingegneria del Software 2

Individuare gli oggetti partecipanti negli use case


Per individuare quali sono gli oggetti che partecipano ad un certo use case, le regole principali da osservare sono:

1. Scelto uno use case, si osserva il relativo flusso di eventi e:


a) Si individuano i termini che gli sviluppatori o gli utenti devono chiarire per comprendere il flusso di eventi.
b) Si cercano i nomi pi ricorrenti.
c) Si identificano le entit del mondo reale di cui il sistema deve tener traccia.
d) Si identificano le procedure del mondo reale delle quali il sistema deve tener traccia.
e) Si identificano le sorgenti dei dati o la destinazione dei dati stessi.
f) Se identificano le interfacce
2. Con molta probabilit, in questa fase alcuni oggetti verranno dimenticati, e bisogna perci essere pronto ad
individuarli in un secondo momento.
3. Il flusso di eventi deve essere modellato con un diagramma di sequenza.
4. I termini utilizzati devono essere gli stessi che lutente in grado di comprendere.

Modellazione dinamica
A questo punto si pu passare alla modellazione dinamica, il cui scopo quello di fornire dei modelli per linterazione
e il comportamento dei partecipanti e del workflow.

Il procedimento generale che viene seguito prevede alcuni passi di base:

1. Si usa come punto di partenza lo use case diagram o lo scenario;


2. Si modella linterazione tra gli oggetti, mediante i sequence diagram. Gli oggetti e le classi che partecipano al
sequence diagram devono essere identificati durante i precedenti passi di analisi. tuttavia possibile che vengano
identificati nuovi oggetti e classi in questa fase. Vengono cos messe in evidenza le relazioni temporali tra gli
oggetti e le sequenze di operazioni, intese come sequenze di eventi e di risposte agli eventi.
3. Si rappresenta il comportamento dinamico dei singoli oggetti, mediante state chart. Tali diagrammi permettono di
mettere in evidenza i cambiamenti interni alloggetto nel corso del tempo
4. Si modella il workflow, mediante gli activity diagram.

Si noti che i modelli dinamici devono essere realizzati solamente per quelle classi che hanno un comportamento
dinamico significativo.

70
Ingegneria del Software 2 Capitolo 7: Specifica

Capitolo 7: Specifica
Il concetto di specifica
Che cos una specifica?
Il termine specifica viene qui utilizzato come sinonimo di descrizione precisa e di alto livello. In generale per il
termine rappresenta un vero e proprio contratto che viene stretto tra il produttore e il cliente del servizio, oppure tra
chi definisce il software e chi lo deve implementare.

Il concetto di specifica perci ben distinto da quello di implementazione; la specifica:

Definisce cosa fa il sistema, in modo astratto (ovvero trascurando tutta una serie di dettagli);
Non necessariamente eseguibile in modo diretto;
Spesso indeterminata, cio sono possibili diverse implementazioni della stessa specifica.

Limplementazione invece definisce in maniera concreta il comportamento del sistema.

Propriet della specifica


La specifica deve di conseguenza possedere le seguenti propriet:

1. Chiarezza
2. Precisione
3. Assenza di ambiguit
4. Consistenza (in caso contrario non esister alcuna implementazione che soddisfi la specifica)
5. Completezza, che a sua volta pu essere:
a) Interna (se si parla di un certo oggetto x in un punto della specifica, bisogna che x sia gi stato definito).
b) Esterna (la specifica deve dire tutto ci che necessario a riguardo del fenomeno che ha per oggetto).
6. Deve essere incrementale (il processo di specifica avviene in maniera incrementale, ovvero si parte da una
descrizione che viene poi gradualmente allargata).

Notazioni per la specifica


Il linguaggio naturale non consente di ottenere specifiche dotate di tutte le propriet appena elencate: ad esempio,
ogni testo scritto in linguaggio naturale ha al suo interno tutta una serie di ambiguit, che il lettore disambigua sulla
base delle proprie conoscenze; tuttavia, ogni individuo pu avere dei background diversi, e di conseguenza possibile
che disambigui le frasi in linguaggio naturale in maniere diverse.

Si utilizzano allora delle notazioni apposite, che possono essere formali (ovvero matematicamente precise) oppure
semiformali (cio che utilizzano dei linguaggi in parte formalizzati, in parte no). Il linguaggio naturale invece una
notazione informale.

Tipi di specifica
Una specifica pu essere di diverse tipologie:

Specifica operazionale
Si tratta di una specifica nella quale vengono utilizzati i concetti tipici delle macchine astratte (automi), come ad
esempio il concetto di stato, per specificare il comportamento del sistema. Ad esempio, una specifica
operazionale pu essere ottenuta per mezzo di uno state chart.

Specifica descrittiva (o dichiarativa)


Una specifica descrittiva consente di indicare il comportamento del sistema sulla base di asserzioni
(normalmente basate sulla logica) che ne rappresentano le propreit.

71
Capitolo 7: Specifica Ingegneria del Software 2

Come verificare la specifica?


Per verificare la specifica, necessario:

1. Osservare il comportamento dinamico del sistema (mediante simulazione, prototipazione, o mediante test sulla
specifica)
2. Analizzare le propriet del sistema oggetto di specifica.

Si hanno quindi alcune analogie con le ingegnerie tradizionali, nelle quali possibile realizzare dei modelli fisici o
matematici di ci che si sta costruendo (ad esempio, un ponte).

Alcuni esempi di notazioni


Le notazioni che noi vedremo sono 2:

UML
LUML, di cui abbiamo gi ampiamente parlato, un linguaggio di specifica semiformali, che include notazioni
molto diverse tra loro per la specifica di aspetti differenti. Le notazioni comportamentali sono soprattutto i
sequence diagram, gli state chart diagram e gli activity diagram; le notazioni descrittive sono soprattutto i class
diagram e gli object diagram.

Alloy
In seguito, introdurremo invece la notazione Alloy, che di tipo descrittivo e che una notazione formale.

Introduzione ad Alloy
Che cos Alloy?
Come abbiamo appena accennato, Alloy un linguaggio formale e descrittivo per la specifica, sviluppato al
Massachusetts Institute of Technology e giunto oggi alla sua quarta versione. Alloy consente perci di definire dei
modelli del software.

I concetti utilizzati da Alloy sono molto simili a quelli tipici dei linguaggi orientati agli oggetti; tuttavia, in questo caso il
concetto di classe non contiene al suo interno una descrizione degli algoritmi utilizzati per compiere determinate
operazioni, ma solo le dichiarazioni di propriet (si tratta di un linguaggio dichiarativo), definite mediante luso della
logica. La notazione di Alloy inoltre compatibile con modelli di rappresentazione grafica degli oggetti.

Alloy utilizza predicati della logica del primo ordine tipizzata.


Il concetto base di Alloy quello di relazione, di conseguenza lalgebra relazione alla base di questa notazione di
specifica.
Dispone di un potente e veloce tool automatico per simulare le specifiche e verificare la validit delle propriet
definite. In dettaglio, questo tool in grado di stabilire se le specifiche date sono soddisfacibili (potr cio esistere
unimplementazione che le soddisfa) e se da esse possono essere tratte delle particolari conseguenze.

Perch usare Alloy?


Alloy pu essere utilizzato ovunque sia necessario costruire un modello. Ad esempio, pu essere usato nella fase di
ingegnerizzazione dei requisiti, per descrivere il dominio e le sue propriet, oppure per descrivere le operazioni che il
sistema dovr essere in grado di eseguire. Inoltre, Alloy pu essere usato nella fase di design, per specificare i
componenti e le loro interazioni.

72
Ingegneria del Software 2 Capitolo 7: Specifica

Concetti base di Alloy


Si utilizza la logica non specializzata
Non ci sono costrutti speciali per i concetti di macchina a stati, concorrenza, sincronizzazione, .

Ambiente ed uso dei controesempi


La verifica delle specifiche si basa in Alloy sulla ricerca di contresempi. In questo si ha perci unanalogia rispetto
alla tradizionale attivit di testing del codice; la differenza fondamentale per nellambiente che viene
utilizzato: mentre il testing avviene campionando in maniera pi o meno casuale un certo insieme di valori scelti
allinterno del dominio, in Alloy si considera un sottoinsieme qualsiasi del dominio, purch tale sottoinsieme sia
finito, e si effettua allinterno di tale sottoinsieme una ricerca esaustiva, andando quindi a verificare tutti i valori
appartenenti al sottoinsieme (si parla perci di small scope hypotesys). In sostanza, il modello infinito, ma lo
scope (ambiente) finito.

Figura 81: Confronto tra lattivit di verifica tramite testing e la verifica mediante luso di Alloy (small scope hypothesys)

Analisi mediante lutilizzo di SAT


La verifica in Alloy viene eseguita mediante un algoritmo detto SAT (che, come noto da corsi come quello di
Algebra e Logica Matematica, sta per Satisfiability, ovvero per soddisfacibilit di formule logiche).

Siccome abbiamo gi affermato che Alloy utilizza la logica del primo ordine (FOL, First Order Logic) e siccome
noto che la soddisfacibilit di formule FOL non un problema decidibile, risulta naturale chiedersi come sia
possibile disporre di un tool software in grado di verificarla, per di pi in maniera rapida. La risposta a questa
domanda proviene proprio dallassunzione che abbiamo descritto nel punto precedente: siccome gli insiemi che
si considerano sono finiti, le formule FOL possono essere in questo caso considerate equivalenti a formule
proposizionali, e quindi in questo caso il problema risulta essere decidibile.

Nonostante questo, il problema rimane nel caso generale NP-completo (e quindi costosissimo in termini di
complessit computazionale). Ci che ci consente di ottenere strumenti in gradi di verificare efficacemente la
soddisfacibilit delle formule in questione in realt unosservazione pratica: nella realt dei fatti, le formule che
vengono scritte in Alloy sono quasi sempre tali che lefficienza che si ottiene molto elevata.

Tutto una relazione


Le relazioni sono utilizzate da Alloy per la rappresentazione di tutte le tipologie di dati, compresi gli insiemi, gli
scalari e le tuple.

Questa scelta legata al fatto che le relazioni sono di facile comprensione (possono anche essere facilmente
rappresentate in maniera grafica), facili da analizzare e consentono la massima uniformit (qualsiasi concetto
rappresentato mediante quello di relazione).

In Alloy esiste inoltre il concetto di atomo: gli atomi sono le entit primitive di Alloy, e si tratta di elementi
indivisibili, immutabili e non interpretabili.

73
Capitolo 7: Specifica Ingegneria del Software 2

Le relazioni sono delle associazioni tra atomi e sono di fatto degli insiemi di tuple, nei quali ogni tupla una
sequenza di atomi.

Tutti i valori sono rappresentati, indipendentemente dal loro tipo, mediante luso di una relazione:

a) Se il valore un insieme, allora rappresentato mediante una relazione unaria:


Figli = { (F0), (F1), (F2) }

b) Se il valore uno scalare, viene rappresentato come un insieme con un solo elemento:
MioNome = { (N0) }

c) Esiste poi il concetto di relazione in senso proprio (che potr essere binaria, ternaria, ). Ad esempio:
AutoriLibri = { (B0, A0), (B0, A1), (B1, A0), (B2, A2) }
In questo caso, abbiamo tre libri B0, B1 e B2. Il primo libro scritto dagli autori A0 e A1, B1 scritto solo da
A0 e B2 ha come autore A2.

Le relazioni possono intuitivamente essere rappresentate mediante tabelle non ordinate, le cui colonne non
hanno un intestazione, ma sono ordinate. Tutte le relazioni sono del primo ordine, ovvero non possono
contenere al loro interno delle altre relazioni.

Ad esempio, la relazione precedentemente indicata come esempio verr rappresentata dalla seguente tabella:

B0 A0
B0 A1
B1 A0
B2 A2
Tabella 4: Rappresentazione tabellare di una relazione di esempio

Pi nel dettaglio, una relazione definita come un insieme di un certo numero n di elementi, dove n prende il
nome di arit della relazione. Le relazioni Alloy sono sempre tipizzate (ad esempio, il primo elemento deve
essere di tipo Book, il secondo di tipo String).

Una relazione binaria viene anche rappresentata come:

Dove il tipo di sinistra e il tipo di destra. Inoltre diciamo che:

a) R totale se ogni atomo del tipo di sinistra mappato ad almeno un atomo del tipo di destra.
b) R suriettiva se ogni atomo della parte di destra mappato ad almeno un atomo del tipo di sinistra.
c) R funzionale se ogni elemento del tipo mappato ad al pi un elemento del tipo .
d) R iniettiva se ogni atomo del tipo mappato ad al massimo un atomo del tipo .
Loperatore .
Loperatore fondamentale loperatore ., che corrisponde al join tra relazioni e che consente di fatto ad
accedere ad uno specifico dato.

La semantica di Alloy
La semantica di Alloy definisce il significato di una specifica Alloy come un insieme di modelli (mondi) nei quali la
specifica Alloy verificata. In Alloy, un mondo costituito da atomi e da relazioni tra atomi. Come accennato, un
atomo un oggetto completamente privo di caratteristiche, indivisibile ed immutabile, senza significato (pu
rappresentare qualsiasi cosa).

74
Ingegneria del Software 2 Capitolo 7: Specifica

La sintassi di Alloy
Le costanti
In Alloy sono definite le seguenti costanti:

Significato Costante
Insieme vuoto none
Insieme universo univ
Relazione identit iden
Tabella 5: Costanti definite in Alloy

Gli operatori
Oltre alloperatore punto, si possono usare anche i seguenti operatori insiemistici:

Operatore Simbolo
Unione +
Intersezione &
Differenza -
Sottoinsieme in
Uguaglianza insiemistica =
Prodotto cartesiano ->
Tabella 6: Operatori insiemistici ammessi in Alloy

Ed i tradizionali operatori logici, riassunti nella tabella seguente:

Operatore Simbolo Parola chiave equivalente


And && and
Or || or
Not ! not
Implicazione logica => implies
Else (alternativa) else else
Se e solo se <=> iff
Tabella 7: Operatori logici ammessi in Alloy

Per chiarire luso di else, di seguito sono riportate due formule equivalenti:

F implies G else H (F && G) || (!F && H)


Come gi accennato, loperatore pi importante loperatore ., che equivale al join relazionale. Ad esempio:

X = { (A1, B1), (A2, B2) }


Y = { (B1, C1), (B3, C3), (B1, C2), (B2, C4) }
X . Y = { (A1, C1), (A1, C2), (A2, C4) }
Cio si costruiscono le tuple partendo dai due insiemi di partenza, considerando solo le coppie di tuple tali che la
prima tupla appartenga allinsieme indicato come primo operando, la seconda appartenga allinsieme indicato come
secondo operando, e lultimo elemento della prima tupla coincida con il primo della seconda; la tupla costruita
ottenuta semplicemente concatenando le due tuple di partenza, me eliminando lultimo elemento della prima e
tupla e il primo della seconda. Loperatore . detto anche dot join, in contrapposizione alloperatore box join, del
tutto equivalente al precedente, ma con una notazione diversa:

e1.e2 equivale a e2[e1]

75
Capitolo 7: Specifica Ingegneria del Software 2

Esistono inoltre alcuni operatori unari, riassunti nella tabella di seguito riportata:

Operatore Simbolo
Trasposta ~
Chiusura transitiva ^
Chiusura transitiva e riflessiva (solo per relazioni binarie) *
Tabella 8: Operatori unari ammessi in Alloy

Gli operatori unari vengono indicati prima del nome della relazione. Ad esempio, se abbiamo:

e = {(A1, A2), (A3, A4)} ~e = {(A2, A1), (A4, A3)}


Altri operatori consentiti sono quelli di restrizione e di override:

Operatore Simbolo
Restrizione di dominio <:
Restrizione di codominio :>
Override ++
Tabella 9: Operatori di restrizione e di override ammessi in Alloy

La restrizione di dominio ha come primo operatore un insieme e come secondo operatore una relazione (anche se
come noto linsieme di per s una relazione, ) e restituisce la relazione costituita da quelle tuple della relazione
data tali che il primo elemento appartenga allinsieme indicato come parametro. Ad esempio:

A = { (A1), (A2) }
r = { (A1, B1), (A1, B2), (A2, B1), (A2, B4), (A3, B5), (A4, B1)}
A <: r = { (A1, B1), (A1, B2), (A2, B1), (A2, B4) }

La restrizione di codominio del tutto simmetrica:

B = { (B1), (B2) }
r = { (A1, B1), (A1, B2), (A2, B1), (A2, B4), (A3, B5), (A4, B1)}
r :> B = { (A1, B1), (A1, B2), (A2, B1), (A4, B1)}
Un po pi complesso loperatore di override: date due relazioni, loperatore di override costruisce una terza
relazione nella quale vengono inserite tutte le tuple delle due relazioni di partenza, salvo quelle della prima relazione il
cui primo elemento presente anche come primo elemento di altre tuple della seconda relazione (tali tuple vengono
perci sovrascritte o scavalcate da quelle della seconda relazione). Pi formalmente:

p ++ q = p (domain[q] <: p) + q

I quantificatori
Alloy consente anche luso dei quantificatori, similmente a quanto accade nella logica del primo ordine. Le sintassi
attraverso le quali un quantificatore pu essere indicato sono le seguenti:

nomeQuantificatore varVincolata : Tipo | Condizione


nomeQuantificatore varVincolata1, varVincolata2 : Tipo | Condizione
nomeQuantificatore varVincolata1 : Tipo1, varVincolata2 : Tipo2 | Condizione
nomeQuantificatore disj varVincolata1, varVincolata2 : Tipo | Condizione
Il significato di tali sintassi risulta molto intuitivo. I quantificatori esistenti sono:

Significato Simbolo
Condizione verificata solo se per ogni elemento del tipo dato la condizione vera. all
Condizione verificata solo se per almeno un elemento del tipo dato la condizione vera. some
Condizione verificata solo se per 0 o 1 elemento del tipo dato la condizione vera. lone
Condizione verificata solo se per 1 e solo un elemento del tipo dato la condizione vera. one
Condizione verificata solo se per nessun elemento del tipo dato la condizione vera. no
Tabella 10: quantificatori ammessi in Alloy

76
Ingegneria del Software 2 Capitolo 7: Specifica

Definizione di una signature


Una signature definisce un tipo e le relazioni nelle quali gli oggetti di quel tipo sono coinvolti come primi elementi. Se
vogliamo definire un tipo di oggetti senza alcuna relazione, scriviamo:

sig TipoOggetto{}
Se vogliamo definire un tipo di oggetti che partecipa come primo elemento in una relazione binaria, scriviamo:

sig TipoOggetto{ NomeRelazione : TipoSecondoElemento }


Questo assomiglia molto nella programmazione ad oggetti a definire un attributo che viene associato alla classe che
si sta definendo, e possiamo in un certo senso interpretarlo in tal modo, anche se nella realt i concetti che si
nascondono dietro tale sintassi sono quelli delle relazioni, fino ad ora analizzati.

Questa dichiarazione pu comprendere anche delle parole chiave, che possono essere interpretate come la
definizione di un attributo che rappresenta un insieme di elementi:

sig TipoOggetto{ NomeRelazione : parolaChiave TipoSecondoElemento }


Le parole chiave che possono essere usate per la definizione di un insieme sono le seguenti:

Significato Simbolo
Insieme con un numero qualsiasi di elementi set
Insieme con almeno un elemento some
Insieme con non pi di un elemento (o zero, o uno) lone
Insieme con uno ed un solo elemento one
Tabella 11: dichiarazione degli insiemi in Alloy

Se non si scrive nulla, come se venisse utilizzata la parola chiave one. Come accennato, in realt si avr una
relazione; ad esempio, se utilizziamo la parola chiave lone, significa che ogni elemento di TipoOggetto potr essere
associato da NomeRelazione ad al massimo un elemento del tipo TipoSecondoElemento. In ogni caso, loperatore
dot join introduce unaltra analogia con la programmazione ad oggetti: scrivendo:

Oggetto.NomeRelazione
Otterremo infatti il valore o linsieme dei valori di TipoSecondoElemento associati ad Oggetto, in maniera analoga
a quanto accadrebbe se la relazione fosse in realt un attributo di una classe.

Si possono inoltre utilizzare delle relazioni di arit superiore. Ad esempio, per definire relazioni ternarie scriviamo:

sig TipoOggetto{ NomeRelazione : TipoSecondoElemento -> TipoTerzoElemento}


Anche in questo caso si possono indicare delle parole chiave (di seguito sostituite da n e m):

sig TipoOggetto{ NomeRelazione : TipoSecondoElemento n -> m TipoTerzoElemento}


I cui valori possibili sono gli stessi definiti nella precedente tabella, in relazione alla definizione di insiemi. Ad esempio:

sig TipoOggetto{ NomeRelazione : TipoSecondoElemento lone -> some TipoTerzoElemento}

Espressioni di quantificazione
La tabella seguente mostra la possibilit di utilizzare delle espressioni di quantificazione che, applicate a relazioni,
producono dei valori booleani:

Significato Simbolo
Vero se la relazione non vuota some
Vero se la relazione vuota no
Vero se la relazione ha al pi un elemento lone
Vero se la relazione ha esattamente un elemento one
Tabella 12: espressioni di quantificazione in Alloy

Scriveremo poi:

operatore NomeInsieme

77
Capitolo 7: Specifica Ingegneria del Software 2

Espressioni per indicare una relazione derivata


possibile anche indicare una certa relazione derivata, mediante espressioni del tipo:

{x1: e1, x2: e2, ..., xn: en | F}


Tale espressione corrisponde a tutte le tuple di n elementi, il cui i-esimo elemento del tipo ei, che verificano la
condizione F.

Utilizzo della parola chiave let


Una parola chiave utile la parola let, che consente di rinominare una certa espressione. Ad esempio, di seguito
sono mostrate 4 espressioni tra loro equivalenti, che servono a chiarire come possibile usare la parola chiave let.

all n: Name | (some n.workAddress implies n.address = n.workAddress


else n.address = n.homeAddress)

all n: Name | let w = n.workAddress, a = n.address |


(some w implies a = w else a = n.homeAddress)

all n: Name | let w = n.workAddress |


n.address = (some w implies w else n.homeAddress)

all n: Name | n.address = (let w = n.workAddress | (some w implies w else n.homeAddress))

Cardinalit
La cardinalit di un insieme o di una relazione indicata mediante loperatore #. Per gestire le cardinalit, si possono
utilizzare i tradizionali operatori di confronto tra interi ( >, <, =, >=, <=), si possono definire degli interi costanti
(semplicemente mediante i numeri decimali), si possono utilizzare le operazioni di addizione e sottrazione tra interi ( +
e ). Esiste infine loperatore di somma:

sum x: e | ie
Che calcola la somma di tutte le espressioni ie valutate per gli elementi x di tipo e.

Definizione di un fact
I fatti sono delle propriet dei modelli, ovvero dei vincoli ai quali i modelli devono sottostare. I fatti vengono indicati
mediante una notazione del tipo:

fact { condizione }
Dove la condizione pu essere espressa mediante tutti gli operatori precedentemente introdotti (ad esempio,
mediante un quantificatore).

Definizione di predicati
I predicati (in inglese predicates) sono delle espressioni riutilizzabili. Essi consentono di definire delle propriet che
dovranno essere rispettate dai mondi utilizzati, e che vengono utilizzate per lindividuazione di tali mondi: quando
verr eseguito il modello, Alloy si preoccuper di fornire uno dei mondi (se esistono) che soddisfano il predicato.

Un esempio di definizione di predicato il seguente:

pred show(b: Book) {


#b.addr > 1 or #b.addr >= 1
}
I predicati possono anche essere utilizzati per definire delle operazioni. Ad esempio, possiamo scrivere:

pred add(b, b': Book, n: Name, a: Addr) {


b'.addr = b.addr + n ->a
}
In questo modo, anche se il predicato in realt solo un vincolo, riusciamo a forzare b e b' in modo che
rappresentino luno il libro prima delloperazione (b), e laltro il libro dopo loperazione (b).

78
Ingegneria del Software 2 Capitolo 7: Specifica

Definizione di funzioni
Alloy permette inoltre di definire delle funzioni in senso vero e proprio, mediante la sintassi:

fun name (parameter1: domain1, paramter2: domain2, ..., parameterN: domain): domain {
[body must evaluate to a value in Domain]
}
Per esempio, possiamo scrivere:

fun between (lower : Int, upper : Int) : Int {


{answer: Int | lower < answer && answer < upper }
}
La funzione cos definita restituisce linsieme di tutti gli interi compresi tra i due valori ricevuti come parametri. Si
possono inoltre aggiungere dei vincoli ai parametri e al valore di ritorno. Ad esempio:

fun name (param: some Int) : lone Int {


...
}
Potremo poi utilizzare la funzione allinterno di espressioni, semplicemente scrivendo (se riprendiamo il precedente
esempio):

Between[par1, par2]

Definizione di asserzioni
Le asserzioni sono delle propriet che devono essere verificate. Esse, a differenza dei predicati, vengono controllate
per ricercare dei controesempi: le propriet espresse allinterno delle asserzioni devono essere verificate per tutti i
mondi e Alloy si preoccupa di cercare degli esempi di mondi in cui ci non accade; se Alloy individua un mondo di
questo tipo, significa che esistono dei problemi nel nostro modello.

Un esempio di asserzione il seguente:

assert delUndoesAdd {
all b, b', b": Book, n: Name, a: Addr |
add[b,b',n,a] and del[b',b",n, a] implies b.addr = b".addr
}
Dove si assunto che, oltre al predicato add definito nellesempio precedente, sia stato definito anche il predicato
del come segue:

pred del (b, b': Book, n: Name, a: Addr) {


b'.addr = b.addr - n ->a
}

Definizione di comandi
Infine, possibile specificare di comandi, ovvero delle istruzioni che servono per comunicare allanalizzatore Alloy
quali asserzioni e predicati devono essere controllati, e come.

Se vogliamo eseguire un predicato e mostrare i mondi possibili coerenti con tale predicato, allora utilizziamo il
comando run, nel quale possiamo anche specificare la dimensione dello scope, mediante un numero che rappresenta
la massima quantit di atomi di ognuno dei tipi definiti:

run predicato() for n


Se invece vogliamo cercare i controesempi di una certa asserzione, utilizziamo in maniera del tutto simile il comando
check:

check asserzione() for n

79
Capitolo 7: Specifica Ingegneria del Software 2

Le gerarchie in Alloy
In Alloy possibile anche definire delle gerarchie tra le signature definite e, similmente a quanto accade nel mondo
della programmazione ad oggetti, una signature pu essere definita astratta.

Per definire una signature che eredi da unaltra si utilizza la parola chiave extends:

sig NomeFiglio extends NomePadre {


//elenco dei campi
}
In sostanza, lerede un sottoinsieme della signature padre. Se si definiscono due diverse signature eredi (pi
propriamente dette subjects), allora si tratter di insiemi disgiunti.

Per definire una signature astratta, sufficiente utilizzare la parola chiave abstract:

abstact sig NomeSignature { }


In questo modo si sicuri che non esisteranno degli oggetti del tipo dato che non appartengano ad uno dei suoi
sottotipi.

Incorporare i fatti nelle signature


Per rendere pi concisa la scrittura dei fatti, possibile incorporarli direttamente allinterno di una signature, come
mostrato nel seguente esempio:

abstract sig Target {}

sig Addr extends Target {}

abstract sig Name extends Target {}

sig Alias, Group extends Name {}

sig Book { addr: Name -> Target } {no n: Name | n in n.^addr}


In questo modo, siccome la dichiarazione dentro alla signature, sottinteso che varr per tutti gli oggetti di tipo
Book.

Tracce di esecuzione
possibile descrivere un ordine allinterno di un qualsiasi insieme, mediante luso della libreria module util/ordering.
Per comprenderlo meglio, vediamo il seguente esempio:

module tour/addressBook3
open util/ordering [Book]
abstract sig Target {}

pred init (b: Book) { no b.addr }

fact traces {
init (first ())
all b: Book - last() | let b' = next(b) |
some n: Name, t: Target | add (b, b', n, t) or del (b, b', n, t)
}
In questo modo abbiamo definito un ordine tra i libri, in modo tale che il primo libro soddisfi una certa condizione
iniziale, e tutti i libri adiacenti ad un altro sono correlati a questultimo mediante una certa operazione.

80
Ingegneria del Software 2 Capitolo 7: Specifica

Un esempio di utilizzo di Alloy


Consideriamo adesso un primo esempio di specifica in Alloy. Consideriamo un mondo costituito da persone che
devono avere le seguenti propriet:

1. Ognuna ha esattamente un nome;


2. Ognuna ha uno o zero coniugi;
3. Ognuna ha dei genitori;
4. Ognuna ha unagenda dei compleanni.

Inoltre, ogni agenda dei compleanni:

1. Contiene una lista di persone;


2. Riporta, per ogni persona nella lista, il relativo giorno di nascita.

Infine, devono sussistere i seguenti vincoli:

1. Nessuna persona sposata con un suo fratello o una sua sorella;


2. Ogni persona contenuta nellagenda dei compleanni di ognuno dei suoi amici (dove gli amici di una persona
sono coloro che fanno parte della lista dei compleanni di quella persona).

module birthday_book

sig Name {}

sig Person {
name: one Name,
spouse: lone Person,
parents: set Person,
birthdayBook : Person -> lone Date
}

sig Date {}

fact notMarriedWithBrotherOrSister {
(no p: Person | some (p.spouse.parents & p.parents))
}

fact birthdayBookConstraint{
all disj p1, p2 : Person |
let b1 = p1.birthdayBook, b2 = p2.birthdayBook
| (some p2.b1 implies some p1.b2)
}

fact noDiffDate{
all p1, p2, p3 : Person | (some p3.(p1.birthdayBook) and some
p3.(p2.birthdayBook)) implies p3.(p1.birthdayBook) = p3.(p2.birthdayBook)
}

fact noHimselfInBirthdayBook{
all p1, p2 : Person | some p2.(p1.birthdayBook) implies (! p1 = p2)
}

pred show(){ }

run show for 5 but exactly 3 Person

81
Capitolo 7: Specifica Ingegneria del Software 2

Si noti che oltre ai vincoli richiesti ne sono stati imposti alcuni aggiuntivi. Un esemio di mondo generato il seguente:

Figura 82: Esempio di mondo generato dallAlloy Analizer

Osservazioni conclusive su Alloy


Prima di concludere, bene sottolineare che:

Se si utilizza il comando check e lanalizzatore Alloy non in grado di individuare alcun controesempio, questo
non significa che il modello sia esatto, perch lanalizzatore si limita a considerare un ambiente finito; tuttavia, se
lambiente sufficientemente grande, non trovare controesempi significa con buona probabilit che il modello
corretto.
Anche se il modello Alloy corretto, non esiste un modo automatico per stabilire se il software che verr in
seguito realizzato sar aderente o meno al modello specificato.

82
Ingegneria del Software 2 Capitolo 8: Software design

Capitolo 8: Software design


Software design & software architecture
Distinzione tra il concetto di design e software architecture
Spesso si parla indistintamente di design e architettura software; in realt per si tratta di concetti distinti, e possiamo
evidenziare tale differenza affermando che lattivit di design produce larchitettura software. Pi in dettaglio:

Design
Consiste nella decomposizione del sistema in moduli e si focalizza sulle relazioni e interazioni tra i moduli.

Architettura
la definizione di un sistema software nei termini dei componenti che lo costituiscono delle interazioni tra tali
componenti.

I componenti possono essere considerati a vari livelli di astrazione: pu cos trattarsi di moduli, unit di routine,
procedure, oggetti. Di conseguenza, anche il concetto di interazione si differenzier in base al livello di astrazione
considerato: ad esempio, uninterazione pu corrispondere a una chiamata di procedura, allinvocazione di un
metodo, .

La descrizione dellarchitettura software


La descrizione dellarchitettura software definisce tutti gli elementi che costituiscono larchitettura, e che abbiamo
fino ad ora citato (componenti, connettori, configurazioni, unit di sviluppo, unit a runtime, moduli).

Si noti che larchitettura software esiste sempre, per ogni tipo di software, e pu avere una descrizione pi o meno
esplicita (o non avere una descrizione del tutto) ad essa associata.

Lo scopo dellIngegneria del Software di esplicitare sempre larchitettura, in modo da analizzarla, comprenderla e
migliorarla prima che avvenga la realizzazione concreta del software.

Le diverse viste architetturali che costituiscono la descrizione di unarchitettura software


Nella maggior parte dei casi, la descrizione dellarchitettura strutturata in diverse viste che mettono in evidenza
aspetti differenti:

Viste funzionali (functional view)


Definiscono lallocazione funzionale dei diversi componenti. Una vista funzionale definisce quindi i componenti e
i connettori e controlla se gli assegnamenti alle funzioni corrispondenti sono completi.

Viste di runtime (runtime view)


Definiscono le unit di runtime (i componenti disponibili in esecuzione), mostrando come collaborano tra loro.

Viste di distribuzione (deployment view)


Definiscono le principali unit di distribuzione e le linee guida allinstallazione.

Viste di modulo (module view)


Forniscono una decomposizione logica del codice in diversi moduli (design in piccolo).

83
Capitolo 8: Software design Ingegneria del Software 2

Ruolo centrale dellarchitettura software


Si pu inoltre affermare che larchitettura del software un elemento centrale del software stesso:

Codice
Strutturato in accordo a sorgente

Descrizione Descrive Architettura Strutturato in accordo a Programma


architetturale software eseguibile

Programma in
Lavora in accordo a
esecuzione

Figura 83: Centralit dellarchitettura software

Possiamo infatti affermare che gli elementi visualizzabili del software sono 3: il sorgente, leseguibile ed il programma
in esecuzione; tutti e 3 tali concetti sono legati allarchitettura, che definisce la struttura del sorgente e delleseguibile
e che descrive ci che accadr durante lesecuzione. Nonostante ci, i 3 punti diversi sono strettamente correlati tra
loro. Pi nel dettaglio:

Dal punto di vista del sorgente, si definiscono quali sono le classi, le interfacce, .
Se si adotta il punto di vista dellesecuzione, larchitettura rappresenta la definizione dei vari eseguibili e delle
interfacce che possono utilizzare, specificando come sono divisi gli elementi descritti dal punto di vista del
sorgente allinterno dei vari eseguibili finali.
Dal punto di vista del runtime, viene descritta, ad esempio, la distinzione tra i vari client e server, .

Una descrizione architetturale pi di alto livello quella dei componenti funzionali. Tale descrizione di livello
concettuale, perci i componenti qui individuati non sono necessariamente mappati su componenti concreti mediante
una relazione uno ad uno. Con componente funzionale si intende un componente in grado di offrire un certo insieme
di funzionalit.

84
Ingegneria del Software 2 Capitolo 8: Software design

Il processo di design
Che cos il processo di design
Il processo di design uninsieme di azioni che, partendo da una descrizione del problema, solitamente rappresentata
dal documento di analisi e specifica dei requisiti (spesso indicato con RASD), consente di definire tutte le viste
architetturali che si ritengono necessarie nello specifico caso. Loutput di tale processo quindi la descrizione
architetturale, che presenta tutti gli aspetti che appaiono pi appropriati per il problema che si sta considerando.

possibile adottare dei processi tra loro molto diversi per la realizzazione dellattivit di design. Alcuni di questi
approcci sono lapproccio waterfall (a cascata), lapproccio bottom-up e lapproccio incrementale.

Il processo top down (a cascata, o waterfall)


Lapproccio top down pu essere riassunto dalla seguente figura:

Fasi alte Fasi di design dettagliato

Creazione Creazione Creazione Creazione


vista vista di vista di vista di
funzionale runtime distribuzione modulo

Vista Vista di Vista di Vista di


RASD
funzionale runtime distribuzione modulo

Figura 84: Processo di design ti tipo top down

Nella precedente figura, sono stati indicati in rosso i documenti che rappresentano gli input e gli output delle varie
fasi, mentre in azzurro sono indicate le fasi del processo. Vediamo ora nel dettaglio quali operazioni vengono
compiute nelle singole fasi del processo:

Creazione della vista funzionale


Durante la definizione della vista funzionale, si individuano i componenti e i connettori e si verifica che tutte le
funzionalit richieste vengano assegnate ai componenti cos individuati.

Creazione della vista di runtime


Si verifica che per ogni funzionalit esista unentit di runtime che le contenga.

Creazione della vista di distribuzione


Si definiscono le tecnologie ed i linguaggi che verranno usati. Occorre verificare che ogni unit di runtime abbia
una corrispondente unit di distribuzione.

Creazione della vista di modulo


In questa fase si definiscono quali sono i moduli e le classi del sistema e come sono mappati alle unit di
deployment (o distribuzione) individuate nella fase precedente.

Il processo bottom up
Un processo diverso quello bottom-up, il quale viene adottato nel caso in cui si abbiano a disposizione alcuni pezzi di
codice riusabili, attorno ai quali costruire le parti restanti del sistema da sviluppare.

Gli elementi preesistenti sono rappresentati da una vista di distribuzione. Lapproccio consiste quindi nel lavorare su
tale vista, in modo da identificare la relativa vista di runtime. Inoltre, se necessario, si passa a definire la vista
funzionale.

85
Capitolo 8: Software design Ingegneria del Software 2

Uso dei diagrammi UML per il design architetturale


Durante la fase di design, si cerca spesso di astrarre alcuni dettagli del codice utilizzando diagrammi uml:

Per le viste funzionali si utilizzano class diagrams e interaction diagrams.


Per le viste di runtime, si usano component diagrams, class diagrams e interaction diagrams.
Per le viste di distribuzione, si usano soprattutto i package diagrams.
Per le viste di modulo, si usano i class diagrams, gli interaction diagrams e gli statecharts.

Strumenti a supporto delle decisioni architetturali


Spesso i designer di architetture usano dei tools di supporto alle decisioni da essi intraprese. In particolare:

Per il design di alto livello, si usano:


a) I DSSA (Domain Specific Software Architecture)
b) Gli stili architetturali
Si possono utilizzare inoltre i middleware e il loro modello a componenti (sistemi che definiscono i componenti
che il software deve avere e come essi devono essere organizzati).
Per il design dettagliato, si usano i design patterns.

I DSSA
I DSSA (Domain Specific Software Architecture) sono delle architetture di riferimento, gi realizzate da altri, utilizzate
per sviluppare software in uno specifico contesto. Per esempio, esistono delle architetture ricorrenti che si usano per
il design di software nel contesto delle telecomunicazioni o dellaereonautica. Risultano particolarmente utili se il
sistema da realizzare necessita di interfacciarsi con altri sistemi, perch si utilizza cos unarchitettura standard, che
semplifica la comunicazione con gli altri sistemi.

Tali architetture sono pensate per minimizzare i rischi e massimizzare la coerenza e la consistenza del sistema. Sono
inoltre riutilizzabili, perci se una certa funzione risulta non necessaria o necessita di essere espansa, possibile
intervenire su essa senza compromettere il resto dellarchitettura.

Un DSSA comprensivo di:

1. Un modello del dominio;


2. Un insieme di requisiti di riferimento;
3. Unarchitettura di riferimento;
4. Uninfrastruttura o ambiente a supporto del DSSA stesso;
5. Una metodologia di processo per instanziare, raffinare e valutare il DSSA stesso.

Gli stili architetturali


Il concetto di stile architetturale
Uno stile architetturale (o di design) una rappresentazione formale di una conoscenza condivisa, che viene utilizzato
soprattutto nelle ingegnerie mature. Uno stile architetturale consente cos di creare un vocabolario condiviso, creando
dei canoni di progettazione maturi.

Come abbiamo accennato nei capitoli introduttivi, lingegneria del software non ha ancora raggiunto la completa
maturit, ma ci si sta muovendo sempre di pi in tale direzione.

Pi precisamente, nellambito dellingegneria del software uno stile di design comprende:

1. I componenti che costituiscono il sistema, come ad esempio i client, i server, i database, i livelli di uno stile
gerarchico, ... .
2. Le interazioni tra i componenti, che possono essere semplici e famigliari, come le chiamate di funzioni e laccesso
a variabili condivise, oppure complessi e ricchi dal punto di vista semantico, come i protocolli client server.

86
Ingegneria del Software 2 Capitolo 8: Software design

Lo stile architetturale client-server


Lo stile architetturale di tipo client-server uno dei pi semplici e noti. Esso prevede che esistano almeno due diversi
processi, che risiedono su altrettanti host; i due processi hanno delle interfacce ben definite che consentono di
accedervi e sono caratterizzati da ruoli diversi:

Client
Il client quel processo che ricopre il ruolo attivo, occupandosi di effettuare richieste di servizio, indirizzate al
server. il client ad occuparsi di inizializzare la comunicazione, attraverso linvio di messaggi e di chiamate
remote.

Server
Il server ricopre un ruolo passivo: si limita a ricevere delle richieste e a fornire le relative risposte. Esso in grado
quindi di offrire un determinato set di servizi.

Figura 85: Schema dello stile client-server Figura 86: distribuzioni di funzionalit nello stile client-server 2-tier

Lallocazione delle funzionalit sui vari host che costituiscono il sistema pu essere di diverso tipo. Supponendo che i
calcolatori esistenti siano 2, le possibilit che si hanno a distribuzione sono mostrate nella figura precedente.

Man mano che ci si sposta dalle architetture di sinistra verso le architetture presentate pi a destra nella precedente
figura, si passa da architetture di tipo thin client ad architetture di tipo fat client. In particolare, abbiamo

Architettura distributed presentation


In questo tipo di architettura lintelligenza risiede nel server, mentre il client si occupa solo di gestire la GUI; il
client non ha a suo carico tutte le questioni di rappresentazione dei dati, ma solo alcune (si nota infatti che parte
della GUI risiede sullo stesso tier che contiene i dati ed il livello applicativo, e per questo si parla di presentazione
distribuita).

Architettura remote presentation


In questo caso il client responsabile di tutte le questioni di rappresentazione e visualizzazione.

Architettura distributed logic


Tale architettura prevede che parte della logica applicativa sia decentralizzata ed eseguita sul client.

Architettura remote data access


Larchitettura remote data access caratterizzata dal fatto che il client ha in carico sia la logica applicativa, sia le
operazioni di presentazione dei dati, mentre il server serve solo da modulo per accedere ai dati, tipicamente
attraverso uninterfaccia SQL.

Architettura distributed database


Nellarchitettura a database distribuito, la gestione dei dati eseguita in parte dal client e in parte dal server.

87
Capitolo 8: Software design Ingegneria del Software 2

Negli ultimi anni si tende sempre di pi ad utilizzare unarchitettura in cui il client non incorpora la logica, ma si
occupa solo della presentazione dei dati; il client si connette perci a dei server che implementano la logica applicativa
e comunica con il database server. Il vantaggio di tale approccio che si disaccoppia la logica dalla rappresentazione e
dai dati. In questo caso per necessario disporre di tre diversi livelli fisici, e si parla di architetture three-tier; le
principali architetture di questo tipo sono riassunte in figura.

Figura 87: Diverse distribuzioni di funzionalit nellarchitettura client-server 3-tier

Dallarchitettura a 3-tier si pu poi passare ad architetture con un numero di livelli fisici superiori. Nelle figure seguenti
sono mostrati dapprima un esempio di architettura a 3-tier, e a destra riportata unarchitettura a 4 livelli fisici.

Figura 88: Esempio di sistema 3-tier client server Figura 89: Esempio di sistema 4-tier client-server

In unarchitettura a pi tier gli oggetti possono essere:

Persistenti o volatili
Ad esempio, in JEE gli oggetti persistenti sono ottenuti mediante gli entity-beans.

Attivi o passivi
Esistono a tale scopo diversi modelli di coordinamento possibili.

Stateful o stateless
Alcuni oggetti devono tenere traccia del loro stato (oggetti stateful); tale risultato pu essere ottenuto mediante
la memorizzazione di dati sul file system, mediante basi di dati ad oggetti o mediante una mappatura con un
database relazionale.

88
Ingegneria del Software 2 Capitolo 8: Software design

Locali o distribuiti
Se gli oggetti sono locali, significa che i riferimenti ad altri oggetti sono sempre riferimenti ad entit che risiedono
sullo stesso tier sul quale risiede il riferimento stesso. In caso contrario, sono remoti.

Gli oggetti distribuiti possono essere messi in stato dormiente e poi riattivati al momento dellarrivo di una
richiesta; tali operazioni risultano per trasparenti allattivazione.

Naturalmente, una chiamata remota ha tempi di risposta molto pi alti di una chiamata locale, perci gli oggetti
distribuiti hanno solitamente un numero ridotto di metodi che compiono un elevato numero di operazioni e
richiedono molti parametri; inoltre, con oggetti distribuiti possono sorgere problemi di affidabilit, di sicurezza
delle informazioni trasmesse e di localizzazione dei dati; a ci si aggiunge che i riferimenti distribuiti hanno una
maggiore occupazione di memoria.

Gli oggetti possono essere eseguiti in parallelo, perci si hanno in ogni caso dei problemi di sincronizzazione.

Una tecnica molto usata per la gestione di oggetti distribuiti la migrazione, che consiste nelleffettuare una vera e
propria copia da una macchina allaltra degli oggetti da usare. Inoltre, in un sistema distribuito non possibile
utilizzare strumenti come il garbage collector per leliminazione automatica degli oggetti.

Solitamente gli oggetti vengono tenuti in una memoria virtuale dalla loro creazione fino alla loro distruzione; tale
scelta potrebbe comportare dei problemi:

1. Il numero di oggetti istanziati potrebbe essere molto elevato;


2. Gli oggetti potrebbero restare in memoria per molto tempo, pur essendo usati solo per brevi istanti;
3. Alcuni host potrebbero dover essere riavviati senza sospendere tutte le loro applicazioni; in questo modo,
lapplicazione verrebbe compromessa, perch i suoi dati risiedono nella memoria virtuale.

Si utilizza anche un meccanismo di attivazione e disattivazione: gli oggetti vengono portati nella memoria centrale
(attivati), elaborati, ed in seguito aggiornati dalla memoria centrale (disattivati).

inoltre fondamentale definire un modello di esecuzione nei casi di failure e anche fare delle casistiche di sicurezza
per trasferire oggetti di diversi livelli di importanza.

Lo stile architetturale funzionale


Nello stile funzionale, il sistema decomposto in operazioni astratte e le operazioni si conoscono a vicenda. I
connettori tra i vari componenti (cio tra le vaie funzioni) sono rappresentati dalle operazioni di chiamata e ritorno di
una funzione. Altre possibili interconnessioni sono rappresentate dalluso di dati condivisi.

Figura 90: Rappresentazione esemplificativa dello stile funzionale

89
Capitolo 8: Software design Ingegneria del Software 2

Lo stile architetturale a livelli


Lo stile a livelli viene adottato per mettere in evidenza lorganizzazione gerarchica dei vari livelli che costituiscono il
sistema. Naturalmente tali livelli gerarchici rappresentano unastrazione e questo modello non del tutto sostitutivo
degli altri modelli che abbiamo presentato o che presenteremo a breve. Ogni diverso livello rappresenta una macchina
astratta.

La gerarchia pu essere messa in evidenza mediante un classico grafo orientato aciclico (DAG), oppure mediante uno
schema a cipolla (onion-ring structure), come mostrato nella precedente figura.

Figura 91: Rappresentazioni alternative di uno stesso sistema con architettura a livelli

Lo stile architetturale pipes&filter


Lo stile architetturale pipes&filter molto diverso da quelli precedentemente elencati; tale stile costituito da una
serie di filtri (o componenti), ciascuno dei quali utilizza come dato dingresso loutput del filtro precedente e fornisce il
proprio output come input del successivo. Ciascun filtro ignora la presenza degli altri filtri.

Questo filtro utilizzato dal sistema operativo Unix, nel quale i singoli comandi rappresentano i vari filtri:

ps | more |
Il termine pipe viene invece usato per indicare i flussi di dati tra i vari filtri. possibile anche filtrare i risultati di diversi
componenti prima di fornirli come input del successivo filtro.

Lo stile prevede 2 possibili modalit per il controllo del flusso: si pu scegliere lapproccio batch, ovvero sequenziale,
oppure lapproccio concorrenziale, che prevede che un filtro a monte di un altro possa continuare la propria
esecuzione anche mentre in corso lesecuzione del filtro a valle, fornendo cos degli input in maniera continuativa.

I vantaggi di questo stile architetturale sono:

1. La composizionalit, ovvero la possibilit di comporre tra loro componenti creati in maniera indipendente, in
maniera molto semplice e affrontando il problema solo a posteriori.
2. La riusabilit dei componenti.
3. La facilit di modifica, dovuta soprattutto al fatto che la sostituzione di un filtro non influenza gli altri. Possiamo
affermare che il comportamento globale del sistema composta da tanti individuali comportamenti di ogni filtro.

Gli svantaggi fondamentali sono invece:

1. Lassenza di supporto alla persistenza, a meno che un filtro rappresenti un repository; lo stile di per s per non
supporta la memorizzazione persistente dei dati.
2. Lassenza di replicazione dei componenti.
3. Lapproccio solitamente di tipo batch, mentre lapproccio concorrente scarsamente usato.

90
Ingegneria del Software 2 Capitolo 8: Software design

Lo stile architetturale peer2peer


Lo stile architetturale peer2peer per certi versi contrapposto allo stile client-server: tale stile prevede infatti
lassenza di una distinzione di ruoli tra i componenti, i quali interagiscono tra loro da pari, in maniera simmetrica e
mediante interazioni di richiesta e risposta di tipo bidirezionale (ci significa che ognuno dei componenti pu
comportarsi alternativamente come client e come server, ovvero ognuno di essi pu essere il componente che d
inizio allinterazione).

Ogni peer inoltre unentit autonoma rispetto a tutti gli altri: tutti i peer condividono dei servizi e traggono beneficio
reciproco dalla loro presenza, ma possono funzionare anche senza la presenza di uno o pi dei restanti peer.

Un tipico esempio di applicazioni che seguono questo stile architetturale sono le applicazioni per il file sharing;
larchitettura usata anche per condividere i cicli di CPU nelle architetture GRID.

I principali vantaggi di questo stile sono:

1. La possibilit di avere una condivisione democratica delle informazioni;


2. La riduzione dei costi (non si ha bisogno di acquistare un server);
3. La presenza di ridondanza naturalmente insita nellarchitettura, che consente cos una maggiore sicurezza contro
la perdita dei dati.

Lo stile architetturale ad eventi


Lo stile architetturale ad eventi ha lobiettivo di fornire uno schema di coordinamento tra componenti disaccoppiati
tra loro. I diversi componenti possono ricoprire il ruolo di mittenti o di destinatari di eventi; in questultimo caso,
necessario che il componente abbia notificato al mittente il proprio interesse a ricevere la notifica di eventi di una
determinata categoria.

possibile individuare una tassonomia dei sistemi che adottano lo stile ad eventi; le principali categorie esistenti sono:

Sistemi broker mode


Questi sistemi prevedono che i riceventi inviino un messaggio di registrazione ad una certa categoria di eventi; a
tale scopo, il messaggio di sottoscrizione (subscribe message) viene inviato ad un event dispatcher, detto anche
broker o publish/subscribe service. Il broker rappresenta perci un servizio di middleware, e lazione di
sottoscrizione di fatto una dichiarazione di interesse nei confronti di determinati eventi.

Lazione indicata con il termine publish invece la generazione di un evento da parte del componente mittente.
Levento, viene comunicato al broker, il quale lo invia in broadcast a tutti i componenti che si erano
precedentemente registrati per quella categoria di eventi.

Si noti che la registrazione pu essere eseguita in base a caratteristiche diverse: ad esempio, si potr avere una
sottoscrizione per tutti i voli da Milano a New York nel mese di dicembre, oppure una sottoscrizione per tutti i
voli verso lAmerica con prezzo inferiore a 500 dollari; il broker valuter quindi di volta in volta, a seconda
dellevento, verso quali componenti inviare la notifica dellevento generato.

Il comportamento di questi sistemi di tipo asincrono; inoltre, si tratta di un comportamento reattivo (la
computazione guidata dalla ricezione di messaggi). Altra caratteristica importante lassenza di
accoppiamento: il mittente e i ricevitori vengono aggiunti senza la necessit di riconfigurare il sistema. inoltre
bene sottolineare che la destinazione dei messaggi determinata in sostanza dal ricevente stesso, e non dal
mittente, il quale non sa quali componenti riceveranno la notifica degli eventi che genera.

Questo approccio oggi sempre pi usato, soprattutto per le interfacce grafiche, che si sottoscrivono a tutti gli
eventi che devono comportare la modifica della loro stessa vista di presentazione; i vantaggi principali sono la
facilit con la quale possibile aggiungere o cancellare dei componenti e la semplicit delle strategie di
integrazione adottate.

91
Capitolo 8: Software design Ingegneria del Software 2

Per contro, si possono avere problemi di scalabilit e di ordinamento degli eventi, e non sempre possibile
garantire la ricezione dei messaggi. Riguardo allordinamento degli eventi, sarebbe desiderabile che gli eventi
venissero ricevuti nellordine mediante il quale sono stati emessi; tuttavia, nella realt dei fatti pu non essere
cos, perch la comunicazione asincrona. I middleware possono allora cercare di adottare diversi approcci:

a) Possono limitarsi a non dare alcuna garanzia di ordinamento;


b) Possono dare una garanzia di ordinamento totale (nella realt per ci quasi impossibile);
c) Possono garantire lordine causale: se un evento e2 causato da un evento e1, allora viene garantito che e1
verr ricevuto prima di e2.
d) Possono garantire lordine relativo rispetto ad un certo mittente, ovvero garantire che se lo stesso mittente
emette un evento e1 seguito dallevento e2, allora il ricevente otterr prima la notifica di e1 ed in seguito
quella di e2, e non viceversa.

Tra gli approcci elencati, quello che risulta di fatto essere solitamente il pi indicato quello che prevede la
garanzia di causalit.

Un ulteriore problematica alla quale abbiamo accennato in precedenza la garanzia di ricezione dei messaggi:
anche in questo caso, i possibili approcci sono:

a) Approccio best effort (non si d di fatto alcuna garanzia);


b) Approccio at least one (il messaggio viene ricevuto almeno una volta);
c) Approccio at most once (il messaggio viene ricevuto al pi una volta);
d) Approccio once and only once (il messaggio viene ricevuto una ed una sola volta).

Sistemi listener mode


In questa tipologia di sistemi, il ricevitore si registra al mittente, creando cos una comunicazione punto-punto.
Lapproccio perci simile a quello visto per i sistemi broker mode, ma in questo caso la registrazione avviene in
maniera diretta tra losservatore (o listener) e lelemento osservato, ovvero il componente che emette gli eventi.
Tale componente si occupa quindi anche di ricevere le sottoscrizioni e di gestirle.

Lapproccio listener mode adatto soprattutto alle applicazioni centralizzate.

Sistemi database trigger


Lapproccio usato allinterno dei database prevede che i mittenti (senders) aggiornino le tabelle, eseguendo delle
opportune query di modifica della base di dati; ai ricevitori viene poi notificato il cambiamento, mediante
lattivazione del trigger corrispondente allevento di modifica avvenuto.

Si pu affermare che tale approccio in realt una specializzazione del precedente: lelemento osservato la
tabella e gli osservatori sono i trigger ad essa associati.

C1 C2 Messaggio evento
Listener 1
1: sottoscrizione 3: ricezione
evento
Sottoscrizione
Broker Elemento
osservato
2: generazione Sottoscrizione
evento
C3 C4 C5 Listener 2
Messaggio evento
Figura 92: architettura ad eventi broker mode Figura 93: Approccio ad eventi listener mode

92
Ingegneria del Software 2 Capitolo 8: Software design

Lo stile architetturale repository


In un sistema repository-based i componenti comunicano tra loro mediante luso di un magazzino, detto appunto
repository. Lo stile perci piuttosto simile allarchitettura ad eventi broken mode, ma in questo caso lelemento
centrale il repository, nel quale i messaggi vengono memorizzati in maniera persistente (a differenza di quanto
accade con lapproccio ad eventi broker mode).

Il repository di fatto una sorta di database, che si comporta in maniera passiva e persistente. I componenti sono
invece attivi. Le azioni sono talvolta raggruppate in transazioni.

I messaggi memorizzati allinterno del repository sono detti tuple; i componenti che leggono una tupla possono
decidere se togliere dal repository la tupla letta, o se lasciarla memorizzata al suo interno. Le letture sono non-
deterministiche: nel caso in cui esistano pi tuple che corrispondo al pattern adottato per interrogare il repository,
questultimo restituir una tupla scelta in maniera casuale tra quelle disponibili. Laccesso al repository inoltre
bloccante.

Lo stile architetturale mobile code


In realt, il termine mobile code racchiude in s pi di uno stile architetturale; tutti gli stili che vanno sotto questo
nome prevedono per che si abbia uninterazione tra client e server nella quale viene di fatto spostato del codice dal
server, eseguito poi localmente dal client.

Questi approcci vengono adottati soprattutto al fine di rendere pi efficiente luso dei canali di comunicazione: se
unoperazione eseguita sul server dovesse richiedere uninterazione troppo forte con il client, talvolta conveniente
lasciar eseguire loperazione direttamente al client, fornendo a questultimo un agente, ovvero un componente che
agisce in sua vece. Naturalmente, ci conveniente a patto che il trasferimento dellagente (o agent) abbia un costo
ragionevole.

Gli approcci possibili sono 4:

Figura 94: Approccio mobile code di tipo client-server Figura 95: Approccio mobile code di tipo remote evaluation

Figura 96: Approccio mobile code di tipo code on demand Figura 97: Approccio mobile code di tipo mobile agent

93
Capitolo 8: Software design Ingegneria del Software 2

Approccio client-server
Il client invia una richiesta al server, il quale la esegue in locale e invia solamente la risposta finale.

Approccio remote evaluation


Il client anzich inviare una semplice richiesta di servizio, include nel proprio messaggio di richiesta anche il
codice che deve essere eseguito dal server.

Approccio code on demand


Il client invia una richiesta al server, il quale gli invia il codice che poi il client eseguir in locale.

Approccio mobile agent


In questo caso, si trasferisce da un calcolatore ad un altro un vero e proprio agente, il quale dotato di un
proprio stato e durante la propria esecuzione pu scegliere di trasferirsi da un computer ad un altro per sfruttare
le risorse del nuovo calcolatore.

Si parla di mobilit forte quando lo stato e il codice vengono trasferiti da ununit di esecuzione ad un diverso
ambiente computazionale; si parla di mobilit debole quando solo il codice pu essere trasferito tra ambienti
computazionali diversi.

Lo stile architetturale a plug-in


Un plug-in un frammento di codice che aggiunge funzionalit ad unapplicazione, detta host application. Tale
applicazione deve offrire opportuni meccanismi per laggiunta dei plug-in stessi, i quali a loro volta devono sottostare
ai vincoli di estensibilit definiti dalla host application e, in generale, dallarchitettura.

Alcuni tipici esempi di applicazioni sviluppate sulla base dello stile a plug-in sono Eclipse e i filtri grafici di Photoshop.

I vantaggi derivanti dalladozione di questo stile architetturale sono molteplici; per gli sviluppatori:

1. possibile implementare e incorporare nuove funzionalit per lapplicazione in maniera molto rapida.
2. Siccome i plug-in sono separati dallapplicazione e comunicano con essa mediante interfacce ben definite,
possibile isolare e risolvere rapidamente eventuali problemi del funzionamento dellapplicazione.
3. possibile creare versioni personalizzate dellapplicazione senza intervenire sul sorgente dellapplicazione stessa.
4. Parti terze possono aggiungere funzionalit allapplicazione;
5. Le interfacce per i plug-in possono essere usate per adattare il codice di sistemi preesistenti, scritti in altri
linguaggi di programmazione.

Inoltre, per gli utenti finali possibile personalizzare le funzionalit e le caratteristiche dellapplicazione, ed
eventualmente si possono disabilitare alcune funzionalit, in modo da ridurre loccupazione in memoria, aumentare le
prestazioni e semplificare linterfaccia utente.

Per definire unarchitettura a plug-in, necessario:

1. Definire una lista di metodi o funzioni che un plug-in deve implementare, oppure definire una classe di base che
dovr essere usata dai plug-in.
2. Definire un meccanismo per la registrazione.
3. Definire quale tipo di comportamento deve essere esibito da ogni metodo o funzione.

La dichiarazione dei plug-in avviene tipicamente in XML, mentre limplementazione avviene, ovviamente, in un
opportuno linguaggio di programmazione (ad esempio, Java): si ha perci unimportante distinzione tra questi 2
concetti.

In particolare, la dichiarazione di un file avviene mediante un manifest file, che specifica le interconnessioni del plug-in
con il mondo esterno, in termini di punti di estensione e di estensioni a punti di estensione definiti da altri plug-in.

94
Ingegneria del Software 2 Capitolo 8: Software design

Ad esempio, per estendere un plug-in in Eclipse, lo sviluppatore del plug-in da estendere deve aver definito
uninterfaccia associata al punto di estensione. Il plug-in che lo estende deve fornire un oggetto che implementi tale
interfaccia, in modo tale da consentire al plug-in esteso di interagire con il nuovo plug-in. Linterazione nella direzione
contraria dipende invece dallimplementazione.

Il caricamento dei plug-in avviene allo start-up dellapplicazione: vengono individuati tutti i plug-in disponibili, si
leggono i relativi manifest file e si costruisce un registro dei plug-in nella memoria centrale; i plug-in non possono
essere aggiunti durante lesecuzione dellapplicazione.

I plug-in vengono poi attivati solo quando effettivamente necessario eseguire il loro codice. Una volta attivati, i plug-
in utilizzano il registro dei plug-in presente in memoria centrale per accedere alle loro estensioni.

Lo stile architetturale SOA


Lo stile architetturale SOA (Service Oriented Architecture) prevede la presenza di uninfrastruttura aperta, nella quel i
componenti sono raggruppati e pubblicati come servizi, ovvero i componenti sono accompagnati da un contratti
rivolto ai clienti, nel quale viene specificata la qualit del servizio offerto. In questo modello architetturale per non
sufficiente fornire uninterfaccia semantica: deve infatti essere possibile individuare i servizi esistenti.

I nuovi servizi possono essere costruiti componendo dei servizi preesistenti; inoltre, ogni servizio viene eseguito
allinterno del proprio dominio.

Larchitettura prevede la presenza di 3 diversi ruoli:

1. Richiedenti del servizio, ovvero coloro che richiedono lesecuzione di un certo servizio;
2. Fornitori del servizio;
3. Intermediari (come il broker, i service registry, ), che forniscono informazioni riguardanti altre informazioni
(metainformazioni) oppure riguardanti i servizi.

Le interazioni tra i 3 ruoli appena elencati avvengono attraverso:

1. Pubblicazione della descrizione di un servizio, effettuata dal fornitore del servizio interagendo con il service
registry (che appunto lintermediario che ha il compito di gestire le descrizioni dei servizi esistenti). Questa
operazione detta anche service descritpion publication.
2. Ricerca di un servizio (service discovery).
3. Interazione tra il richiedente e il fornitore del servizio (service binding).

Tali interazioni sono riassunte anche allinterno della seguente figura.

Service
description
Service
UDDI registry WSDL

find publish

Service
Service bind Service
requestor provider Service
SOAP description

Figura 98: Schema delle interazioni previste dallarchitettura SOAP

95
Capitolo 8: Software design Ingegneria del Software 2

La principale differenza tra unapplicazione SOA e un sistema component-based che unorganizzazione che dispone
di un sistema basato sui componenti acquisisce i componenti e li mette insieme fino a costruire il sistema completo; il
componente perci, una volta acquisito, viene eseguito nel dominio dell'organizzazione che l'ha acquisito. Nei sistemi
SoA invece si segue un diverso approccio: lorganizzazione utilizza dei pezzi messi a disposizione da altre
organizzazioni, ma tali porzioni di software (che rappresentano dei servizi) non vengono vendute, non si spostano, e
lorganizzazione che li deve eseguire pu solamente utilizzarli attraverso l'interfaccia a servizi.

Lesempio tipico dellarchitettura SOA quello dei Web Service: il tradizionale paradigma del web viene esteso in
modo da poter ricercare anche delle applicazioni (servizi), anzich solamente delle informazioni passive. Per fare ci si
utilizzano dei protocolli standard per lo scambio dei dati (XML e SOAP).

In tal modo, le applicazioni che interagiscono tra loro appartengono a domini amministrativi diversi, e ciascuna
espone una certa interfaccia; per una certa funzionalit potranno essere individuati diversi fornitori di servizi.

I problemi di questo tipo di approccio sono soprattutto:

1. La sicurezza: trattandosi di un sistema aperto nel quale possono essere trasmesse informazioni critiche,
necessario avere un certo grado di fiducia nei servizi che vengono utilizzati;
2. Affidabilit dello scambio di messaggi;
3. Controllo della qualit del servizio;
4. Manutenibilit del servizio;
5. Gestione delle transazioni;
6. Composizione dei servizi;

I design pattern
Il concetto di design pattern
I design pattern sono degli schemi che rappresentano il modo di gestire i componenti in un sistema software,
solitamente sviluppato mediante un linguaggio ad oggetti; essi hanno perci lobiettivo di rendere pi semplice lo
sviluppo di moduli (che, come accennato, saranno in tal coso principalmente delle classi).

Per fare ci, i design pattern forniscono delle linee guida per linterazione reciproca tra le classi, costituendo cos degli
schemi riutilizzabili e adattabili a sistemi diversi.

La differenza principale rispetto agli stili architetturali data dal fatto che i design pattern riguardano il design in
piccolo: essi fanno riferimento al design di singoli moduli e delle loro interazioni con il sistema. In ogni caso, non
sempre il confine tra questi due concetti netto e ben definito.

I vantaggi derivanti dalluso dei design pattern sono diversi:

1. Siccome si utilizza dellinformazione consolidata, ovvero vengono usati dei paradigmi gi sviluppati, testati e
consolidati da altri, il processo di sviluppo risulta essere pi rapido;
2. Forniscono un linguaggio comune agli sviluppatori;
3. Forniscono una base solida per creare del codice pi robusto rispetto a quello che si otterrebbe mediante schemi
realizzati ad-hoc.

Per contro, i pattern introducono spesso delle ridondanze che possono portare ad inefficienze: la riusabilit del
pattern comporta un certo livello di astrazione che potrebbe complicare le cose, soprattutto in progetti troppo piccoli,
e questa una delle ragioni per le quali talvolta non vengono usati.

96
Ingegneria del Software 2 Capitolo 8: Software design

Classificazione dei design pattern


I design pattern possono essere classificati in 3 diverse categorie:

Pattern creazionali
Sono pattern che nascondono i costruttori delle classi, mettendo a disposizione degli utilizzatori dei metodi
opportuni che consentono la creazione delle relative istanze. In tal modo vengono forniti meccanismi ad-hoc per
la creazione delle nuove istanze di una nuova classe, senza che lutilizzatore conosca tali meccanismi.

Pattern strutturali
Sono pattern che forniscono delle semplici modalit per realizzare relazioni e composizioni tra le entit esistenti.
Tali pattern consentono perci di usare gli oggetti esistenti, fornendo agli utilizzatori uninterfaccia pi adatta
alle loro esigenze.

Pattern comportamentali
Questi pattern forniscono degli schemi per la comunicazione tra gli oggetti esistenti.

I pattern creazionali
Tra i pattern creazionali, i pi noti sono:

Labstract factory
Questo pattern, il cui nome significa letteralmente, "fabbrica astratta", fornisce un'interfaccia per creare famiglie
di oggetti connessi o dipendenti tra loro, in modo che non ci sia necessit da parte degli utilizzatori di specificare i
nomi delle classi concrete all'interno del proprio codice.

Il Factory method
Letteralmente metodo fabbrica, questo pattern fornisce uninterfaccia per creare un oggetto, ma lascia che le
sottoclassi decidano quale oggetto istanziare.

Il Builder
Questo pattern separa la costruzione di un oggetto complesso dalla sua rappresentazione, in modo che il
processo di costruzione stesso possa creare diverse rappresentazioni.

Il Prototype pattern
Si tratta di un pattern che permette di creare nuovi oggetti clonando un oggetto iniziale, o prototipo.

Il Singleton
un pattern che ha lo scopo di assicurare che di una classe possa essere creata una sola istanza e fornisce un
unico accesso ad essa, negando cos laccesso ai costruttori.

Tra tutti i pattern appena elencati, noi ci soffermeremo soprattutto sul pattern singleton, che risulta essere il pi
semplice da analizzare. Tale pattern viene usato quando necessario che in una certa applicazione non esistano
diverse istanze di una stessa classe, come ad esempio durante il login su un server: tutte le parti devono utilizzare la
stessa istanza per loggarsi sul server, il quale non dovrebbe essere pi in grado di cambiare listanza una volta
effettuato il login.

Figura 99: Class diagram che rappresenta il pattern singleton

Per assicurare che la classe abbia al massimo unistanza, si fornisce un punto di accesso globale allistanza stessa: tale
punto di accesso il metodo pubblico getInstance(), generalmente di tipo syncronized (in modo da consentirne

97
Capitolo 8: Software design Ingegneria del Software 2

lutilizzo in applicazioni multi-thread), definito allinterno della classe Singleton, che rappresenta la classe di cui si
vuole avere una sola istanza. Naturalmente, il metodo getInstance deve essere statico.

In genere, si sceglie di implementare una classe astratta Singleton esattamente come descritta dal precedente
diagramma UML; le classi che devono essere singleton verranno semplicemente dichiarate come eredi di tale classe.

Il costruttore della classe Singleton deve essere dichiarato privato, in modo che non sia possibile accedervi
dallesterno. Di seguito riportato il codice di una possibile implementazione in Java di questo pattern:

public class Singleton {


private static Singleton INSTANCE = null;
private Singleton() {}
private synchronized static void createInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
public static Singleton getInstance() {
createInstance();
return INSTANCE;
}
}

I pattern strutturali
Tra i pattern strutturali, i pi diffusi sono:

LAdapter
Questo pattern converte linterfaccia di una classe in una interfaccia diversa.

Bridge
Un pattern che permette di separare lastrazione di una classe dalla sua implementazione, per permettere loro di
variare indipendentemente.

Il Composite
un pattern utilizzato per dare la possibilit all'utilizzatore di manipolare gli oggetti in modo uniforme, organizza
gli oggetti in una struttura ad albero.

Il Decorator
Consente di aggiungere metodi a classi esistenti durante il run-time (cio durante lo svolgimento del
programma), permettendo una maggior flessibilit nell'aggiungere delle funzionalit agli oggetti.

Il Faade
Permette, attraverso un'interfaccia pi semplice, l'accesso a sottosistemi che espongono interfacce complesse e
diverse tra loro.

Flyweight
Letteralmente peso piuma, un pattern che permette di separare la parte variabile di una classe dalla parte
che pu essere riutilizzata.

Proxy
Il pattern fornisce una rappresentazione di un oggetto di accesso difficile o che richiede un tempo importante
per laccesso o creazione. Il Proxy consente di posticipare laccesso o creazione al momento in cui sia davvero
richiesto.

98
Ingegneria del Software 2 Capitolo 8: Software design

Focalizziamo ora la nostra attenzione sul pattern proxy. Questo pattern viene usato sia in contesto distribuito, sia in
contesto centralizzato, allo scopo di consentire a pi client di interagire con i servizi offerti da un server, ma non in
maniera diretta, al fine di rendere trasparente la localizzazione del servizio e di garantire sicurezza ed efficienza.

Per implementarlo perci necessario implementare un intermediario (solitamente una classe apposita) che svolga il
ruolo di intermediario, eseguendo delle azioni pre e post-processo.

Di seguito riportato il diagramma UML relativo al pattern in esame:

Figura 100: Class diagram che rappresenta il pattern proxy Figura 101: Sequence diagram che rappresenta il pattern proxy

Come si osserva dal class diagram, il server ed il proxy devono avere la stessa interfaccia, in modo tale che il client non
si accorga, durante le interazioni, se il proprio interlocutore il client oppure il server.

Esistono diverse tipologie di proxy:

Proxy remoto
Fornisce un riferimento a un oggetto localizzato in un diverso spazio di indirizzamento, su macchine differenti o
sulla stessa macchina.

Cache proxy
Consente limmagazzinamento temporaneo di risultati in modo che diversi client possano condividere i risultati.

Proxy di protezione dellaccesso


Permette a diversi client laccesso al servizio con differenti livelli di permesso.

Proxy virtuale
Consente la creazione di oggetti che richiedono un grande costo solo quando strettamente necessario,
nascondendo questa ottimizzazione.

Smart reference proxy


Fornisce azioni addizionali quando un oggetto viene referenziato.

Copy-on-write proxy
Rinvia la copia o clonazione di un oggetto fino allistante in cui effettivamente richiesta dal client.

99
Capitolo 8: Software design Ingegneria del Software 2

I pattern comportamentali
Tra i pattern comportali pi importanti, possiamo ricordare:

Chain of Responsibility
Letteralmente catena di responsabilit, un pattern che diminuisce laccoppiamento fra loggetto che effettua
una richiesta e quello che la soddisfa, dando a pi oggetti la possibilit di soddisfarla.

Il Command
Permette di isolare la porzione di codice che effettua un'azione dal codice che ne richiede l'esecuzione.

LInterpreter
Dato un linguaggio, definisce una rappresentazione della sua grammatica insieme ad un interprete che utilizza
questa rappresentazione per linterpretazione delle espressioni in quel determinato linguaggio.

L'Iterator
Risolve diversi problemi connessi all'accesso e alla navigazione attraverso gli elementi di una struttura dati, senza
esporre i dettagli dellimplementazione e della struttura interna del contenitore. Si tratta dei classici iteratori
Java.

Il Mediator
Si interpone nelle comunicazioni tra oggetti, allo scopo di aggiornare lo stato del sistema quando uno qualunque
di essi comunica un cambiamento del proprio stato.

Il Memento
Pattern il cui nome sta per promemoria; l'operazione di estrarre lo stato interno di un oggetto, senza violarne
lincapsulazione, e memorizzarlo per poterlo ripristinare in un momento successivo.

LObserver
Definisce una dipendenza uno a molti fra oggetti diversi, in maniera tale che se un oggetto cambia il suo stato,
tutti gli oggetti dipendenti vengono notificati del cambiamento avvenuto e possono aggiornarsi.

Lo State
Permette ad un oggetto di cambiare il suo comportamento al cambiare di un suo stato interno.

Lo Strategy
un pattern utile in quelle situazioni dove necessario modificare dinamicamente gli algoritmi utilizzati da
unapplicazione.

Il Template method
Ovvero metodo schema, permette di definire la struttura di un algoritmo lasciando alle sottoclassi il compito
di implementarne alcuni passi come preferiscono.

Il Visitor
Permette di separare un algoritmo dalla struttura di oggetti composti a cui applicato, in modo da poter
aggiungere nuovi comportamenti senza dover modificare la struttura stessa.

100
Ingegneria del Software 2 Capitolo 8: Software design

Analizziamo ora nel dettaglio il pattern Observer. Al suo interno, si individuano due ruoli diversi: il soggetto (che
losservato) e gli osservatori (o listener). Lo scopo quello di consentire ai listener di osservare come varia lo stato del
soggetto osservato, in modo che si possano aggiungere durante lesecuzione dei nuovi listener.

Figura 102: Class diagram che rappresenta il pattern observer Figura 102: Sequence diagram del pattern observer

Questo pattern dovrebbe essere utilizzato quando i cambiamenti del soggetto devono essere inviati in broadcast a
diversi observer, e il soggetto non conosce chi siano esattamente i listener in ascolto.

I pattern architetturali
Il concetto di pattern architetturali
I pattern architetturali sono degli schemi architetturali ricorrenti, definiti ad un livello di astrazione pi elevato rispetto
ai design pattern.

Il pattern MVC
Tra i pattern architetturali pi noti ed utilizzati, va citato certamente il pattern MVC (Model-View-Controller), il quale
consente la separazione tra il modello dei dati, la logica applicativa e la presentazione dei dati; tali elementi sono
infatti implementati in 3 componenti distinti:

Model
la rappresentazione delle informazioni che riguardano lo specifico dominio applicativo, indipendentemente
dalle operazioni che su tali dati verranno eseguite.

View
Presenta i dati in modo tale che sia possibile interagire con essi, tipicamente mediante uninterfaccia utente.

Controller
Risponde agli eventi, solitamente rappresentati da azioni dellutente, invocando cambiamenti sul modello e,
talvolta, anche sulla view.

In questo modo, la modifica di ciascuno dei tre componenti ha un impatto minimale sugli altri.

Il pattern MVC stato definito per la prima volta nel 1979, nel linguaggio di programmazione Smalltalk (il primo
linguaggio ad oggetti). In realt il pattern MVC considerato la composizione di pattern diversi tra quelli finora
elencati. Ad esempio, la sincronizzazione tra i 3 diversi componenti viene ottenuta mediante lapplicazione del pattern
observer. In alcuni la view interagisce solamente con il controller; in altri casi (pi frequenti), il model a segnalare i
propri cambiamenti alla view.

101
Capitolo 9: Verifica e validazione Ingegneria del Software 2

Capitolo 9: Verifica e validazione


Introduzione e terminologia
A questo punto della nostra trattazione, abbiamo analizzato tutte le fasi di progettazione del software; oltre a tali fasi,
necessario eseguire anche la fase di implementazione e quella di verifica e validazione.

In questo capitolo vogliamo soffermarci su questultima, in modo tale da stabilire quali sono i criteri attraverso i quali
accettare o meno il software prodotto e quali sono le possibili modalit attraverso le quali individuare errori di vario
genere.

La differenza tra verifica e validazione


Prima di tutto, bene operare una distinzione tra i due concetti di verifica e di validazione del software.

Verifica del software


La verifica del software consiste nel verificare se lapplicazione stata costruita in modo corretto rispetto alle
specifiche che sono state definite nelle precedenti fasi.

Validazione del software


La validazione del software consiste nel verificare se stata costruita lapplicazione corretta, ovvero se il
software corretto rispetto alle aspettative del cliente.

Naturalmente, possibile che un software superi la fase di verifica, ma non quella di validazione: ci accade
tipicamente a causa di errori nellindividuazione delle specifiche del software.

A che cosa servono le fasi di verifica e validazione?


Come si pu facilmente intuire, il software completamente privo di errori e/o difetti impossibile da ottenere;
partendo da questa semplice constatazione, si ricava la necessit di una continua e attenta attivit di verifica del
software e di tutti i prodotti che si ottengono durante il suo ciclo di vita: non solo il codice vero e proprio, ma anche il
documento di specifica dei requisiti, il design document, . In altri termini, lattivit di verifica e validazione non deve
essere eseguita solo al termine del processo di creazione del software.

Complessit della verifica del software


La verifica e validazione del software risulta particolarmente complessa, perch il software un prodotto il cui
comportamento per definizione discreto: valutare il risultato di una funzione in corrispondente di un certo valore
non ci d alcuna informazione sul comportamento che la funzione ha in corrispondenza di qualsiasi altro valore.

Inoltre, la verifica di molte qualit non pu essere eseguita pensando di ottenere solo un valore di verit del tipo
rispettata o non rispettata; a ci si aggiunge la difficolt di individuare alcune propriet, che sono enunciate solo
implicitamente, e la soggettivit delle propriet stesse. Altre difficolt derivano dal fatto che lintroduzione di nuove
tecnologie pu portare nuovi problemi ed errori.

Tutte le problematiche sopra elencate rendono necessario individuare un modo per ottenere il giusto mix di verifica
e validazione per lo specifico software in oggetto.

102
Ingegneria del Software 2 Capitolo 9: Verifica e validazione

Tempi e modalit della fase di verifica e validazione


Quando eseguire la verifica e validazione?
La fase di verifica e validazione deve iniziare sin dallinizio del processo si sviluppo del prodotto.

Ad esempio, durante lo studio di fattibilit occorre considerare le funzionalit e i requisiti di qualit, con i loro impatti
e i loro costi. Per tale ragione, esiste la figura del quality manager, che partecipa allo studia di fattibilit focalizzandosi
sul controllo della qualit e sulle modalit attraverso le quali deve essere gestito e pianificato tale controllo durante
tutto lo sviluppo del prodotto software. Il quality manager pu inoltre influenzare la scelta iniziale dellarchitettura del
sistema, in modo che venga assicurata la possibilit di testare e analizzare il sistema stesso con maggiore semplicit.

Le tecniche della verifica e validazione


La scelta delle tecniche mediante le quali effettuare la verifica e validazione del software dipende da vari parametri,
come la qualit, i costi, i vincoli di tempo e di risorse a disposizione.

Solitamente si utilizza un insieme di tecniche diverse, perch ogni tecnica potrebbe risultare efficace per una
particolare categoria di problemi, oppure potrebbe essere applicabile solo in certe fasi del progetto, o comunque
potrebbe avere diversi obiettivi o diversi rapporti tra costi e risultati garantiti.

Quando il prodotto pronto per essere messo sul mercato?


Come abbiamo detto, individuare tutti gli errori praticamente impossibile; tuttavia, ad un certo punto si rende
necessario immettere sul mercato il prodotto, e perci non possibile portare avanti la fase di testing allinfinito.

Occorre quindi stabilire dei parametri per poter decidere quando il prodotto pronto per essere commercializzato.
Una possibilit quella di stabilire dei parametri per i test, come ad esempio:

Copertura del codice


Si stabilisce una certa percentuale di copertura del codice, e il software viene rilasciato solo quando il testing ha
coperto la percentuale di codice prefissata.

Copertura di funzionalit
Si stabilisce una certa percentuale di copertura delle funzionalit, e il software viene rilasciato solo quando la
percentuale prefissata delle funzionalit da esso fornite stata gi testata.

Si possono inoltre utilizzare delle altre misure per valutare se il prodotto pronto:

Disponibilit
Si valuta la qualit del servizio in termini di rapporto tra tempo durante il quale disponibile e tempo durante il
quale down.

MTBF (Mean Time Between Failure)


lintervallo di tempo che intercorre tra due guasti successivi.

Affidabilit
Laffidabilit la percentuale che indica quante delle operazioni eseguite dal sistema sono terminate
correttamente.

Nella pratica per capita molto spesso che il software viene semplicemente rilasciato quando scade il tempo
prefissato dal cliente, oppure quando il budget a disposizione per il progetto terminato; tale scelta comporta per
molto spesso una lunga serie di problemi.

103
Capitolo 9: Verifica e validazione Ingegneria del Software 2

Verifica e validazione dei rilasci successivi del software


Quando si rilascia una nuova versione di un software, necessario verificare che i test gi eseguiti sulle precedenti
release siano ancora superati. Si parla perci di regression testing: tali test vengono eseguiti per verificare se il nuovo
software in grado di fornire ancora tutte le funzionalit che forniva prima. Questi test vengono solitamente eseguiti
con strumenti automatici, per evitare che i tempi diventino troppo lunghi.

Naturalmente, possibile aggiungere anche dei nuovi test, oltre a quelli di regressione (relativi ad esempio a nuove
funzionalit aggiunte nella versione del software che sta per essere rilasciata).

Il processo di verifica e validazione


Processo di V&V
Vediamo ora di descrivere nel dettaglio come strutturato il processo di verifica e validazione (V&V, Verification and
Validation). Questo processo non solo deve seguire tutte le fasi del processo di sviluppo del software, ma deve anche
prevedere delle soluzioni per il proprio miglioramento, mediante lidentificazione degli errori pi comuni che sono
stati commessi in passato e la realizzazione di test automatici per verificare che tali errori non si ripetano in seguito. In
sostanza quindi necessario stabilire procedure automatizzate di identificazione dei casi di test.

A tale scopo, possibile usare degli strumenti automatici che consentono di tener traccia dei bachi verificatisi in
passato e di come sono stati gestiti. Tali tool sono spesso integrati in sistemi di Configuration Management; talvolta
esistono per anche degli strumenti opensource (ad esempio, Bugzilla), non collegati ad altri tool.

Le fasi che costituiscono il processo di verifica e validazione sono 4:

1. Definizione di quali dati riguardanti gli errori necessario raccogliere;


2. Analisi dei dati raccolti al fine di identificare le categorie di appartenenza degli errori;
3. Analisi delle classi di errori e identificazione dei punti di debolezza del processo di qualit e sviluppo, mediante
opportune misure;
4. Perfezionamento del processo di qualit e sviluppo.

Il V model
La figura riporta il cosiddetto V model, adottato come modello di processo di verifica e validazione del software.

Figura 103: il V model

In questa figura sono indicate in colore pi scuro e sul lato destro della V tutti i prodotti software realizzati; sul lato
sinistro, rappresentati mediante un grigio pi chiaro, sono invece indicati i prodotti del processo di sviluppo del
software che non sono rappresentati da codice, ma da parti di documentazione (sono cio i documenti prodotti nelle
fasi alte dello sviluppo). Le frecce indicano invece le attivit di verifica (in bianco) e di validazione (in grigio). Come si
nota, la validazione unattivit che richiede la comunicazione con lesterno, mentre la verifica avviene internamente
allazienda.

104
Ingegneria del Software 2 Capitolo 9: Verifica e validazione

Pianificazione e monitoraggio
Quando si effettua una pianificazione dellanalisi e dei test su un prodotto software, necessario identificare:

1. Obiettivi e scopi;
2. Documenti e oggetti che devono essere disponibili per eseguire le diverse attivit in garanzia della qualit;
3. Gli elementi e le caratteristiche che richiedono di essere testati;
4. Le attivit di analisi e test da eseguire;
5. Il personale da coinvolgere.

Nella pianificazione devono inoltre essere inclusi i vincoli, i criteri per stabilire se il test viene superato oppure no, una
previsione dei tempi, unanalisi dei rischi, ed una serie di requisiti hardware e software.

Gli obbiettivi della qualit devono essere chiaramente definiti, ragionevoli e bisogna identificare le relazioni con gli
obbiettivi degli altri progetti in termini di qualit.

Approcci alla verifica e alla validazione


Gli approcci possibili per la verifica e validazione del software sono principalmente 2: il testing e lanalisi

Il testing
Lapproccio del testing prevede che si sperimenti il comportamento del prodotto e si cerchino dei controesempi
attraverso dei comportamenti in corrispondenza di particolari input. Si tratta quindi di una tecnica dinamica (richiede
cio lesecuzione del codice)

Lanalisi
Lapproccio dellanalisi prevede invece lo studio analitico delle propriet del software. Siccome non richiede
lesecuzione del codice, si dice anche che lanalisi una tecnica statica.

Lanalisi pu a sua volta prevedere due diversi approcci fondamentali:

1. Ispezione manuale
2. Analisi statica automatizzata

Lapproccio dellanalisi pu essere adottato in ogni fase del processo di sviluppo, ed particolarmente adatto alle fasi
alte di tale processo, quando non si ha ancora a disposizione il codice da eseguire per il testing.

Tecniche di ispezione del software


Per ispezione del software si intende la revisione formale da parte di colleghi di pari livello di un prodotto del ciclo di
vita del software, con lo scopo di trovarne i difetti.

La prima formalizzazione delle ispezioni dovuta a Michael Fagan che le ha impiegate a lungo allinterno di IBM. La
tecnica di ispezione del software, pur essendo una tecnica piuttosto rudimentale (non richiede alcuna tecnologia
particolare, anzi, una tecnica del tutto manuale) risulta spesso efficace. Come accennato dalla definizione
precedentemente fornita, questa tecnica non viene usata solo per il codice, ma anche per tutti gli altri documenti
ottenuti nel corso del ciclo di vita del software (il documento di design, lSRS o RASD, ).

I ruoli che vengono individuati nellispezione del software sono:

Il moderatore, ovvero una persona che non partecipa al progetto, e che si occuper di presiedere i meeting, di
scegliere i partecipanti e controllare il processo.
I tester e i reader ovvero coloro che si occupano di leggere il codice o il documento ricercando gli errori. I reader si
limitano ad analizzare il codice, mentre i tester svolgono una vera e propria esecuzione manuale.
Gli autori del codice (o del documento), che assistono passivamente, limitandosi a rispondere a eventuali
domande.

105
Capitolo 9: Verifica e validazione Ingegneria del Software 2

Il processo di ispezione del software solitamente articolato nelle seguenti fasi:

1. Pianificazione (il moderatore controlla i criteri iniziali, sceglie i partecipanti e fissa i meeting);
2. Overview (si fornisce un minimo di background ai partecipanti e si assegnano i ruoli; viene fornita una checklist in
cui sono descritti degli aspetti critici da controllare a seconda del linguaggio usato)
3. Preparazione.
4. Ispezione.
5. Rework (lo sviluppatore si occupa di sistemare il codice, correggendo gli errori individuati).
6. Follow-up ed eventuali re-ispezioni (il moderatore verifica che i problemi del codice siano stati risolti ed
eventualmente si procede con una nuova ispezione).

Analizziamo ora come avviene nel dettaglio lispezione. Essa si svolge attraverso dei meeting, ciascuno dei quali ha lo
scopo di individuare il maggior numero di errori possibili. Per fare ci, si realizzano solitamente 2 meeting al giorno,
della durata di 2 ore ciascuno, cercando di analizzare una media di 150 linee di codice allora. Lapproccio adottato
quello di parafrasare il codice linea per linea, ricostruirne lintento e fare un test a mano (con carta e penna). Gli errori
individuati non devono essere corretti: il moderatore verifica che ci non avvenga, perch sar poi lautore del codice
ad apportare le necessarie correzioni (in questa fase sufficiente riportare gli errori in un log).

La tipologia di errori da ricercare viene definita preventivamente mediante unapposita checklist. Il contenuto di
questa lista dipende da vari parametri, come ad esempio il tipo di progetto ed il linguaggio di programmazione, ma in
ogni caso pu contenere dei controlli di basso livello (riguardanti ad esempio il rispetto degli standard di
programmazione, come le regole seguite per lattribuzione dei nomi a variabili e costanti), cos come controlli pi di
alto livello, quali laderenza con le fasi precedenti dello sviluppo (con il Design Document).

Per incentivare lindividuazione di errori durante lispezione, una possibile strategia quella di non usare per la
valutazione personale degli autori del codice gli errori individuati durante lispezione stessa; gli errori trovati nella fase
di testing (che quella successiva) vengono invece valutati.

Lispezione del software una tecnica efficace sotto diversi punti di vista:

1. conveniente dal punto di vista economico.


2. un approccio formale e dettagliato, che tiene conto dellintero spazio degli input.
3. Pu essere applicata anche al software incompleto.
4. Tiene conto di aspetti sociali come lesperienza dellautore.

Lapproccio ha per anche alcune limitazioni:

1. Si tratta per natura di un approccio che permette di effettuare solo dei controlli sulle singole unit, e non dei
controlli di integrazione sul sistema.
2. Il test non pu essere eseguito in modo incrementale: se si realizza una nuova versione del software, necessario
effettuare nuovamente lintera ispezione.

Lanalisi automatica
Lanalisi automatica un insieme di tecniche che permettono di individuare errori in maniera automatizzata. Tra
queste tecniche, le principali sono:

Data flow analysis


La tecnica data flow analysis basata sullidentificazione delle definizioni delle variabili e dei punti nei quali le
variabili vengono usate. Questa tecnica viene tipicamente usata dai compilatori per controllare errori come luso
di variabili non ancora inizializzate, ma anche per ottimizzare il codice. I possibili controlli effettuati sono:

a) Tutte le variabili vengono utilizzate solo dopo linizializzazione? Per fare ci, si costruisce il diagramma di
flusso che rappresenta luso e lassegnamento delle variabili, e si verifica se in tutti i percorsi le variabili
vengono inizializzate prima di essere usate.

106
Ingegneria del Software 2 Capitolo 9: Verifica e validazione

b) Esistono variabili dichiarate ma mai usate? Per eseguire questo controllo, si usa ancora il diagramma di
flusso delluso e dellassegnamento delle variabili, e si verifica se esiste almeno un percorso in cui la variabile
viene dichiarata e non usata: se s, questo viene considerato un errore.
c) Esistono variabili che prima di essere usate hanno ogni volta un valore diverso?

Si noti che i punti b e c non sono di per s degli errori, ma potrebbero essere sintomi di errore. Il problema di
questo approccio che assume un punto di vista pessimistico: non possibile sapere durante il controllo se
esistono percorsi che in realt non verranno mai eseguiti. Inoltre, non si pu sempre determinare se due nomi o
espressioni si riferiscono allo stesso oggetto.

Esecuzione simbolica
In questo caso si costruiscono i predicati che caratterizzano le condizioni per lesecuzione di un certo percorso e i
predicati che individuano gli effetti che lesecuzione di un certo percorso ha sullo stato dellapplicazione. Questa
tecnica trova importanti applicazioni nellanalisi dei programmi, nella generazione dei dati per i test e nella
verifica formale della correttezza del software.

Un concetto importante per lesecuzione simbolica quello di stato simbolico. Uno stato simbolico una coppia:

<path-condition, symbolic bindings>

I valori sono cio espressi non da valori concreti, ma da espressioni costituite da opportuni simboli. Ad esempio,
la figura seguente mette a confronto lesecuzione concreta con lesecuzione simbolica di unapplicazione.

Figura 104: Esempio di esecuzione simbolica

Nel caso in cui siano presenti delle istruzioni di brach, occorre utilizzare le cosiddette path condition, le quali
conservano memoria delle condizioni sui dati di input che specificano il percorso seguito durante lesecuzione
simbolica. Costruiremo cos delle triple:

<risultato dellesecuzione, percorso seguito, path condition>

Dove il percorso seguito la sequenza di istruzioni seguite. Consideriamo il seguente esempio:

read (y, a);


x = y + 2;
if x > a
a = a + 2;
else
y = x + 3;
x = x + a + y;
Unesecuzione simbolica sar:

< {a = A, y = Y + 5, x = 2 * Y + A + 7}, <1, 2, 3, 5>, Y + 2 <= A>


Le path condition possono essere usate per sintetizzare i dati che seguono dallesecuzione di un certo path. Se un
sottoprogramma o una funzione ha una precondizione e una postcondizione, occorre controllare che la verit
della path condition implichi sempre la verit della precondizione.

107
Capitolo 9: Verifica e validazione Ingegneria del Software 2

Il testing: introduzione
A che cosa serve il testing?
Lattivit di testing consente lindividuazione di errori, ma non permette mai di dedurre la loro assenza: se nel testing
non vengono individuati errori, questo non necessariamente significa che il codice ne privo ( possibile che questi
semplicemente non siano stati individuati).

Le tecniche possibili mediante le quali eseguire il testing sono diverse; la tecnica random (che consiste nello scegliere
valori casuali tra quelli del dominio dei dati di ingresso da fornire al software da testare) la pi semplice, ma non
efficace nellindividuazione di tutti i possibili flussi, perci viene affiancata o sostituita da altre tecniche pi mirate.

Differenza tra il testing e il debugging


A questo punto, bene chiarire la distinzione tra il concetto di debugging e testing: mentre il testing ha lobiettivo di
identificare la presenza di errori, il debugging, deve localizzare il punto in cui gli errori si trovano e, di conseguenza,
correggerli. Il debugging avviene quindi dopo il testing e pu essere seguito da un nuovo test, al fine di verificare se
lerrore stato effettivamente eliminato (la ripetibilit dei test quindi una caratteristica fondamentale).

Formalizzazione dei concetti legati alla correttezza dellapplicazione


Il programma come funzione
Un programma una funzione , eventualmente parziale, definita da un certo insieme di valori di ingressi, detto
dominio , su un certo insieme di valori , detto dominio degli output:

Correttezza di un programma
Per definire la correttezza di un programma, si definisce un insieme di coppie costituite da un valore di input
e dal corrispondente valore di output atteso:

Il comportamento del programma corretto in corrispondenza dellingresso se . Il


programma corretto se .

Failure
Chiamiamo failure la manifestazione esterna di un errore, ovvero la situazione nella quale per un certo ingresso
, si ha . Ci pu accadere perch il programma non definito per quel valore (mentre dovrebbe
esserlo) oppure produce un valore di output errato.

Error
Chiamiamo errore (error) un qualsiasi evento che provoca una failure (ad esempio, un errore di battitura, la
dimenticanza dellinizializzazione di una variabile, ).

Fault
Chiamiamo fault lo stato interno in cui si trova il sistema quando si ha un errore. Il fault potrebbe non essere
visibile allesterno, cio potrebbe non manifestarsi mediante una failure, e questa la situazione pi pericolosa.

La terminologia appena introdotta non tuttavia universale. Ora che abbiamo introdotto questi concetti, possiamo
affermare che il testing ha lobiettivo di fare in modo che la presenza di errori si manifesti mediante delle failure; il
debugging deve invece identificare le situazioni di fault il pi presto possibile.

108
Ingegneria del Software 2 Capitolo 9: Verifica e validazione

Formalizzazione dei concetti legati al testing


Caso di test
Chiamiamo caso di test (test case) un singolo elemento del dominio di ingresso .

Insieme di casi di test


Chiamiamo insieme di casi di test (test set) un sottoinsieme finito del dominio dingresso .

Test terminato con successo


Diciamo che un test terminato con successo (successful test) se .

Test set terminato con successo


Diciamo che un test set terminato con successo (successful test set) se, per ogni , si ha .

Test set ideale


Un test set si dice ideale se un insieme di casi di test tale che, se il programma non corretto, esiste
almeno un elemento allinterno di per il quale si ha non corretto, ovvero .

Se esistesse un test set ideale per ogni programma, e se fossimo in grado di identificarlo, potremmo essere in
grado di provare la correttezza del software; tuttavia, non possibile stabilire se un test set ideale oppure no.

Criterio di test
Un criterio di test un sottoinsieme finito di tutti i possibili insiemi di test per un certo programma . In altri
termini, un sottoinsieme dellinsieme delle parti di , ovvero un insieme di test set.

Test set che soddisfa un criterio di test


Un test set soddisfa un criterio di test se un elemento di , ovvero .

I criteri di test: propriet


Consistenza
Un criterio di test consistente se, per ogni coppia di test , termina con successo se e solo se
termina con successo. Di conseguenza, il criterio consistenze se ogni test set che lo soddisfa fornisce di fatto le
stesse informazioni.

Completezza
Un criterio di test completo se, nel caso in cui il programma sia incorretto, esiste almeno un test set che
soddisfa e che non termina con successo. Un criterio di test completo e consistente identifica un test set
ideale, perci consente di provare la correttezza del codice.

Finezza
Un criterio di test detto pi fine di un criterio di test se, per ogni programma , si ha che per ogni test set
che soddisfa il criterio esiste un sottoinsieme di che soddisfa .

Criteri di test empirici


Nessuna delle propriet appena elencate verificabile (siamo di fronte a problemi indecidibili). Di conseguenza, non si
pu fare altro che utilizzare dei criteri di test empirici, che cerchino un compromesso tra ci che impossibile
ottenere (la prova di correttezza) e ci che inadeguato (ovvero non eseguire alcun test, o eseguire solo test casuali).

Lobiettivo di questi criteri quello di suddividere il dominio di input in sotto-domini , , , , in modo il


programma abbia, per ciascuno degli elementi di ognuno dei sottodomini cos identificati, un comportamento atteso
simile. Naturalmente, lunione dei vari sottodomini deve coincidere con il dominio di partenza, per il principio di
copertura totale. Si hanno poi diverse possibilit:

Se i sotto-domini costituiscono una partizione (sono disgiunti a 2 a 2), allora si sceglier un valore per ognuno dei
sotto-domini, e si valuter il comportamento del software in corrispondenza dei soli valori cos trovati.
In caso contrario, si cerca di ridurre il numero dei casi di test, utilizzando gli elementi appartenenti allintersezione
tra pi domini, e considerando per i sotto-domini in questione solo il caso di test comune.

109
Capitolo 9: Verifica e validazione Ingegneria del Software 2

Confronto tra testing strutturale e testing funzionale


Test funzionale e test strutturale
Per lidentificazione dei casi di test, possibile seguire uno dei due modelli seguenti:

Il test funzionale (il software come scatola nera)


In questo caso, i criteri di partizionamento si basano solo sulla specifica del modulo, ed il software considerato
come una black box: non si conosce il codice e la struttura interna del codice. Viene cos testato solo ci che il
software dovrebbe fare. Si noti inoltre che questo tipo di test dipende fortemente dal modo in cui le specifiche
vengono fornite. Uno dei suoi difetti limpossibilit di distinguere tra implementazioni diverse di uno stesso
metodo o funzione o modulo.

Il test strutturale (il software come scatola trasparente)


Il test strutturale prevede luso di criteri di partizionamento del dominio degli input basati sul codice interno dei
moduli. Seguendo questo approccio quindi, a differenza di quanto accadrebbe con il precedente, non possibile
accorgersi di eventuali funzionalit mancanti. Si va infatti a testare solo ci che il software effettivamente fa. I
test set vengono individuati sulla base del flusso di controllo e/o sul flusso di dati.

Unaltra differenza tra i due approcci riguarda la scalabilit: lapproccio black box infatti pi scalabile, perch non
rende necessaria lanalisi del codice; di conseguenza, se il codice diviene troppo lungo, anche il test strutturale
diventer lungo e complesso, mentre lo stesso non accade nel caso del test black box. A ci si aggiunga che, in casi di
elevato numero di funzionalit, ci si pu con semplicit limitare ad analizzare solo una parte della specifica.

Possibili criteri di copertura


Per stabilire se la copertura garantita dai test sufficiente oppure no, possono essere usati diversi criteri, che
verranno di seguito elencati. Per ognuno di essi, la copertura viene valutata come:

Idealmente la copertura dovrebbe essere del 100%. Si hanno criteri di controllo basati sul flusso di controllo:

Criterio statement coverage


Si valuta quante sono le istruzioni coperte dal test, senza valutare quali sono i rami seguiti a seguito delle
istruzioni condizionali.

La determinazione di un metodo automatico per individuare un test set che garantisca la completa copertura
secondo il criterio statement coverage risulta in realt impossibile: se potessimo disporre di un metodo per
stabilire se tutte le istruzioni di un programma vengono eseguite, allora saremmo in grado di stabilire se il
programma termina oppure no; come noto, per, tale problema indecidibile.

Criterio edge coverage


Si valuta quali sono i percorsi seguiti (e quindi quali sono i rami utilizzati nel diagramma di flusso
dellapplicazione); questo significa che per ogni istruzione condizionale, si deve testare il software sia nel caso in
cui la condizione sia vera, sia nel caso in cui sia falsa.

Questo criterio risulta quindi pi potente rispetto al precedente.

Criterio condition coverage


In questo caso, si valuta anche la ragione per la quale una condizione vera o falsa: se si in presenza di una
condizione composta da due parti diverse, si deve testare il comportamento del software rendendo vera o falsa
non solo lintera condizione, ma anche tutte le sue singole sottocondizioni.

110
Ingegneria del Software 2 Capitolo 9: Verifica e validazione

Criterio path coverage


Il criterio path coverage prevede che, se ci sono cicli, si valuti quale percorso deve essere seguito, ovvero quante
iterazioni coprire del ciclo stesso.

Naturalmente, non possibile coprire tutti i percorsi possibili, perch in generale sono infiniti, a seguito della
presenza dei cicli. quindi necessario stabilire dei criteri per limitare opportunamente il numero di iterazioni del
ciclo. Naturalmente per non si ha alcuna garanzia di correttezza nella scelta di tali limiti.

Esistono inoltre dei criteri basati sul flusso dei dati:

Criterio data-flow
Il criterio di copertura basato sul controllo del flusso dei dati utilizza la tecnica dellanalisi statica, per mezzo del
controllo della dipendenza con le relazioni def e use. In sostanza quindi si va ad identificare per ogni variabile
dove essa viene definita e dove viene utilizzata, e si selezionano dei test set in modo tale che tutte le possibili
coppie <def, use> vengano eseguite. Ad esempio, consideriamo il seguente codice:

0 int select(int A[], int N, int X) {


1 int i = 0;
2 while(i < N and A[i] < X) {
3 if(A[i] < 0)
4 A[i] = - A[i];
5 i++;
- }
6 return(1);
- }
In questo caso, le possibili coppie di definizione ed uso delle variabili sono:

Variabile Coppie Def/Use


i <1, 2>, <1, 3>, <1, 4>, <1, 5>, <5, 2>, <5, 3>, <5, 4>, <5, 5>
A <0, 2>, <0, 3>, <0, 4>, <4, 2>, <4, 3>, <4, 4>
N <0, 2>
X <0, 2>
Tabella 13: Coppie def-use di una porzione di codice di esempio

Si osserva perci che la coppia <5, 3> per la variabile i (cos come tutte le altre coppie che hanno il 5 come primo
elemento) viene raggiunta solo a patto che si abbiano almeno 2 iterazioni del ciclo, e quindi nel test set occorrer
tenere conto di questo. Si sceglier quindi, ad esempio, un test set del tipo:

<N = 2, X = 5, A[0] = -3, A[1] = -4>


In ogni caso, nella maggior parte dei casi impossibile raggiungere la copertura totale del secondo i criteri sopra
elencati, perch alcuni comportamenti sintatticamente possibili, nella realt non si possono verificare. Di
conseguenza, si fissano degli obiettivi inferiori al 100%, che solitamente sono tra l80% e il 95%.

111
Capitolo 9: Verifica e validazione Ingegneria del Software 2

Il test funzionale
Se si applica il test funzionale, i test set vengono individuati a partire dalla specifica e permettono di verificare ci che
il software si suppone debba fare.

Siccome la specifica espressa in linguaggio naturale, i test set non potranno essere derivati in maniera automatica. In
questo possono per venire in aiuto gli standard dellorganizzazione che realizza il software, oltre ad una serie di linee
guida, come ad esempio verificare che il test set contenga:

1. Un sottoinsieme di dati validi ed omogenei.


2. Almeno una combinazione non valida di input.
3. I dati boundary, ovvero al confine tra linsieme dei valori ammessi e quello dei valori non ammessi.
4. Tutti i valori in input particolari, che vengono trattati indipendentemente dagli altri.

Per rendere pi sistematici i test di tipo black box, possibile utilizzare alcune tecniche:

Testing basato sulle tavole di decisione


Questo metodo consiste nel realizzare una tabella nella quale ad ogni riga viene fatto corrispondere un possibile
comando (o input) fornito al sistema, e ad ogni colonna corrisponde unazione che risulta dai comandi.

A scopo esemplificativo, consideriamo la seguente specifica scritta in linguaggio naturale:

The word-processor may present portions of text in three different formats: plain text (p), boldface (b),
italics (i). The following commands may be applied to each portion of text: make text plain (P), make
boldface (B), make italics (I), emphasize (E), superemphasize (SE). Commands are available to
dynamically set E to mean either B or I (we denote such commands as E=B and E=I, respectively.)
Similarly, SE can be dynamically set to mean either B (command SE=B) or I (command SE=I), or B and I
(command SE=B+I.)

La tavola di decisione che ne deriva rappresentata in figura 105. Dovremo poi far corrispondere ad ogni
colonna almeno un caso di test; si noti per che, siccome il numero di colonne dipende dalle possibili condizioni
di ingresso dei dati, avremo nel peggiore dei casi casi di test, dove il numero di possibili condizioni (cio il
numero di righe): naturalmente, tale approccio risulterebbe in questo caso del tutto in applicazione.

Figura 105: Esempio di tavola di decisione

112
Ingegneria del Software 2 Capitolo 9: Verifica e validazione

Testing basato sui grafi di causa ed effetto


Un approccio diverso quello che consiste nel rappresentare i possibili comandi e le possibili uscite, mettendo in
relazione tali elementi con un cosiddetto grafo di causa-effetto, che appare molto simile ad una rete logica: i
comandi sono gli ingressi, le azioni sono le uscite, ed possibile legare tra loro mediante operatori logici come
AND ed OR i vari ingressi (con ovvio significato). Ad esempio, il grafo di causa ed effetto che fa riferimento alla
specifica precedentemente riportata parzialmente raffigurato nella figura seguente:

Figura 106: Esempio di grafo di causa-effetto

Nel grafo possono essere rappresentati anche dei vincoli pi dettagliati:

1. Si pu specificare che, per un certo insieme di input, se ne pu fornire al sistema al pi uno (at most one).

2. Si pu specificare che esattamente un input di un certo insieme deve essere fornire al sistema (one and only
one).

3. Si pu specificare che, per un certo insieme di input, almeno uno deve essere fornito al sistema (at least
one).

4. Si pu specificare che, se viene fornito un certo input al sistema, allora il sistema dovr ricevere anche un
altro input specificato (requires-implies).

5. Si pu specificare che, se si fornisce un certo input al sistema, allora viene bloccata la possibilit di fornirvi un
secondo input specificato (masks). Ci pu essere specificato anche per gli output.

Figura 107: At most one Figura 108: At least one Figura 109: One and only one

Figura 110: Requires (implies) Figura 111: Masks

113
Capitolo 9: Verifica e validazione Ingegneria del Software 2

Nella figura seguente sono applicati alcuni dei costrutti appena descritti per perfezionare il grafo di causa ed
effetto della specifica che abbiamo finora utilizzato per i nostri esempi:

Figura 112: Esempio di grafo di causa-effetto con costrutti per vincolare input ed output

Occorrerebbe poi testare tutte le possibili combinazioni di input ottenute mediante il grafo di causa-effetto,
controllando ogni volta che loutput ottenuto sia quello atteso. Per ridurre il numero di casi di test, possono
essere utilizzate delle euristiche, che prevedono che si parta dagli output, andando indietro verso gli input:

a) per ogni nodo OR, se si desidera renderlo vero, si considerano solo le combinazioni degli ingressi di tale nodo
nelle quali solamente uno degli ingressi ha valore true;

b) per ogni nodo OR, se si desidera renderlo falso, si considerano solo le combinazioni degli ingressi di tale
nodo nelle quali solamente uno degli ingressi ha valore false;

Derivazione dei test set a partire dai diagrammi di sequenza


possibile anche generare i test set a partire dai sequence diagram, nei quali vengono definite delle possibili
sequenze di messaggi scambiati tra i vari oggetti, solitamente corrispondenti sia alle situazioni che si verificano
pi frequentemente, sia ai casi particolari.

Lapproccio prevede diverse fasi:

1. In una prima fase, si genera un test-case per ogni sequence diagram.

2. Nelle fasi successive, si considerano nuovamente i singoli diagrammi e allinterno di ciascuno di essi si
individuano tutte le possibili situazioni alternative, generando per ognuna di esse un diverso test-case.

Anche in questo caso, la selezione dei casi di test avviene in maniera prevalentemente manuale, e non
facilmente automatizzabile.

Figura 113: Esempio di sequence diagram utilizzato per la generazione dei casi di test

114
Ingegneria del Software 2 Capitolo 9: Verifica e validazione

Considerano il sequence diagram mostrato nella precedente figura, possiamo ad esempio generare i seguenti
casi di test:

1. Un test case nel quale viene generato un nome non corretto per lo studente;
2. Un test case nel quale lo studente risulta gi iscritto al corso;
3. Un test case nel quale lo studente non pu iscriversi al corso (ad esempio, perch richiede dei corsi come
prerequisiti, ma lo studente non li ha ancora frequentati);
4. Un test case nel quale viene richiesta liscrizione ad un corso inesistente;
5. Un test case nel quale il corso non ha posti disponibili.

E cos via.

Testing basato sulla struttura sintattica degli input


Un altro approccio di tipo black-box si basa sulla struttura sintattica degli input. Conoscendo tale struttura,
rappresentata ad esempio mediante una grammatica generativa, possibile generare dei test set in modo che
tutte le regole della grammatica siano coperte dai test case considerati.

In questo caso, la specifica espressa in modo formale, perci possibile generare i test in maniera automatica.

Osservazioni varie sulla fase di test


Lanalisi dei test: gli oracoli
Una volta effettuato un test, necessario ispezionare i risultati ottenuti per andare ad individuare gli errori. Il
meccanismo utilizzato per stabilire se un test stato superato oppure no prende il nome di oracolo. In sostanza
loracolo prevede che si confronti il risultato di ogni singolo caso di test con il risultato che loracolo stesso ha stabilito
che il sistema avrebbe dovuto fornire.

Gli oracoli sono perci necessari in ogni fase del testing. Se si deve eseguire un elevato numero di test, allora risulta
indispensabile disporre di oracoli automatizzati. Tuttavia, gli oracoli sono molto complessi da progettare, e non esiste
una ricetta universale che consenta di effettuare tale operazione.

Ad esempio, in JUnit gli oracoli possono essere definiti in maniera precisa e molto semplice, mediante lutilizzo delle
asserzioni.

Il contesto di esecuzione dei test


Quando si effettua un test di unit, spesso necessario creare il contesto allinterno del quale eseguire i test stessi. A
tale scopo, oltre alloracolo, necessario costruire anche:

Il driver
Un componente che si occupa di inizializzare tutti i parametri e le variabili non locali. Tale componente si
occuper anche di chiamare lunit da testare.

Lo stub
Nel caso in cui lunit utilizzi delle altre unit, pu essere necessario realizzare dei moduli stub da sostituire a tali
unit. Si tratta perci di veri e propri templates di classi e funzioni richiamate allinterno del codice da testare.

115
Capitolo 9: Verifica e validazione Ingegneria del Software 2

Sia gli stub, sia i driver vengono realizzati mediante la stesura di porzioni di codice ad-hoc. La figura seguente mostra la
relazione tra lunit da testare, il driver, gli stub e loracolo:

Figura 114 Il test e il contesto di esecuzione

Per evitare di dover realizzare degli stub ad hoc, possibile adottare lapproccio bottom-up, il quale prevede che si
realizzi un grafo della relazione usa tra le varie unit da testare, e si proceda poi partendo dalle unit che non hanno
dipendenze con altre unit da testare, per poi risalire gradualmente tutti i vari rami dellalbero.

Test di regressione
Come gi accennato, ad ogni nuovo rilascio del software necessario effettuare dei testing. Per minimizzare gli sforzi
da affrontare in questa nuova fase di testing, opportuno:

1. Al momento del test delle precedenti versioni, memorizzare tutta la documentazione relativa ai test, tutti i casi di
test valutati con i relativi risultati, ma anche gli oracoli, i driver e gli stub utilizzati.
2. Nella nuova release, si devono poi valutare i cambiamenti apportati, tenendone traccia e considerando quale
impatto possono avere tali cambiamenti.

La documentazione dei testing


La documentazione della fase di test deve essere standardizzata e opportunamente strutturata. Per ogni test set, le
informazioni di cui tenere traccia sono:

1. Il software testato con la relativa versione.


2. Lobiettivo dei test.
3. Lautore dei test.
4. I risultati complessivi ottenuti dal test.

Per ogni test case bisogna inoltre memorizzare:

1. Lobiettivo del test case.


2. Lambiente (oracolo, driver, stub).
3. Linput fornito.
4. Loutput realmente ottenuto e quello che ci si attendeva.
5. I risultati e le osservazioni sui risultati stessi.

116