Ingegneria del Software 2

Dimensione: px
Iniziare la visualizzazioe della pagina:

Download "Ingegneria del Software 2"

Transcript

1 Politecnico di Milano Anno Accademico 2010/2011 Ingegneria del Software 2 Corso della Prof.ssa Elisabetta Di Nitto Stefano Invernizzi Facoltà di Ingegneria dell Informazione Corso di Laurea Magistrale in Ingegneria Informatica

2

3 Ingegneria del Software 2 Indice Indice Capitolo 1: Introduzione 5 L ingegneria del software: definizioni 5 L ingegneria del software e le altre discipline ingegneristiche 5 Ingegneria del software e programmazione 7 Cenni alla storia dell ingegneria del software 7 Aspetti fondamentali dell ingegneria 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 un organizzazione 26 Standard ISO Capitolo 5: Ingegneria dei requisiti 31 L ingegneria 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

4 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 l UML 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

5 Ingegneria del Software 2 Capitolo 1: Introduzione Capitolo 1: Introduzione L ingegneria del software: definizioni Possiamo dare diverse definizioni del termine Ingegneria del Software: Definizione 1 L ingegneria del software è il settore dell informatica 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 L ingegneria del software è l approccio 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 l ambiente in cui il software operava). Definizione 3 L ingegneria 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 L ingegneria 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 dell uomo. Questa definizione mette in evidenza una serie di concetti base legati in generale all ingegneria: l intenzione di risolvere dei problemi pratici, la ricerca di soluzioni vantaggiose dal punto di vista economico, l uso della conoscenza scientifica, l obiettivo di costruire qualcosa, l intento di realizzare qualcosa che sia utile per l uomo. L ingegneria 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. Nell ingegneria del software molte attività riguardano la categoria del design innovativo: nell ingegneria del software infatti non viene catturata e gestita l organizzazione di ciò che è già noto. Tutte le discipline ingegneristiche mature prevedono che le conoscenze di design vengano conservate, organizzate e condivise. L ingegneria del software si pone l obiettivo di fare questo anche nel campo software, che è un area ingegneristica ancora non completamente matura. 5

6 Capitolo 1: Introduzione Ingegneria del Software 2 Evoluzione delle pratiche dell ingegneria del software La figura seguente ritrae in maniera schematica l evoluzione prevista nell ingegneria 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 Miglioramento delle pratiche di routine Codifica di procedure sistematiche Figura 1: evoluzione delle pratiche dell ingegneria del software Differenze rispetto alle discipline ingegneristiche tradizionali La precedente figura mette in evidenza la presenza di cicli, assenti invece nell evoluzione delle pratiche adottate dalle altre discipline ingegneristiche (come ad esempio l ingegneria civile). Tale caratteristica è dovuta al fatto che il contesto nel quale opera l Ingegneria del software è sempre diverso. Si osserva inoltre che l ingegneria 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 l ingegneria 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 l uso di modelli; dopo la scelta di un certo design, tale scelta viene congelata e la flessibilità nel cambiamento di specifiche è pressoché nulla; viceversa, nell ingegneria 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 l ingegneria civile hanno ormai circa 3 millenni di vita, mentre l ingegneria 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 all analisi dei fallimenti che storicamente si sono verificati; l ingegneria del software non può invece contare su tutto questo. 6

7 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 all interno 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 all interno di più sistemi diversi tra loro. Possiamo perciò fare le seguenti affermazioni: 1. Siccome il software deve interagire con l ambiente esterno, l ingegnere del software deve essere in grado di capire e analizzare tale ambiente. Dall ambiente esterno verranno tratti i requisiti del software che verrà realizzato. 2. Dai requisiti ottenuti, occorre essere in grado di derivare una serie di specifiche dell applicazione. 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 dell ingegnere del software sono le seguenti: 1. Competenze tecniche 2. Competenze di gestione del progetto 3. Competenze cognitive 4. Capacità di organizzazione dell impresa 5. Capacità di interazione con altre culture 6. Conoscenze di dominio Cenni alla storia dell ingegneria del software L arte della programmazione Inizialmente il software veniva considerato come un arte ( l arte 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: l esempio tipico di programmi di questo tipo è rappresentato dall applicazione 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 l informatica 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: un azienda 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, l incomprensione era dovuta al fatto che nel progettare il software si ipotizzò che tutta una serie di controlli fossero svolti direttamente dall hardware, che invece li aveva demandati all applicazione. 7

8 Capitolo 1: Introduzione Ingegneria del Software 2 L ingegnerizzazione 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. L automazione del processo 4. L introduzione 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 nell ottobre È da sottolineare che l ingegneria 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). L utilizzo dell approccio 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 dell elettronica; nonostante ciò, occorre ricordare che dopo i primi anni 2000 ci fu un certo ridimensionamento del settore. Uno dei compiti fondamentali dell ingegneria 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 l evoluzione, 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. L ingegneria del software cerca quindi di limitare questi fallimenti e questi inconvenienti nello sviluppo del prodotto software stesso. Aspetti fondamentali dell ingegneria del software Gli aspetti fondamentali dell ingegneria 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

9 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 L obiettivo 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. L importanza 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 un attività creativa dell uomo durante la sua realizzazione. Gli altri prodotti prevedono invece un attività 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 2. Affidabilità 3. Robustezza 4. Prestazioni 5. Scalabilità Vediamo ora di analizzarle una dopo l altra. 6. Usabilità 7. Manutenibilità 8. Riusabilità 9. Portabilità 10. Interoperabilità 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 l individuazione 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, l approccio migliore è quello che prevede di cercare di realizzare un software corretto a priori, attraverso l adozione di un processo adeguato e l uso 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

10 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 dell utente, o che siano fondate su requisiti errati, e perciò un software corretto (cioè che soddisfa tutte le specifche) potrebbe anche non soddisfare l utente. 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 l utente si può fidare del software stesso, ovvero quest ultimo non creerà danni all utente che lo usa. Da un punto di vista matematico, l affidabilità 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 l affidabilità è una richiesta più debole rispetto alla correttezza, spesso si dà una maggiore priorità all affidabilità 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 dell hardware, 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 l analisi di complessità, e la valutazione delle performance per mezzo di modelli o simulazioni. Le performance possono influenzare l usabilità 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 l utilizzo del software stesso. I sistemi usabili sono detti talvolta anche ergonomici o user-friendly. Per valutare l usabilità del software è quindi fondamentale definire in maniera accurata quelli che saranno gli utenti che ci si aspetta che useranno l applicazione. Nonostante questo, la valutazione dell usabilità rimane piuttosto soggettiva e difficile da valutare. Una modalità tipica mediante la quale si può valutare l usabilità consiste nel far provare il sistema o il prototipo del sistema stesso ad un certo insieme di utenti appartenenti al gruppo degli expected-users. L usabilità dipende principalmente dall interfaccia con l utente (testuale o grafica). 10

11 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 un architettura 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 un altra qualità piuttosto simile alla manutenibilità. Interoperabilità (interoperability) L interoperabilità è 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 dell ingegneria 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à è l abilità 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

12 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 l approccio 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 dall utilizzatore l approccio 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 dall inizio. Un altra importante caratteristica di questo modello è la standardizzazione di tutti i prodotti risultanti da ciascuna delle singole fasi del processo. Si può perciò affermare che l obiettivo 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 fattibilità Analisi dei requisiti e specifica Design Codifica e unit test Integrazione e test di sistema Deployment Manutenzione 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

13 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 l applicazione dovrà operare, identificando così tutti i requisiti che lo caratterizzano. Da tali requisiti si derivano poi la specifiche del software, mediante l interazione con l utente. 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 l utente 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 l utente e una pianificazione dei test per il sistema. Design Nella fase di design viene definita l architettura del software, individuando quali sono i componenti (moduli) che lo costituiscono, quali sono le relazioni tra i componenti e quali interazioni avvengono tra essi. L obiettivo è quello di consentire uno sviluppo concorrente, separando le responsabilità: in questo modo i singoli componenti verranno realizzati indipendentemente l uno 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 dell unità). 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 l attività 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 l obiettivo di distribuire l applicazione e gestire le diverse installazioni e configurazioni dal lato client. 13

14 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 dall inizio. 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 l 80%). I tipi di manutenzione sono: Manutenzione correttiva Consiste nel riparare i difetti che vengono individuati all interno 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 all eliminazione di errori da sistemi nuovi). Inoltre, molto spesso la rimozione di errori comporta l introduzione 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. L evoluzione, può essere necessaria per cambiamenti del contesto nel quale l applicazione opera, per cambiamenti dei requisiti (nuove richieste degli utenti, che emergono solo dopo l introduzione 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 un architettura che faciliti i cambiamenti futuri, in modo economico e affidabile: questo è uno dei principali obiettivi dell ingegneria del software. Il costo della manutenzione evolutiva è a carico del committente. a) Manutenzione adattativa: consiste nell adattare il software ai cambiamenti dell ambiente (l hardware, i sistemi operativi, le regole di business, le leggi, ). Un esempio è stato il dover adattare le applicazioni all introduzione dell euro. È 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 dell ingegneria, devono sempre essere prima messi in atto modificando il design, e solo in seguito devono riguardare l implementazione. 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

15 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 dall inizio 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 un operazione di validazione e verifica: Validazione La validazione consiste nel verificare che, dal punto di vista dell utente, 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 dell utente. 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, l aderenza 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 un applicazione, 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 dell applicazione (ad esempio, l interfaccia grafica, nel caso in cui sia particolarmente importante l usabilità). 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 dall utente. 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 l approccio throw-away se il prototipo è stato realizzato solo per mostrare qualcosa all utente, me si usa l approccio evolutivo se il prototipo riguarda aspetti di progettazione. 15

16 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à: l idea di base è quella che in questo modo si fornisce anticipatamente un certo insieme di funzionalità, e perciò si avrà anticipatamente un feedback da parte dell utente, 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 L approccio 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 dell approccio 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 sull analisi 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

17 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 un applicazione del modello a spirare e dell approccio 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 l esecuzione dei seguenti tasks (che sono quindi quelli che costituiscono ogni iterazione della spirale stessa): 1. Identificazione dei componenti necessari 2. Ricerca dei componenti necessari all interno 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

18 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 d opera. 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 dall approccio 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 dell applicazione 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

19 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, l extreme programming sta oggi attirando su di sé forte attenzione: la flessibilità viene infatti portata a livelli estremi. La premessa sulla quale si basa l extreme programming è che risulta impossibile stabilire in maniera esatta le specifiche del software in modo anticipato. L approccio viene così paragonato a quello della guida di un auto: si ha la necessità di continui aggiustamenti. La distinzione tra il design e l implementazione risulta naturalmente molto labile, e a volte non esiste del tutto. I principi base dell XP model sono 4: 1. Comunicazione: occorre agevolare la comunicazione all interno 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 all interno del modello XP sono la codifica, il testing, l ascolto 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

20 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 l attenzione). Proprietà colletiva del codice Chiunque veda la possibilità di apportare miglioramenti, può modificare il codice. Per fare ciò, è preferibile adottare un organizzazione del codice semplice e rispettare le convenzioni di programmazione più diffuse. Integrazione continua L integrazione avviene in continuazione, senza prevedere un unica 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 dell XP Secondo i sostenitori dell XP, 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 cambiamenti Approccio tradizionale Costo dei cambiamenti Approccio XP Istante in cui il cambiamento avviene (dall avvio del progetto) Istante in cui il cambiamento avviene (dall avvio del progetto) Figura 6: confronto tra il costo dei cambiamenti con l approccio tradizionale e con l approccio 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 all utente finale. 20

21 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 nell acronimo è il nome dell azienda che ha dato vista a questo strumento, oggi diventata parte di IBM. L approccio può essere considerato un evoluzione 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, all organizzazione, al dominio dell applicazione, 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 l utilizzo di UML come linguaggio di descrizione, si basano sulle best practices e focalizzano la loro attenzione sull architettura 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 l acronimo 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. L approccio di RUP è di tipo iterativo ed incrementale, in modo tale da gestire la complessità e da consentire l evoluzione dei requisiti. 2. Inoltre, la metodologia RUP pone l enfasi sulla modellizzazione anziché sull uso 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 sull architettura 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 dell approccio RUP 1. Inception: si identificano i casi di business e l ambito 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. Vision Architettura di base Funzionalità iniziali Rilascio del prodotto Inception Elaboration Construction Transition Figura 7: fasi della metodologa RUP 21

22 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 nell ordine 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 all interno del modello RUP Sincronizzazione e stabilizzazione (Sync-and-stabilize) L approccio sync-and-stabilize L approccio 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 all introduzione 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

23 Ingegneria del Software 2 Capitolo 3: Cicli di vita del software Fasi principali Le fasi principali dell approccio 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 l intero 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 l altro. 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 l analisi delle funzionalità da implementare sin dall inizio 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 all attività di sviluppo e si ha una visione concreta del progetto e del suo livello di completamento. 23

24 Capitolo 3: Cicli di vita del software Ingegneria del Software 2 Lo sviluppo open source Gli obiettivi dell open 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. L obiettivo fondamentale dello sviluppo open source è quello di produrre del software gratuitamente disponibile per chiunque lo desideri, fornendo direttamente il codice sorgente dell applicazione. Trattandosi di uno sviluppo fortemente distribuito, la comunicazione si basa su strumenti legati ad Internet (come ad esempio le , 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 dell applicazione (ovvero la sua architettura) e valuta gli sviluppi messi a disposizione dagli altri programmatori. 24

25 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à dell organizzazione 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 l approccio 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 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à dell azienda 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 un organizzazione. 25

26 Capitolo 4: Il Capacity Maturity Model Ingegneria del Software 2 Valutazione della maturità di un organizzazione Il concetto di immaturità Come accennato, per prima cosa il CMM ha dovuto individuare le caratteristiche tipiche delle organizzazioni immature; tali caratteristiche sono: 1. L improvvisazione nel processo di sviluppo; 2. Il carattere reattivo dei manager, i quali si occupano di risolvere i problemi man mano che si presentano; 3. L incapacità di valutare correttamente i tempi ed i costi del progetto, che porta l azienda a non rispettare le scadenze, i budget e i livelli di qualità prefissati; 4. L impossibilità 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 un attività 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 un organizzazione che produce software: Continuo miglioramento del processo Processo prevedibile Definizione di standard, Processo consistente Processo metodico Livello 5: Ottimizzato Livello 4: Gestito Livello 3: Definito Livello 2: Ripetibile Livello 1: Iniziale Figura 9: i 5 livelli di maturità definiti dal SEI all interno del CMM 26

27 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, l organizzazione è 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 dell esperienza accumulata in progetti simili. Le tecniche di management consentono di stabilire degli obiettivi ragionevoli sulla base del confronto con esperienze precedenti. I manager controllano l avanzamento 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 dell organizzazione predefinito e derivazione dei singoli processi da esso) Se un organizzazione si trova al livello definito, allora all interno dell organizzazione esiste un processo documentato e standardizzato che definisce sia le attività tecniche che quelle di gestione in modo organico (organization s 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 (project s 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 un organizzazione 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 nell organizzazione. Livello gestito (processo definito e valutato attraverso opportune misure) L organizzazione è 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

28 Capitolo 4: Il Capacity Maturity Model Ingegneria del Software 2 Livello ottimizzante (miglioramento del processo basato sulle misure di valutazione della sua qualità) In un organizzazione a livello ottimizzante, i riscontri quantitativi dati dall attuazione del processo e dalla realizzazione di progetti pilota forniscono indicazioni su come migliorare continuamente il processo standard, attraverso l identificazione 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 all interno 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 un organizzazione 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 un organizzazione? I motivi per i quali la valutazione della maturità di un organizzazione è 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 un organizzazione, 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

29 Ingegneria del Software 2 Capitolo 4: Il Capacity Maturity Model Le fasi di un assessment L assessment del processo software avviene secondo le fasi seguenti. 1. La prima fase consiste nell identificare 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 nell ingegneria 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 nell analisi dei dati così raccolti è nell identificazione 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 dell organizzazione in analisi. Il team condurrà così delle interviste sul luogo e si occuperà di analizzare la documentazione dell organizzazione 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 dell azienda. 6. Infine, il team si occupa di preparare un key process area profile, nel quale vengono evidenziate le aree nelle quali l organizzazione è in grado di ottenere gli obiettivi prefissati e quelle in cui invece non è in grado di raggiungerli. È possibile che un area, pur avendo ancora delle debolezze, sia in grado di raggiungere gli obiettivi prefissati. Figura 10: le fasi di un assessment 29

30 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 dall ISO (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 (L approccio 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 dall ISO la relativa certificazione, che di conseguenza rappresenta un attestato della qualità del processo adottato dall organizzazione. Per ottenere tale certificazione, l organizzazione 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 l organizzazione 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 dell organizzazione 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 l approccio 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, l ISO 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

31 Ingegneria del Software 2 Capitolo 5: Ingegneria dei requisiti Capitolo 5: Ingegneria dei requisiti L ingegneria dei requisiti Definizione L ingegneria dei requisiti è un insieme di attività che hanno a che fare con l identificazione e la comunicazione dello scopo e dei requisiti di un sistema software Di conseguenza, possiamo affermare che l ingegneria dei requisiti fa da ponte tra le necessità dei committenti e degli utenti all interno del mondo reale e le capacità ed opportunità messe a disposizione dalle tecnologie software. Esigenze del mondo reale Requirement Engineering (RE) Tecnologie software Figura 11: L ingegneria dei requisiti come ponte tra mondo reale e tecnologie software L ingegneria 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 l insieme dei fenomeni del mondo (ovvero l insieme di tutti quegli eventi che accadono nell ambiente) e l insieme dei fenomeni del sistema (cioè l insieme di tutti quei fenomeni che accadono all interno della macchina), risulta quindi ovvio che l intersezione tra tali insiemi non può essere vuota. Fenomeni del mondo Fenomeni condivisi Fenomeni della 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. L ingegneria dei requisiti deve essere in grado di determinare quali sono i fenomeni condivisi, che rappresentano l interfaccia 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

32 Capitolo 5: Ingegneria dei requisiti Ingegneria del Software 2 L importanza dell ingegneria dei requisiti L ingegneria 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. L ingegneria 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. L ingegneria 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 l attività di identificazione e analisi dei requisiti determina con un peso circa pari al 40% l esito di successo o insuccesso di un sistema software. Complessit{ dell ingegneria dei requisiti I fattori che rendono complessa l ingegneria dei requisiti sono molteplici: 1. Complessità e vastezza dell ambiente Spesso i sistemi nei quali il software deve essere inserito risultano essere molto complessi e richiedono l interazione 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ù d uno: 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 l introduzione 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 dell applicazione, ). Tali categorie di persone hanno ovviamente dei background molto diversi tra loro, e questo conduce ad una elevata difficoltà nell individuazione di un modo di comunicare che possa essere compreso da tutti. 32

33 Ingegneria del Software 2 Capitolo 5: Ingegneria dei requisiti Le dimensioni dell ingegneria dei requisiti L ingegneria 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{ dell ingegneria dei requisiti L ingegneria dei requisiti si occupa di svolgere le seguenti attività: 1. Raccolta delle informazioni Attraverso interviste al committente e agli utenti, ma anche attraverso l analisi dei sistemi già esistenti e talvolta anche attraverso l interazione con tecnici dell aspetto di dominio dell applicazione, si individuano gli obiettivi del progetto, il contesto, l ambiente e si raccolgono le conoscenze di dominio e i requisiti. 2. Modellizzazione e analisi L ingegneria 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 l SRS, 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 l impatto che ognuno di questi cambiamenti potrà avere. 33

34 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 all interno del quale è indicato il nome dell agente stesso: Agente Figura 13: Rappresentazione di un agente all interno di un system context diagram La macchina La macchina (ovvero il S2B) viene rappresentata in maniera molto simile all agente, 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). L agente da cui la freccia ha origine è colui che controlla il fenomeno (cioè colui che lo provoca), mentre l agente sul quale la freccia arriva è l agente che lo monitora. Sulla freccia è inoltre indicato il nome del fenomeno. Agente A Fenomeno Agente B Figura 15: Rappresentazione di un fenomeno all interno 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

35 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, un ambulanza deve arrivare sul luogo dell incidente 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 l ADS (Automated Dispatching Software, ovvero il sistema) deve mobilitare l ambulanza disponibile più vicina l incidente, sulla base delle informazioni messe a disposizione dal GPS delle ambulanze. Si noti che l ingegneria 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

36 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 l insieme D delle proprietà di dominio rappresenti proprietà e assunzioni valide nel mondo in analisi. 2. Verificare che l insieme degli obiettivi G catturi tutte le esigenze degli stakeholders. 3. Assicurarsi che l insieme dei requisiti R soddisfi tutti gli obiettivi di G all interno 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 all inizio dello sviluppo del progetto: l ingegneria 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 all interno del quale vengono catturati tutti i requisiti del sistema che si vuole realizzare. L SRS 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 nell SRS 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. L SRS dovrebbe infatti contenere informazioni sufficienti per verificare se il sistema finale effettivamente soddisfa i requisiti contenuti nell SRS stesso. 5. È una base per il controllo dei cambiamenti dei requisiti e, di conseguenza, del software. A chi si rivolge l SRS? 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 nell SRS stesso. 3. Sviluppatori e programmatori, che devono fare in modo che l implementazione del software soddisfi i requisiti. 4. Tester, che dovranno verificare se i requisiti sono soddisfatti dall implementazione del software. 5. I manager del progetto, che devono analizzare, misurare e controllare il processo di sviluppo. 36

37 Ingegneria del Software 2 Capitolo 5: Ingegneria dei requisiti Chi scrive l SRS? L SRS potrebbe essere scritto da categorie diverse di persone: Chi richiede il sistema software In questo caso, l SRS deve essere abbastanza generale per raccogliere un buon numero di offerte di implementazione, ma non troppo, così da escludere le offerte non ragionevoli. L SRS è inoltre una vera e propria richiesta di proposte di implementazione, che verranno poi fornite dagli sviluppatori. Chi fornirà il sistema software L SRS è in tal caso una proposta di implementazione di un sistema, abbastanza specifica per dimostrarne la fattibilità, ma anche abbastanza generale, in modo che l organizzazione che deve fornire il software e che sta scrivendo l SRS non si impegni in modo eccessivo, imponendo requisiti difficili da implementare. Uno sviluppatore selezionato In questa situazione, l SRS 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 dell IEEE suggerisce che l SRS venga scritto congiuntamente da chi richiede il sistema e chi intende fornirlo. I contenuti dell SRS Il documento SRS dovrebbe contenere le seguenti informazioni: Funzionalità L elenco 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 l hardware 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 sull implementazione Bisogna elencare gli standard da utilizzare, la lingua dell implementazione, le politiche per l integrità del database, i limiti delle risorse, l ambiente operativo,. 37

38 Capitolo 5: Ingegneria dei requisiti Ingegneria del Software 2 La struttura dell SRS secondo lo standard IEEE L IEEE 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 dell SRS 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 User Interfaces Hardware Interfaces Software Interfaces Communication Interfaces 3.2. Functional Requirements può essere organizzata per modalità, tipologia di utenti, caratteristica, User Class Functional Requirement User Class Functional Requirement Performance Requirements 3.4. Design Constraints Standards compliance Hardware limitations 3.5. Software System Attributes Reliability Availability Security Maintainability Portability 3.6. Other Requirements Appendices Index 38

39 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. Nell SRS 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 dell ambiente deve essere chiaramente definita. Fattibilità Gli obiettivi e i requisiti definiti all interno dell SRS devono essere realizzabili all interno 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. L impatto che consegue dalla modifica di un singolo elemento dovrebbe essere facilmente valutabile. 39

40 Capitolo 5: Ingegneria dei requisiti Ingegneria del Software 2 Possibili errori all interno 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 l implementazione. 8. Mancanza di chiarezza (terminologia inventata inutilmente, presenza di frasi scritte male, ) 9. Scarsa strutturazione (riferimenti ad elementi definiti in seguito, elementi definiti all ultimo momento tra parentesi, riferimenti incrociati difficili da seguire). 10. Mancanza di tracciabilità. Osservazioni 1. La specifica dei requisiti sarà necessariamente imperfetta: l ingegneria 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 l analisi, 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: l analisi 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 nell ingegneria dei requisiti, perché abbiamo visto che ciò potrebbe comportare il fallimento del progetto. 3. Lo sviluppo del software non è un processo sequenziale, perciò l analisi 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, l individuazione 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. L esempio fa riferimento ad un tornello per il controllo dell ingresso 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 all interno 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 l accesso a chi inserisce nel tornello la moneta necessaria per entrare. 40

41 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. Nell esempio che stiamo analizzando, tali eventi saranno: 1. L evento push, che si verifica quando viene fatto ruotare il tornello. 2. L evento lock, ovvero l emissione del segnale che blocca il tornello. 3. L evento unlock, cioè l emissione del segnale che sblocca il tornello. 4. L evento enter, che si verifica quando l utente oltrepassa il tornello. 5. L evento coin, che corrisponde all inserimento 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. L unico fenomeno non condiviso tra la macchina e l ambiente è l evento enter, perché la macchina non è in grado di osservarlo. Passo 3: asserzioni o proprietà di dominio Il terzo passaggio è rappresentato dall individuazione delle asserzioni o proprietà di dominio, che caratterizzano il mondo reale. D1: Gli eventi push ed enter avvengono alternativamente, ed il primo a verificarsi è l evento push. D2: L evento push è sempre seguito dall evento enter. D3: L utente può generare l evento 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 l obiettivo 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 dell istante 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 l evento 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

42 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 all identificazione dei requisiti, e che comprendono: a) L identificazione degli attori. b) L identificazione degli scenari (cioè delle modalità di interazione tra le persone e il sistema nelle diverse circostanze). c) Identificazione dei casi d uso (che avviene sulla base degli scenari e che rappresenta un astrazione 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 un applicazione. 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 all esame di I.S.2 con il professore Di Nitto. Attori: Rossi, Di Nitto. Event flow: Rossi apre l interfaccia, 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

43 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 all interno 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 d uso, 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) L elenco degli attori partecipanti. c) La condizione di ingresso. d) Il flusso degli eventi che caratterizzano lo use case. e) La condizione d uscita. 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 dall attore 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 all identificazione degli attori e solo in seguito occuparsi della descrizione del flusso degli eventi, utilizzando il linguaggio naturale. Analisi Dopo l attività di raccolta dei requisiti, è necessaria l attività 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

44 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 dell ingegneria 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 qualcos altro, realizzato partendo dall osservazione della realtà, individuando gli elementi di interesse e proiettando solo tali elementi all interno 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 d interpretazione 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 all interno 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 l insieme di regole che permettono di scrivere il modello, consentendo cioè di organizzare le informazioni semantiche in modo che possano essere visualizzate ed editate. 44

45 Ingegneria del Software 2 Capitolo 6: UML Aspetti critici derivanti dall uso dei modelli Nell utilizzare i modelli si deve però tener conto anche di alcuni possibili problemi: 1. L astrazione 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 l implementazione). 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 è l interpretazione 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? Nell ingegneria 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 dell architettura) 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? L UML (acronimo di Unified Modelling Language) è un linguaggio di modellazione grafico a carattere generale (non è destinato solo all Ingegneria 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

46 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 è l uso 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 dell intero 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

47 Ingegneria del Software 2 Capitolo 6: UML Rappresentazione delle classi La classe Una classe viene rappresentata all interno 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 all interno di un class diagram Il nome permette di identificare l elemento del quale stiamo parlando, gli attributi consistono nell elenco 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, all interno 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 l attributo ha visibilità private. + Indica che l attributo ha visibilità public. # Indica che l attributo ha visibilità protected. ~ Indica che l attributo ha visibilità friendly. Tabella 1: Notazione adottata per indicare la visibilità all interno 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 l attributo è sottolineato. 47

48 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 l aggregazione. 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 nell esempio 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 quest ultima 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 l ereditarietà multipla. Nelle classi che ereditano da un altra, 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

49 Ingegneria del Software 2 Capitolo 6: UML Come mostrato nell esempio, l implementazione di una classe è indicata così come la generalizzazione (ereditarietà), ma con linea tratteggiata. Analogamente, le associazioni che coinvolgono l interfaccia (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 l obiettivo 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 nell interfaccia. 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 all azienda perché lavora per essa, perciò avremo un associazione tra Persona e Azienda. Come rappresentare le associazioni Le associazioni vengono rappresentate mediante delle linee che congiungono le classi interessate dall associazione 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 all interno dell associazione, 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 un indicazione 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 un azienda (non ci sono disoccupati!). È possibile anche che ci sia un associazione riflessiva (come nell esempio a lato), ovvero nella quale entrambe le estremità ricadono sulla stessa classe. Figura 25: Esempio di associazione riflessiva in un UML class diagram 49

50 Capitolo 6: UML Ingegneria del Software 2 Come si traducono le associazioni: l uso delle frecce Le associazioni si traducono concretamente attraverso l inserimento di opportuni attributi. In particolare, ogni estremo è un attributo implicito : se la cardinalità è 0..1 oppure 1, allora l attributo sarà semplicemente una variabile di tipo di riferimento all altra classe interessata dall associazione, 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 l associazione una freccia. La classe verso la quale è rivolta la freccia non conterrà attributi aggiuntivi per memorizzare l associazione. Ad esempio: Figura 25: Esempio di traduzione di un associazione all interno 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 un altra perché una di esse rappresenta una parte dell altra. 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 l oggetto completo. Si indicano comunque le cardinalità, come nelle normali associazioni. Figura 26: Esempio di aggregazione 50

51 Ingegneria del Software 2 Capitolo 6: UML Le composizioni Le composizioni poi sono un caso particolare di aggregazione: una composizione è infatti un aggregazione forte, ovvero un aggregazione nella quale le parti componenti non esistono senza il contenitore. Ciò significa che la creazione e la distruzione dei componenti avvengono all interno 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 dell aggregazione, con l unica 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 l esterno. 51

52 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. All interno del rettangolo è indicato il nome dell istanza, seguito dal suo tipo, separato dal nome mediante i due punti. Use case diagram Figura 30: Esempio di object diagram Cosa sono? I diagrammi dei casi d uso (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 d uso descrivono: 1. Il sistema; 2. L ambiente; 3. Le relazioni tra il sistema e l ambiente. 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

53 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, all interno della quale è indicato il nome del sistema stesso. Ambiente esterno SISTEMA Figura 31: Rappresentazione del sistema all interno di uno use case diagram Il rettangolo che rappresenta il sistema quindi separa ciò che è all interno del sistema stesso da ciò che invece appartiene al mondo esterno. All interno 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 dell utilizzatore. Ogni use case è rappresentato mediante un ovale all interno del quale viene indicato il nome dello use case stesso. SISTEMA nome use case Figura 32: Rappresentazione di uno use case all interno di uno use case diagram Attori Come accennato, gli attori sono gli utilizzatori del sistema. Ogni attore è rappresentato mediante il seguente simbolo, con un etichetta nella quale è riportato il nome (o una descrizione) dell attore stesso: Attore Figura 33: Rappresentazione di un attore Più nel dettaglio, possiamo dire che un attore è un entità 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). Nell interazione tra attore e sistema, l attore può rivestire un ruolo attivo (cioè richiede delle funzionalità) oppure passivo (cioè è il sistema che, per svolgere una sua funzione, ha bisogno dell attore). 53

54 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 : l attore nei confronti dello use case può essere il beneficiario, il controllore, può essere informato,. L associazione si rappresenta mediante un semplice segmento: SISTEMA Attore nome use case Figura 34: Rappresentazione di un associazione tra un attore e uno use case L associazione può anche avere un verso, che è rappresentato orientando il segmento mediante una freccia. In particolare, la freccia va verso lo use case se l attore è il soggetto attivo dell associazione (cioè è l attore a richiedere la funzionalità), mentre ha verso opposto se l attore è soggetto passivo (cioè è lo use case che richiede l intervento dell attore). Ad esempio: PRENOTAZIONE VIAGGIO Ricercare viaggio Cliente Prenotare viaggio Pagare viaggio Figura 35: Rappresentazione di un associazione orientata tra un attore e uno use case 54

55 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 L inclusione, rappresentata dallo stereotipo «includes», si rappresenta come: SISTEMA Nome use case 1 «includes» Nome use 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, dell esecuzione 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 dell attività 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 l inclusione 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 l aggregazione 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è l aggiunta 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 l esecuzione dell altro use case. L estensione rappresenta quindi solo una variazione dal comportamento standard. 55

56 Capitolo 6: UML Ingegneria del Software 2 L estensione è 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: 1 A «extends» 2 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 è l estensione di 1, mentre 1 è l esteso. In UML dovremmo rappresentare questa situazione nella maniera seguente: 1 C SISTEMA «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è è l elemento 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 l intera attività. 1 SISTEMA «extends» 2 Figura 41: Rappresentazione semplificata di una relazione di estensione tra use case 56

57 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 L unico 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 L attore figlio eredita tutte le caratteristiche dell attore padre e può partecipare a tutti gli use case a cui partecipa l attore padre. Descrizione degli use case Oltre al semplice diagramma nel quale sono indicati tutti gli specifici casi d uso, è necessario indicare, per ogni use case,una relativa descrizione, con associati ad essa uno o più scenari. Le informazioni che devono essere elencate all interno della descrizione dello use case sono state già discusse nel precedente capitolo. 57

58 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 l interazione tra oggetti, materializzando così degli scenari specifici. In particolare, essi evidenziano il modo in cui uno scenario (ovvero uno specifico percorso in un caso d uso) 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 all interno 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 l interazione 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 l utente (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 quell oggetto esiste, ma è passivo (cioè non fa nulla); se invece la linea verticale è doppia, significa che l oggetto è attivo. Infine, se la linea non è presente, significa che l oggetto 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 l istante in cui si perde il riferimento a quell oggetto). 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 all interno di un sequence diagram 58

59 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 d interazione, che consentono appunto di specificare questo tipo di situazioni. Alcuni dei più usati frame di interazione sono i seguenti: alt opt loop ref par neg Indica un alternativa del tipo (o o): se è verificata una condizione si fa una certa cosa, altrimenti se ne fa un altra. Indica un azione opzionale, che viene cioè svolta solo se è verificata una certa condizione (in caso contrario non si fa nulla). Indica l iterazione di una certa operazione. La condizione di iterazione è espressa da una descrizione a parole affiancata alla parola loop. Indica un operazione che è descritta all interno di un diverso diagramma. Indica che più frammenti vengono eseguiti in parallelo. Il frame è perciò diviso a metà. Serve per evidenziare un interazione non valida. Tabella 3: Elenco dei principali frame usati nei sequence diagram All interno 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 nell intervallo tra la verifica di disponibilità e l effettiva prenotazione, la disponibilità dell auto venga a mancare: tale situazione creerebbe ovviamente un errore. Possiamo allora disegnare il seguente diagramma di sequenza: Figura 46: Esempio di utilizzo dei frame all interno dei sequence diagram 59

60 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è l evoluzione 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 un attività più complessa. Più precisamente, l activity diagram rappresenta il flusso di controllo di attività computazionali per l esecuzione di una serie di calcoli o di un workflow. L activity 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. All implementazione 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à Un attività (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. Un attività 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 un attività all interno di un activity diagram Se l attività è contraddistinta da un * in alto a sinistra, significa che l attività può essere ripetuta più volte. L attività ha un inizio ed una fine, ed il controllo di tutto il flusso rimane all attività per tutto il tempo che intercorre tra l inizio dell attività e la sua fine (tempo che può anche essere molto lungo). Il passaggio del controllo da un attività ad un altra è detto transizione. Ovviamente, la transizione avviene quando termina l attività sorgente e dà il controllo all attività di destinazione. Ogni attività ha una transizione in ingresso ed una transizione in uscita, entrambe rappresentate mediante frecce (quella in ingresso è una freccia entrante nell attività, quella in uscita è uscente): Nome attività Figura 48: Rappresentazione di un attività e delle relative transizioni all interno di un activity diagram 60

61 Ingegneria del Software 2 Capitolo 6: UML Inizio e fine del diagramma All interno dell activity diagram esistono anche due attività fittizie, che sono l inizio e la fine del diagramma stesso. L inizio è rappresentato mediante un cerchio pieno, mentre la fine è rappresentata da un cerchio pieno all interno di un cerchio vuoto più grande. L attività di inizio ha solo una transizione di uscita, mentre quella d uscita ha solo una transizione d ingresso. Figura 49: Attività di inizio dell activity diagram Figura 50: Attività di fine dell activity 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 un attività particolare, con una sola transizione d ingresso e almeno due transizioni d uscita. Ad ogni freccia d uscita è associata una condizione. Tali condizioni devono essere mutuamente esclusive, e si deve sempre fare in modo che esattamente una di tali condizioni sia vera. L unica transizione che avviene veramente è quella associata alla condizione verificata in quella particolare istanza del diagramma. È anche possibile che un ramo d uscita 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 (nell esempio 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 all attività di destinazione dell unica transizione d uscita del merge stesso. [A] [else] Figura 51: Rappresentazione di un branch nella notazione dei sequence diagram Figura 53: Rappresentazione di un merge nella notazione dei sequence diagram Di seguito sono riportati due esempi, il secondo dei quali mette in evidenza come sia possibile realizzare un iterazione 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

62 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 all interno 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 l attività successiva. Il simbolo del join è il seguente: Figura 57: Rappresentazione di un join all interno 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

63 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. Nell esempio in figura, si hanno due swimlane: Student e System. Figura 60: Esempio di activity diagram con due swimlane Segnali Inoltre, all interno 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 l invio di segnali nell activity diagram Figura 62: Ricezione di segnali nell activity 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 [A] Attività 1 [else] [A] Attività 2 [else] Attività 2 Figura 63: Esempio di activity diagram non robusto Figura 64: Esempio di activity diagram robusto 63

64 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 B C B [C1] [else] C Figura 65: Esempio di activity diagram con fork e merge Figura 66: Esempio di activity diagram con branch e join Nell esempio di sinistra, le attività B e C vengono avviate contemporaneamente e poi, appena termina la prima, si termina l intero processo. Nell esempio 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, nell implementazione è 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 l uno con l altro. 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

65 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. L interfaccia è la definizione di un insieme di metodi (almeno uno), con l aggiunta 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. Un interfaccia 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 l ambiente esterno. Le porte sono rappresentate semplicemente come dei quadrati al margine del componente. Alla porta può essere associato un nome. <<component>> Porta Nome componente Figura 70: Rappresentazione di un porta all interno 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 l uso 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

66 Capitolo 6: UML Ingegneria del Software 2 Statechart Cosa sono? Gli state chart sono dei diagrammi a stati che consentono di rappresentare l evoluzione 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 l interazione con l esterno. 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 all interno 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 l input che determina la transizione stessa. Push switch ON OFF 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 all aumentare della complessità dell automa. 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

67 Ingegneria del Software 2 Capitolo 6: UML Notazione grafica adottata dagli statecharts Negli statecharts, ogni stato è indicato mediante un rettangolo con gli angoli smussati, all interno 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 in uno statechart Figura 74: Stato iniziale in uno statechart Di seguito è mostrato un primo semplice esempio di statechart. Figura 75: rappresentazione di uno stato finale in uno statechart Figura 76: Esempio di statechart Per ridurre il numero di stati, si possono utilizzare i cosiddetti sottostati : all interno di uno stato si rappresenta di fatto un nuovo statechart. Quando si giunge allo stato in esecuzione, viene di fatto avviata l esecuzione 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 all interno dello state chart interno. Uno stato S può inoltre avere un history substate, ovvero un sottostato che viene utilizzato perché ogni transizione in ingresso nell history substate equivale a dire che si ritorna nel sottostato di S nel quale ci si trovava prima di passare ad un nuovo stato. L history substate viene indicato mediante un pallino con all interno la lettera H. Figura 77: Esempio di state chart con sottostati Figura 78: Esempio di state chart con history substate 67

68 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; all interno 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 un azione, separata dalla parte restante dei dati della transizione mediante il simbolo di slash ( / ). La struttura è perciò: Nessuna delle 3 parti è obbligatoria. Si noti che: Evento [Condizione] / Azione L evento può essere di diversi tipi: a) Evento di chiamata (una chiamata sincrona proveniente da un certo oggetto). b) Evento di cambiamento (il valore di un espressione booleane varia). c) Evento di segnale (ricezione di un segnale asincrono). d) Evento di tempo (si arriva ad un certo istante assoluto). L azione è ciò che viene fatto durante la transizione. Può essere un azione semplice, oppure un azione 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

69 Ingegneria del Software 2 Capitolo 6: UML Utilizzare l UML 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 l insieme 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 all interno 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 l intuizione 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 all interno 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 l utente finale solitamente non sono interessati ai class diagram e focalizzano la loro attenzione soprattutto sulle funzionalità del sistema. 69

70 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 l utente è in grado di comprendere. Modellazione dinamica A questo punto si può passare alla modellazione dinamica, il cui scopo è quello di fornire dei modelli per l interazione 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 l interazione 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 all oggetto 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

71 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. L implementazione 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

72 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 L UML, 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 l uso 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 l algebra 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 un implementazione 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

73 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ò un analogia rispetto alla tradizionale attività di testing del codice; la differenza fondamentale è però nell ambiente che viene utilizzato: mentre il testing avviene campionando in maniera più o meno casuale un certo insieme di valori scelti all interno del dominio, in Alloy si considera un sottoinsieme qualsiasi del dominio, purché tale sottoinsieme sia finito, e si effettua all interno 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 l attività di verifica tramite testing e la verifica mediante l uso di Alloy (small scope hypothesys) Analisi mediante l utilizzo 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 dall assunzione 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à un osservazione pratica: nella realtà dei fatti, le formule che vengono scritte in Alloy sono quasi sempre tali che l efficienza 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

74 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 l uso 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. L operatore. L operatore fondamentale è l operatore., 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

75 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 all operatore 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 l uso di else, di seguito sono riportate due formule equivalenti: F implies G else H (F && G) (!F && H) Come già accennato, l operatore più importante è l operatore., 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 all insieme indicato come primo operando, la seconda appartenga all insieme indicato come secondo operando, e l ultimo elemento della prima tupla coincida con il primo della seconda; la tupla costruita è ottenuta semplicemente concatenando le due tuple di partenza, me eliminando l ultimo elemento della prima e tupla e il primo della seconda. L operatore. è detto anche dot join, in contrapposizione all operatore box join, del tutto equivalente al precedente, ma con una notazione diversa: e1.e2 equivale a e2[e1] 75

76 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)} Altri operatori consentiti sono quelli di restrizione e di override: ~e = {(A2, A1), (A4, A3)} 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 l insieme è di per sé una relazione, ) e restituisce la relazione costituita da quelle tuple della relazione data tali che il primo elemento appartenga all insieme 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 è l operatore di override: date due relazioni, l operatore 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 l uso 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 Condizione verificata solo se per ogni elemento del tipo dato la condizione è vera. Condizione verificata solo se per almeno un elemento del tipo dato la condizione è vera. Condizione verificata solo se per 0 o 1 elemento del tipo dato la condizione è vera. Condizione verificata solo se per 1 e solo un elemento del tipo dato la condizione è vera. Condizione verificata solo se per nessun elemento del tipo dato la condizione è vera. Tabella 10: quantificatori ammessi in Alloy Simbolo all some lone one no 76

77 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 Insieme con un numero qualsiasi di elementi Insieme con almeno un elemento Insieme con non più di un elemento (o zero, o uno) Insieme con uno ed un solo elemento Tabella 11: dichiarazione degli insiemi in Alloy Simbolo set some lone one 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, l operatore dot join introduce un altra analogia con la programmazione ad oggetti: scrivendo: Oggetto.NomeRelazione Otterremo infatti il valore o l insieme 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: Scriveremo poi: 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 operatore NomeInsieme 77

78 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 l operatore #. 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 l operatore 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 l individuazione 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 rappresentino l uno il libro prima dell operazione (b), e l altro il libro dopo l operazione (b ). b' in modo che 78

79 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 l insieme 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 all interno 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 all interno 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 nell esempio 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 all analizzatore 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

80 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 un altra si utilizza la parola chiave extends: sig NomeFiglio extends NomePadre { //elenco dei campi } In sostanza, l erede è 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 all interno 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 all interno di un qualsiasi insieme, mediante l uso 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 quest ultimo mediante una certa operazione. 80

81 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 un agenda 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 nell agenda 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

82 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: Osservazioni conclusive su Alloy Prima di concludere, è bene sottolineare che: Figura 82: Esempio di mondo generato dall Alloy Analizer Se si utilizza il comando check e l analizzatore Alloy non è in grado di individuare alcun controesempio, questo non significa che il modello sia esatto, perché l analizzatore si limita a considerare un ambiente finito; tuttavia, se l ambiente è 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

83 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 l attività di design produce l architettura 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, un interazione può corrispondere a una chiamata di procedura, all invocazione di un metodo,. La descrizione dell architettura software La descrizione dell architettura software definisce tutti gli elementi che costituiscono l architettura, e che abbiamo fino ad ora citato (componenti, connettori, configurazioni, unità di sviluppo, unità a runtime, moduli). Si noti che l architettura 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 dell Ingegneria del Software è di esplicitare sempre l architettura, in modo da analizzarla, comprenderla e migliorarla prima che avvenga la realizzazione concreta del software. Le diverse viste architetturali che costituiscono la descrizione di un architettura software Nella maggior parte dei casi, la descrizione dell architettura è strutturata in diverse viste che mettono in evidenza aspetti differenti: Viste funzionali (functional view) Definiscono l allocazione 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 all installazione. Viste di modulo (module view) Forniscono una decomposizione logica del codice in diversi moduli (design in piccolo). 83

84 Capitolo 8: Software design Ingegneria del Software 2 Ruolo centrale dell architettura software Si può inoltre affermare che l architettura del software è un elemento centrale del software stesso: Strutturato in accordo a Codice sorgente Descrizione architetturale Descrive Architettura software Strutturato in accordo a Programma eseguibile Lavora in accordo a Programma in esecuzione Figura 83: Centralità dell architettura software Possiamo infatti affermare che gli elementi visualizzabili del software sono 3: il sorgente, l eseguibile ed il programma in esecuzione; tutti e 3 tali concetti sono legati all architettura, che definisce la struttura del sorgente e dell eseguibile e che descrive ciò che accadrà durante l esecuzione. 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 dell esecuzione, l architettura 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 all interno 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

85 Ingegneria del Software 2 Capitolo 8: Software design Il processo di design Che cos è il processo di design Il processo di design è un insieme 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. L output 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 dell attività di design. Alcuni di questi approcci sono l approccio waterfall (a cascata), l approccio bottom-up e l approccio incrementale. Il processo top down (a cascata, o waterfall) L approccio top down può essere riassunto dalla seguente figura: Fasi alte Fasi di design dettagliato Creazione vista funzionale Creazione vista di runtime Creazione vista di distribuzione Creazione vista di modulo RASD Vista funzionale Vista di runtime Vista di distribuzione Vista di 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 un entità 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. L approccio 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

86 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 dell aereonautica. Risultano particolarmente utili se il sistema da realizzare necessita di interfacciarsi con altri sistemi, perché si utilizza così un architettura 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 dell architettura. Un DSSA è comprensivo di: 1. Un modello del dominio; 2. Un insieme di requisiti di riferimento; 3. Un architettura di riferimento; 4. Un infrastruttura 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, l ingegneria del software non ha ancora raggiunto la completa maturità, ma ci si sta muovendo sempre di più in tale direzione. Più precisamente, nell ambito dell ingegneria 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, Le interazioni tra i componenti, che possono essere semplici e famigliari, come le chiamate di funzioni e l accesso a variabili condivise, oppure complessi e ricchi dal punto di vista semantico, come i protocolli client server. 86

87 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 l invio 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 L allocazione 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 l intelligenza 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 L architettura 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 un interfaccia SQL. Architettura distributed database Nell architettura a database distribuito, la gestione dei dati è eseguita in parte dal client e in parte dal server. 87

88 Capitolo 8: Software design Ingegneria del Software 2 Negli ultimi anni si tende sempre di più ad utilizzare un architettura 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à nell architettura client-server 3-tier Dall architettura 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 un architettura a 4 livelli fisici. Figura 88: Esempio di sistema 3-tier client server Figura 89: Esempio di sistema 4-tier client-server In un architettura 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

89 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 dell arrivo di una richiesta; tali operazioni risultano però trasparenti all attivazione. 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 nell effettuare una vera e propria copia da una macchina all altra degli oggetti da usare. Inoltre, in un sistema distribuito non è possibile utilizzare strumenti come il garbage collector per l eliminazione 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, l applicazione 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 dall uso di dati condivisi. Figura 90: Rappresentazione esemplificativa dello stile funzionale 89

90 Capitolo 8: Software design Ingegneria del Software 2 Lo stile architetturale a livelli Lo stile a livelli viene adottato per mettere in evidenza l organizzazione gerarchica dei vari livelli che costituiscono il sistema. Naturalmente tali livelli gerarchici rappresentano un astrazione 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 d ingresso l output 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 l approccio batch, ovvero sequenziale, oppure l approccio concorrenziale, che prevede che un filtro a monte di un altro possa continuare la propria esecuzione anche mentre è in corso l esecuzione 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. L assenza 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. L assenza di replicazione dei componenti. 3. L approccio è solitamente di tipo batch, mentre l approccio concorrente è scarsamente usato. 90

91 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 l assenza 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 all interazione). Ogni peer è inoltre un entità 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; l architettura è 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 nell architettura, che consente così una maggiore sicurezza contro la perdita dei dati. Lo stile architetturale ad eventi Lo stile architetturale ad eventi ha l obiettivo 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 quest ultimo 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 l azione di sottoscrizione è di fatto una dichiarazione di interesse nei confronti di determinati eventi. L azione indicata con il termine publish è invece la generazione di un evento da parte del componente mittente. L evento, 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 l America con prezzo inferiore a 500 dollari ; il broker valuterà quindi di volta in volta, a seconda dell evento, verso quali componenti inviare la notifica dell evento 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 è l assenza 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

92 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 all ordinamento degli eventi, sarebbe desiderabile che gli eventi venissero ricevuti nell ordine 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 l ordine causale: se un evento e2 è causato da un evento e1, allora viene garantito che e1 verrà ricevuto prima di e2. d) Possono garantire l ordine relativo rispetto ad un certo mittente, ovvero garantire che se lo stesso mittente emette un evento e1 seguito dall evento 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. L approccio è perciò simile a quello visto per i sistemi broker mode, ma in questo caso la registrazione avviene in maniera diretta tra l osservatore (o listener) e l elemento osservato, ovvero il componente che emette gli eventi. Tale componente si occupa quindi anche di ricevere le sottoscrizioni e di gestirle. L approccio listener mode è adatto soprattutto alle applicazioni centralizzate. Sistemi database trigger L approccio usato all interno 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 l attivazione del trigger corrispondente all evento di modifica avvenuto. Si può affermare che tale approccio è in realtà una specializzazione del precedente: l elemento osservato è la tabella e gli osservatori sono i trigger ad essa associati. C1 1: sottoscrizione Broker C2 2: generazione evento 3: ricezione evento C3 C4 C5 Figura 92: architettura ad eventi broker mode Elemento osservato Messaggio evento Messaggio evento Sottoscrizione Sottoscrizione Listener 1 Listener 2 Figura 93: Approccio ad eventi listener mode 92

93 Ingegneria del Software 2 Capitolo 8: Software design Lo stile architetturale repository In un sistema repository-based i componenti comunicano tra loro mediante l uso di un magazzino, detto appunto repository. Lo stile è perciò piuttosto simile all architettura ad eventi broken mode, ma in questo caso l elemento centrale è il repository, nel quale i messaggi vengono memorizzati in maniera persistente (a differenza di quanto accade con l approccio 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 all interno 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 nondeterministiche: nel caso in cui esistano più tuple che corrispondo al pattern adottato per interrogare il repository, quest ultimo restituirà una tupla scelta in maniera casuale tra quelle disponibili. L accesso 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 un interazione 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 l uso dei canali di comunicazione: se un operazione eseguita sul server dovesse richiedere un interazione troppo forte con il client, è talvolta conveniente lasciar eseguire l operazione direttamente al client, fornendo a quest ultimo un agente, ovvero un componente che agisce in sua vece. Naturalmente, ciò è conveniente a patto che il trasferimento dell agente (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

94 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 un unità 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 un applicazione, detta host application. Tale applicazione deve offrire opportuni meccanismi per l aggiunta dei plug-in stessi, i quali a loro volta devono sottostare ai vincoli di estensibilità definiti dalla host application e, in generale, dall architettura. Alcuni tipici esempi di applicazioni sviluppate sulla base dello stile a plug-in sono Eclipse e i filtri grafici di Photoshop. I vantaggi derivanti dall adozione di questo stile architetturale sono molteplici; per gli sviluppatori: 1. È possibile implementare e incorporare nuove funzionalità per l applicazione in maniera molto rapida. 2. Siccome i plug-in sono separati dall applicazione e comunicano con essa mediante interfacce ben definite, è possibile isolare e risolvere rapidamente eventuali problemi del funzionamento dell applicazione. 3. È possibile creare versioni personalizzate dell applicazione senza intervenire sul sorgente dell applicazione stessa. 4. Parti terze possono aggiungere funzionalità all applicazione; 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 dell applicazione, ed eventualmente si possono disabilitare alcune funzionalità, in modo da ridurre l occupazione in memoria, aumentare le prestazioni e semplificare l interfaccia utente. Per definire un architettura 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 l implementazione avviene, ovviamente, in un opportuno linguaggio di programmazione (ad esempio, Java): si ha perciò un importante 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

95 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 un interfaccia 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. L interazione nella direzione contraria dipende invece dall implementazione. Il caricamento dei plug-in avviene allo start-up dell applicazione: 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 l esecuzione dell applicazione. I plug-in vengono poi attivati solo quando è effettivamente necessario eseguire il loro codice. Una volta attivati, i plugin 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 un infrastruttura 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 un interfaccia semantica: deve infatti essere possibile individuare i servizi esistenti. I nuovi servizi possono essere costruiti componendo dei servizi preesistenti; inoltre, ogni servizio viene eseguito all interno del proprio dominio. L architettura prevede la presenza di 3 diversi ruoli: 1. Richiedenti del servizio, ovvero coloro che richiedono l esecuzione 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 l intermediario 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 all interno della seguente figura. UDDI Service registry Service description WSDL find publish Service requestor bind SOAP Service provider Service Service description Figura 98: Schema delle interazioni previste dall architettura SOAP 95

96 Capitolo 8: Software design Ingegneria del Software 2 La principale differenza tra un applicazione SOA e un sistema component-based è che un organizzazione 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: l organizzazione 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 l organizzazione che li deve eseguire può solamente utilizzarli attraverso l'interfaccia a servizi. L esempio tipico dell architettura 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ò l obiettivo 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 l interazione 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 dall uso dei design pattern sono diversi: 1. Siccome si utilizza dell informazione 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

97 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 l utilizzatore 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 un interfaccia 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: L abstract 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 un interfaccia 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ì l accesso 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 l istanza una volta effettuato il login. Figura 99: Class diagram che rappresenta il pattern singleton Per assicurare che la classe abbia al massimo un istanza, si fornisce un punto di accesso globale all istanza stessa: tale punto di accesso è il metodo pubblico getinstance(), generalmente di tipo syncronized (in modo da consentirne 97

98 Capitolo 8: Software design Ingegneria del Software 2 l utilizzo in applicazioni multi-thread), definito all interno 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 dall esterno. 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: L Adapter Questo pattern converte l interfaccia di una classe in una interfaccia diversa. Bridge Un pattern che permette di separare l astrazione 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 Façade 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 l accesso o creazione. Il Proxy consente di posticipare l accesso o creazione al momento in cui sia davvero richiesto. 98

99 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 l immagazzinamento temporaneo di risultati in modo che diversi client possano condividere i risultati. Proxy di protezione dell accesso Permette a diversi client l accesso 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 all istante in cui è effettivamente richiesta dal client. 99

100 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 l accoppiamento fra l oggetto 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. L Interpreter Dato un linguaggio, definisce una rappresentazione della sua grammatica insieme ad un interprete che utilizza questa rappresentazione per l interpretazione 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 dell implementazione 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 l incapsulazione, e memorizzarlo per poterlo ripristinare in un momento successivo. L Observer 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 un applicazione. 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

101 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 è l osservato) 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 l esecuzione 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 un interfaccia utente. Controller Risponde agli eventi, solitamente rappresentati da azioni dell utente, 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 l applicazione 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

102 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 quest ultima, 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 l applicazione è 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 l applicazione 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 nell individuazione 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, l attività 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 l introduzione 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

103 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 dall inizio 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 dell architettura 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 all infinito. 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) È l intervallo di tempo che intercorre tra due guasti successivi. Affidabilità L affidabilità è 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

104 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 l identificazione 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. 104 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 è un attività che richiede la comunicazione con l esterno, mentre la verifica avviene internamente all azienda.

105 Ingegneria del Software 2 Capitolo 9: Verifica e validazione Pianificazione e monitoraggio Quando si effettua una pianificazione dell analisi 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, un analisi 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 l analisi Il testing L approccio 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è l esecuzione del codice) L analisi L approccio dell analisi prevede invece lo studio analitico delle proprietà del software. Siccome non richiede l esecuzione del codice, si dice anche che l analisi è una tecnica statica. L analisi può a sua volta prevedere due diversi approcci fondamentali: 1. Ispezione manuale 2. Analisi statica automatizzata L approccio dell analisi 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 all interno 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, l SRS o RASD, ). I ruoli che vengono individuati nell ispezione 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

106 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 l ispezione. 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 all ora. L approccio adottato è quello di parafrasare il codice linea per linea, ricostruirne l intento 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 l autore 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 un apposita 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 l attribuzione dei nomi a variabili e costanti), così come controlli più di alto livello, quali l aderenza con le fasi precedenti dello sviluppo (con il Design Document). Per incentivare l individuazione di errori durante l ispezione, una possibile strategia è quella di non usare per la valutazione personale degli autori del codice gli errori individuati durante l ispezione stessa; gli errori trovati nella fase di testing (che è quella successiva) vengono invece valutati. L ispezione 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 dell intero spazio degli input. 3. Può essere applicata anche al software incompleto. 4. Tiene conto di aspetti sociali come l esperienza dell autore. L approccio 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 l intera ispezione. L analisi automatica L analisi 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 sull identificazione delle definizioni delle variabili e dei punti nei quali le variabili vengono usate. Questa tecnica viene tipicamente usata dai compilatori per controllare errori come l uso di variabili non ancora inizializzate, ma anche per ottimizzare il codice. I possibili controlli effettuati sono: a) Tutte le variabili vengono utilizzate solo dopo l inizializzazione? Per fare ciò, si costruisce il diagramma di flusso che rappresenta l uso e l assegnamento delle variabili, e si verifica se in tutti i percorsi le variabili vengono inizializzate prima di essere usate. 106

107 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 dell uso e dell assegnamento 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 l esecuzione di un certo percorso e i predicati che individuano gli effetti che l esecuzione di un certo percorso ha sullo stato dell applicazione. Questa tecnica trova importanti applicazioni nell analisi dei programmi, nella generazione dei dati per i test e nella verifica formale della correttezza del software. Un concetto importante per l esecuzione 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 l esecuzione concreta con l esecuzione simbolica di un applicazione. 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 l esecuzione simbolica. Costruiremo così delle triple: <risultato dell esecuzione, 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; Un esecuzione 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 dall esecuzione 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

108 Capitolo 9: Verifica e validazione Ingegneria del Software 2 Il testing: introduzione A che cosa serve il testing? L attività di testing consente l individuazione 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 nell individuazione 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 l obiettivo 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 l errore è stato effettivamente eliminato (la ripetibilità dei test è quindi una caratteristica fondamentale). Formalizzazione dei concetti legati alla correttezza dell applicazione 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 e dal corrispondente valore di output atteso: di coppie costituite da un valore di input Il comportamento del programma è corretto in corrispondenza dell ingresso 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 dell inizializzazione 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 all esterno, 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 l obiettivo 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

109 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 d ingresso. 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 all interno 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 dell insieme 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). L obiettivo 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, l unione 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 all intersezione tra più domini, e considerando per i sotto-domini in questione solo il caso di test comune. 109

110 Capitolo 9: Verifica e validazione Ingegneria del Software 2 Confronto tra testing strutturale e testing funzionale Test funzionale e test strutturale Per l identificazione 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 è l impossibilità 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 l uso 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. Un altra differenza tra i due approcci riguarda la scalabilità: l approccio black box è infatti più scalabile, perché non rende necessaria l analisi 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 dell applicazione); 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 l intera condizione, ma anche tutte le sue singole sottocondizioni. 110

111 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 dell analisi 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 l 80% e il 95%. 111

112 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 dell organizzazione 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 l insieme 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 un azione 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

113 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

114 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 l output 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. L approccio 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 all interno 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

115 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 l iscrizione 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 L analisi 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 l oracolo prevede che si confronti il risultato di ogni singolo caso di test con il risultato che l oracolo 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 l utilizzo delle asserzioni. Il contesto di esecuzione dei test Quando si effettua un test di unità, è spesso necessario creare il contesto all interno del quale eseguire i test stessi. A tale scopo, oltre all oracolo, è 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 l unità da testare. Lo stub Nel caso in cui l unità 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 all interno del codice da testare. 115

116 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 l unità da testare, il driver, gli stub e l oracolo: Figura 114 Il test e il contesto di esecuzione Per evitare di dover realizzare degli stub ad hoc, è possibile adottare l approccio 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 dell albero. 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. L obiettivo dei test. 3. L autore dei test. 4. I risultati complessivi ottenuti dal test. Per ogni test case bisogna inoltre memorizzare: 1. L obiettivo del test case. 2. L ambiente (oracolo, driver, stub). 3. L input fornito. 4. L output realmente ottenuto e quello che ci si attendeva. 5. I risultati e le osservazioni sui risultati stessi. 116

Rational Unified Process Introduzione

Rational Unified Process Introduzione Rational Unified Process Introduzione G.Raiss - A.Apolloni - 4 maggio 2001 1 Cosa è E un processo di sviluppo definito da Booch, Rumbaugh, Jacobson (autori dell Unified Modeling Language). Il RUP è un

Dettagli

UML e (R)UP (an overview)

UML e (R)UP (an overview) Lo sviluppo di sistemi OO UML e (R)UP (an overview) http://www.rational.com http://www.omg.org 1 Riassumento UML E un insieme di notazioni diagrammatiche che, utilizzate congiuntamente, consentono di descrivere/modellare

Dettagli

RUP (Rational Unified Process)

RUP (Rational Unified Process) RUP (Rational Unified Process) Caratteristiche, Punti di forza, Limiti versione del tutorial: 3.3 (febbraio 2007) Pag. 1 Unified Process Booch, Rumbaugh, Jacobson UML (Unified Modeling Language) notazione

Dettagli

Processi (di sviluppo del) software. Fase di Analisi dei Requisiti. Esempi di Feature e Requisiti. Progettazione ed implementazione

Processi (di sviluppo del) software. Fase di Analisi dei Requisiti. Esempi di Feature e Requisiti. Progettazione ed implementazione Processi (di sviluppo del) software Fase di Analisi dei Requisiti Un processo software descrive le attività (o task) necessarie allo sviluppo di un prodotto software e come queste attività sono collegate

Dettagli

Cos è l Ingegneria del Software?

Cos è l Ingegneria del Software? Cos è l Ingegneria del Software? Corpus di metodologie e tecniche per la produzione di sistemi software. L ingegneria del software è la disciplina tecnologica e gestionale che riguarda la produzione sistematica

Dettagli

Ciclo di Vita Evolutivo

Ciclo di Vita Evolutivo Ciclo di Vita Evolutivo Prof.ssa Enrica Gentile a.a. 2011-2012 Modello del ciclo di vita Stabiliti gli obiettivi ed i requisiti Si procede: All analisi del sistema nella sua interezza Alla progettazione

Dettagli

2. Ciclo di Vita e Processi di Sviluppo

2. Ciclo di Vita e Processi di Sviluppo 2. Ciclo di Vita e Processi di Sviluppo come posso procedere nello sviluppo? Andrea Polini Ingegneria del Software Corso di Laurea in Informatica (Ingegneria del Software) 2. Ciclo di Vita e Processi di

Dettagli

Il ciclo di vita del software

Il ciclo di vita del software Il ciclo di vita del software Il ciclo di vita del software Definisce un modello per il software, dalla sua concezione iniziale fino al suo sviluppo completo, al suo rilascio, alla sua successiva evoluzione,

Dettagli

Il software: natura e qualità

Il software: natura e qualità Sommario Il software: natura e qualità Leggere Cap. 2 Ghezzi et al. Natura e peculiarità del software Classificazione delle qualità del software Qualità del prodotto e del processo Qualità interne ed esterne

Dettagli

metodologie metodologia una serie di linee guida per raggiungere certi obiettivi

metodologie metodologia una serie di linee guida per raggiungere certi obiettivi metodologie a.a. 2003-2004 1 metodologia una serie di linee guida per raggiungere certi obiettivi più formalmente: un processo da seguire documenti o altri elaborati da produrre usando linguaggi più o

Dettagli

AOT Lab Dipartimento di Ingegneria dell Informazione Università degli Studi di Parma. Unified Process. Prof. Agostino Poggi

AOT Lab Dipartimento di Ingegneria dell Informazione Università degli Studi di Parma. Unified Process. Prof. Agostino Poggi AOT Lab Dipartimento di Ingegneria dell Informazione Università degli Studi di Parma Unified Process Prof. Agostino Poggi Unified Process Unified Software Development Process (USDP), comunemente chiamato

Dettagli

13. Ciclo di Vita e Processi di Sviluppo

13. Ciclo di Vita e Processi di Sviluppo 13. Ciclo di Vita e Processi di Sviluppo come posso procedere nello sviluppo? Andrea Polini Ingegneria del Software Corso di Laurea in Informatica (Ingegneria del Software) 13. Ciclo di Vita e Processi

Dettagli

Ciclo di vita del progetto

Ciclo di vita del progetto IT Project Management Lezione 2 Ciclo di vita del progetto Federica Spiga A.A. 2009-2010 1 Ciclo di vita del progetto Il ciclo di vita del progetto definisce le fasi che collegano l inizio e la fine del

Dettagli

Principi dell ingegneria del software Relazioni fra

Principi dell ingegneria del software Relazioni fra Sommario Principi dell ingegneria del software Leggere Cap. 3 Ghezzi et al. Principi dell ingegneria del software Relazioni fra Principi Metodi e tecniche Metodologie Strumenti Descrizione dei principi

Dettagli

Processo parte III. Modello Code and fix. Modello a cascata. Modello a cascata (waterfall) Leggere Sez. 7.4 Ghezzi et al.

Processo parte III. Modello Code and fix. Modello a cascata. Modello a cascata (waterfall) Leggere Sez. 7.4 Ghezzi et al. Modello Code and fix Processo parte III Leggere Sez. 7.4 Ghezzi et al. Modello iniziale Iterazione di due passi scrittura del codice correzione degli errori Problemi: dopo una serie di cambiamenti, la

Dettagli

Poca documentazione: uso di Story Card e CRC (Class Responsibility Collabor) Collaborazione con il cliente rispetto alla negoziazione dei contratti

Poca documentazione: uso di Story Card e CRC (Class Responsibility Collabor) Collaborazione con il cliente rispetto alla negoziazione dei contratti Sviluppo Agile [Cockburn 2002] Extreme Programming (XP) [Beck 2000] Sono più importanti auto-organizzazione, collaborazione, comunicazione tra membri del team e adattabilità del prodotto rispetto ad ordine

Dettagli

Ingegneria del Software UML - Unified Modeling Language

Ingegneria del Software UML - Unified Modeling Language Ingegneria del Software UML - Unified Modeling Language Obiettivi. Presentare un approccio visuale alla progettazione. Illustrare i vantaggi dell utilizzo di diagrammi nella fase di progettazione. Rispondere

Dettagli

La disciplina che cura un approccio sistematico, disciplinato e quantificabile allo sviluppo, all operatività ed alla manutenzione del software

La disciplina che cura un approccio sistematico, disciplinato e quantificabile allo sviluppo, all operatività ed alla manutenzione del software Ingegneria del software (software engineering) La branca dell'ingegneria che si occupa della realizzazione di sistemi software. La disciplina che cura un approccio sistematico, disciplinato e quantificabile

Dettagli

Ingegneria del Software Requisiti e Specifiche

Ingegneria del Software Requisiti e Specifiche Ingegneria del Software Requisiti e Specifiche Obiettivi. Affrontare i primi passi della produzione del software: la definizione dei requisiti ed il progetto architetturale che porta alla definizione delle

Dettagli

Processi di Sviluppo Software Introduzione. Giuseppe Calavaro

Processi di Sviluppo Software Introduzione. Giuseppe Calavaro Processi di Sviluppo Software Introduzione Giuseppe Calavaro Processi di sviluppo software - Agenda Differenza tra Programmazione e Progettazione SW I Processi di Sviluppo Software Waterfall Spirale RUP

Dettagli

Tecnopolis CSATA s.c.r.l. APQ in Materia di Ricerca Scientifica nella Regione Puglia

Tecnopolis CSATA s.c.r.l. APQ in Materia di Ricerca Scientifica nella Regione Puglia BANDO ACQUISIZIONI Prodotti Software ALLEGATO 6.3 Capitolato Tecnico Piattaforma per l Analisi e la Progettazione di alto livello del Software Allegato 6.3: capitolato tecnico Pag. 1 1 Ambiente di Analisi

Dettagli

Ingegneria del Software. Processi di Sviluppo

Ingegneria del Software. Processi di Sviluppo Ingegneria del Software Processi di Sviluppo Ingegneria del Software: Tecnologia Stratificata tools metodi processi Focus sulla qualità Ingegneria del Software: Tecnologia Stratificata (2) Qualità Elemento

Dettagli

Concetti di base di ingegneria del software

Concetti di base di ingegneria del software Concetti di base di ingegneria del software [Dalle dispense del corso «Ingegneria del software» del prof. A. Furfaro (UNICAL)] Principali qualità del software Correttezza Affidabilità Robustezza Efficienza

Dettagli

Ciclo di vita del software

Ciclo di vita del software Ciclo di vita del software Nel corso degli anni, nel passaggio dalla visione artigianale alla visione industriale del software, si è compreso che il processo andava formalizzato attraverso: un insieme

Dettagli

I lucidi messi a disposizione sul sito del corso di Analisi e progettazione del software NON sostituiscono il libro di testo

I lucidi messi a disposizione sul sito del corso di Analisi e progettazione del software NON sostituiscono il libro di testo Luca Cabibbo Analisi e Progettazione del Software Sviluppo iterativo, evolutivo e agile Capitolo 2 marzo 2015 Lo sviluppo iterativo dovrebbe essere utilizzato solo per i progetti che si desidera che vadano

Dettagli

Ciclo di vita del software

Ciclo di vita del software Ciclo di vita del software Da Wikipedia, l'enciclopedia libera. 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à

Dettagli

Verifica e Validazione del Simulatore

Verifica e Validazione del Simulatore Verifica e del Simulatore I 4 passi principali del processo simulativo Formulare ed analizzare il problema Sviluppare il Modello del Sistema Raccolta e/o Stima dati per caratterizzare l uso del Modello

Dettagli

INGEGNERIA DEL SOFTWARE. Prof. Paolo Salvaneschi

INGEGNERIA DEL SOFTWARE. Prof. Paolo Salvaneschi Università di Bergamo Facoltà di Ingegneria Corso di Laurea in Ingegneria Informatica INGEGNERIA DEL SOFTWARE Prof. Paolo Salvaneschi 1 Obiettivi Scopi del corso: - Fornire gli elementi di base della disciplina,

Dettagli

PIANIFICAZIONE E REALIZZAZIONE DI UN SISTEMA INFORMATIVO 147 6/001.0

PIANIFICAZIONE E REALIZZAZIONE DI UN SISTEMA INFORMATIVO 147 6/001.0 PIANIFICAZIONE E REALIZZAZIONE DI UN SISTEMA INFORMATIVO 147 6/001.0 PIANIFICAZIONE E REALIZZAZIONE DI UN SISTEMA INFORMATIVO ELEMENTI FONDAMENTALI PER LO SVILUPPO DI SISTEMI INFORMATIVI ELABORAZIONE DI

Dettagli

Considera tutti i requisiti funzionali (use cases) NON deve necessariamente modellare i requisiti non funzionali

Considera tutti i requisiti funzionali (use cases) NON deve necessariamente modellare i requisiti non funzionali Corso di Laurea Specialistica in Ingegneria Informatica Corso di Ingegneria del Software A. A. 2008 - Progettazione OO E. TINELLI Punto di Partenza Il modello di analisi E una rappresentazione minima del

Dettagli

Verifica e Validazione (V & V) Software e difetti. Processo di V & V. Test

Verifica e Validazione (V & V) Software e difetti. Processo di V & V. Test Software e difetti Il software con difetti è un grande problema I difetti nel software sono comuni Come sappiamo che il software ha qualche difetto? Conosciamo tramite qualcosa, che non è il codice, cosa

Dettagli

CONCETTI DI BASE PER LA QUALITA

CONCETTI DI BASE PER LA QUALITA CONCETTI DI BASE PER LA QUALITA Misura: è una funzione m: A -> B che associa ad ogni attributo A di un osservabile nel mondo reale o empirico (dominio) un oggetto formale B nel mondo matematico (range);

Dettagli

Introduzione all Ingegneria del Software

Introduzione all Ingegneria del Software Introduzione all Ingegneria del Software Alessandro Martinelli alessandro.martinelli@unipv.it 10 Dicembre 2013 Introduzione all Ingegneria del Software Ingegneria del Software Modelli di Sviluppo del Software

Dettagli

ANALISI E PROGETTAZIONE OBJECT ORIENTED. Lorenzo Saladini

ANALISI E PROGETTAZIONE OBJECT ORIENTED. Lorenzo Saladini ANALISI E PROGETTAZIONE OBJECT ORIENTED Lorenzo Saladini 1. Introduzione In questo capitolo vengono presentati alcuni degli elementi necessari al corretto sviluppo di sistemi informatici secondo una metodologia

Dettagli

Il ciclo di vita del software. La necessita` di un modello. La mancanza di un modello. La prima proposta di soluzione

Il ciclo di vita del software. La necessita` di un modello. La mancanza di un modello. La prima proposta di soluzione Il ciclo di vita del software Progettazione e implementazione è solo una fase, per quanto importante, della produzione industriale del software Altre fasi sono importanti. Ad esempio: h Analisi dei requisiti

Dettagli

TECNOLOGIE DELL INFORMAZIONE E DELLA COMUNICAZIONE PER LE AZIENDE

TECNOLOGIE DELL INFORMAZIONE E DELLA COMUNICAZIONE PER LE AZIENDE TECNOLOGIE DELL INFORMAZIONE E DELLA COMUNICAZIONE PER LE AZIENDE Materiale di supporto alla didattica Tecnologie dell informazione e della comunicazione per le aziende CAPITOLO 3: Progettazione e sviluppo

Dettagli

Corso di Progettazione di sistemi multimediali

Corso di Progettazione di sistemi multimediali Corso di Progettazione di sistemi multimediali prof. Pierluigi Feliciati a.a.2012/13 Modulo 0 Progettare, sistemi, multimedialità: Definizioni, strumenti, ciclo di vita dei progetti, figure professionali

Dettagli

Ingegneria dei Requisiti

Ingegneria dei Requisiti Corso di Laurea Specialistica in Ingegneria Informatica Corso di Ingegneria del Software A. A. 2008 - Ingegneria dei Requisiti E. TINELLI Contenuti I requisiti del software Documento dei requisiti I processi

Dettagli

Automazione della gestione degli ordini d acquisto di una società di autonoleggio

Automazione della gestione degli ordini d acquisto di una società di autonoleggio Automazione della gestione degli ordini d acquisto di una società di autonoleggio Professore Gaetanino Paolone Studenti Paolo Del Gizzi Maurizio Di Stefano 1 INDICE INTRODUZIONE.pag.3 IL PIANO METODOLOGICO

Dettagli

Lezione 1 Ingegneria del Software II- Introduzione e Motivazione. Ingegneria del Software 2 Introduzione e Richiami 1

Lezione 1 Ingegneria del Software II- Introduzione e Motivazione. Ingegneria del Software 2 Introduzione e Richiami 1 Lezione 1 Ingegneria del Software II- Introduzione e Motivazione Ingegneria del Software 2 Introduzione e Richiami 1 Riferimenti bibliografici I. Sommerville Ingegneria del Software 8a edizione Cap.1 R.

Dettagli

Ciclo di vita dimensionale

Ciclo di vita dimensionale aprile 2012 1 Il ciclo di vita dimensionale Business Dimensional Lifecycle, chiamato anche Kimball Lifecycle descrive il framework complessivo che lega le diverse attività dello sviluppo di un sistema

Dettagli

Cosa significa che il SW è non lineare? Piccoli cambiamenti nel codice portano a grandi cambiamenti di comportamento

Cosa significa che il SW è non lineare? Piccoli cambiamenti nel codice portano a grandi cambiamenti di comportamento Cosa significa che il SW è non lineare? Piccoli cambiamenti nel codice portano a grandi cambiamenti di comportamento Cosa s'intende per Information Hiding? Impedire l'accesso a dettagli implementativi

Dettagli

IL PROCESSO DI FABBRICAZIONE (sviluppo nuovo prodotto)

IL PROCESSO DI FABBRICAZIONE (sviluppo nuovo prodotto) CORSO DI Gestione aziendale Facoltà di Ingegneria IL PROCESSO DI FABBRICAZIONE (sviluppo nuovo prodotto) Carlo Noè Università Carlo Cattaneo Istituto di Tecnologie e-mail: cnoe@liuc.it 1 Il processo di

Dettagli

Modellazione di sistema

Modellazione di sistema Corso di Laurea Specialistica in Ingegneria Informatica Corso di Ingegneria del Software A. A. 2008 - Modellazione di sistema E. TINELLI Contenuti Approcci di analisi Linguaggi di specifica Modelli di

Dettagli

Insegnamento di Gestione e Organizzazione dei Progetti A.A. 2008/9

Insegnamento di Gestione e Organizzazione dei Progetti A.A. 2008/9 Insegnamento di Gestione e Organizzazione dei Progetti A.A. 2008/9 Lezione 15: P.M.: metodologie di progetto Prof.ssa R. Folgieri email: folgieri@dico.unimi.it folgieri@mtcube.com 1 Modelli di conduzione

Dettagli

Indice. Prefazione all edizione italiana

Indice. Prefazione all edizione italiana Indice Prefazione all edizione italiana XV Capitolo 1 Il software e l ingegneria del software 1 1.1 L evoluzione del ruolo del software 3 1.2 Il software 5 1.3 La natura mutevole del software 8 1.4 Il

Dettagli

Introduzione a UML. Iolanda Salinari

Introduzione a UML. Iolanda Salinari Introduzione a UML Iolanda Salinari Perché modelliamo Un modello è una semplificazione della realtà I modelli ci aiutano a visualizzare un sistema come è o come vorremmo che fosse ci permettono di specificare

Dettagli

5 Gestione dei progetti software. 5.1 Attività gestionale. Sistemi Informativi I Lezioni di Ingegneria del Software

5 Gestione dei progetti software. 5.1 Attività gestionale. Sistemi Informativi I Lezioni di Ingegneria del Software 5 Gestione dei progetti software. Dopo aver completato lo studio del ciclo di vita del software, in questa parte vengono discussi gli aspetti gestionali della produzione del software. Vengono esaminate

Dettagli

Il modello RAD 1. Rapid Application Development punta a un ciclo di sviluppo molto breve

Il modello RAD 1. Rapid Application Development punta a un ciclo di sviluppo molto breve Il modello RAD 1 Rapid Application Development punta a un ciclo di sviluppo molto breve adattamento del modello a cascata in cui l obiettivo di uno sviluppo rapido è raggiunto grazie a strategie costruttive

Dettagli

UniRoma2 - Ingegneria del Software 1 1

UniRoma2 - Ingegneria del Software 1 1 Object Oriented Analysis - OOA La fase di OOA definisce, secondo un approccio ad oggetti, COSA un prodotto software deve fare (mentre la fase di OOD definisce, sempre secondo un approccio ad oggetti, COME

Dettagli

11. Evoluzione del Software

11. Evoluzione del Software 11. Evoluzione del Software Andrea Polini Ingegneria del Software Corso di Laurea in Informatica (Ingegneria del Software) 11. Evoluzione del Software 1 / 21 Evoluzione del Software - generalità Cosa,

Dettagli

Introduzione. Il software e l ingegneria del software. Marina Mongiello Ingegneria del software 1

Introduzione. Il software e l ingegneria del software. Marina Mongiello Ingegneria del software 1 Introduzione Il software e l ingegneria del software Marina Mongiello Ingegneria del software 1 Sommario Il software L ingegneria del software Fasi del ciclo di vita del software Pianificazione di sistema

Dettagli

Quality gate. Sono eventi programmati regolarmente e condotti seguendo una procedura standard

Quality gate. Sono eventi programmati regolarmente e condotti seguendo una procedura standard Quality gate Nei punti chiave del processo di sviluppo del software, viene integrato un insieme di quality gate per monitorare la qualità del prodotto intermedio prima che quest ultimo possa passare al

Dettagli

Sistemi Informativi I Lezioni di Ingegneria del Software

Sistemi Informativi I Lezioni di Ingegneria del Software 4 Codifica, Test e Collaudo. Al termine della fase di progettazione, a volte anche in parallelo, si passa alla fase di codifica e successivamente alla fase di test e collaudo. In questa parte viene approfondita

Dettagli

Business white paper. Sette best practice per creare applicazioni che rispondano alle esigenze aziendali

Business white paper. Sette best practice per creare applicazioni che rispondano alle esigenze aziendali Business white paper Sette best practice per creare applicazioni che rispondano alle esigenze aziendali Indice 3 Sommario esecutivo 3 Introduzione 3 Best practice a livello aziendale 5 Best practice a

Dettagli

Introduzione. Capitolo 1

Introduzione. Capitolo 1 Capitolo 1 Introduzione Architecture is the set of design decisions that you wish you could get right early in a project, but that you are not necessarily more likely to get them right than any other.

Dettagli

Architettura SW Definizione e Notazioni

Architettura SW Definizione e Notazioni Corso di Laurea Specialistica in Ingegneria Informatica Corso di Ingegneria del Software A. A. 2008 - Stili Architetturali E. TINELLI Architettura SW Definizione e Notazioni Definizione ANSI/IEEE Std Std1471-2000

Dettagli

La progettazione del software nelle piccole o micro imprese

La progettazione del software nelle piccole o micro imprese La progettazione del software nelle piccole o micro imprese Il contenuto di questo documento è strettamente confidenziale, la visione dello stesso è consentita solo al personale di FadeOut Snc e della

Dettagli

1. L Ingegneria del Software

1. L Ingegneria del Software 1. L Ingegneria del Software Obiettivi della lezione: Definire cosa si intende per Ingegneria del Software Discutere i concetti di prodotto software e di processo software Spiegare il concetto di visibilità

Dettagli

WebRatio. L altra strada per il BPM. Web Models s.r.l. www.webratio.com contact@webratio.com 1 / 8

WebRatio. L altra strada per il BPM. Web Models s.r.l. www.webratio.com contact@webratio.com 1 / 8 WebRatio L altra strada per il BPM Web Models s.r.l. www.webratio.com contact@webratio.com 1 / 8 Il BPM Il BPM (Business Process Management) non è solo una tecnologia, ma più a grandi linee una disciplina

Dettagli

Agile. mercoledì, 1 luglio 2015, 3:05 p. Prof. Tramontano docente Federico II ingegneria del software. Sviluppo Agile: metaprocesso

Agile. mercoledì, 1 luglio 2015, 3:05 p. Prof. Tramontano docente Federico II ingegneria del software. Sviluppo Agile: metaprocesso Agile mercoledì, 1 luglio 2015, 3:05 p. Prof. Tramontano docente Federico II ingegneria del software Sviluppo Agile: metaprocesso Molti progetti software falliscono Sì parte dagli anni 2000 Millennium

Dettagli

Gestione Requisiti. Ingegneria dei Requisiti. Requisito. Tipi di Requisiti e Relativi Documenti. La gestione requisiti consiste in

Gestione Requisiti. Ingegneria dei Requisiti. Requisito. Tipi di Requisiti e Relativi Documenti. La gestione requisiti consiste in Ingegneria dei Requisiti Il processo che stabilisce i servizi che il cliente richiede I requisiti sono la descrizione dei servizi del sistema Funzionalità astratte che il sistema deve fornire Le proprietà

Dettagli

Modelli di Processo. www.vincenzocalabro.it

Modelli di Processo. www.vincenzocalabro.it Modelli di Processo Il Modello del Processo Il modello del processo stabilisce i principi di base su cui si fonda lo sviluppo del software (e a cui è dovuto il successo o l insuccesso) Non esiste un unico

Dettagli

all ingegneria del software

all ingegneria del software Luca Cabibbo Ingegneria del Software Introduzione all ingegneria del software Dispensa IDS 1 ottobre 2008 1 -Fonti [Sommerville/8e] Capitolo 1, Introduzione [Pressman/6e] Capitolo 1, Il software e l ingegneria

Dettagli

Architetture Applicative

Architetture Applicative Alessandro Martinelli alessandro.martinelli@unipv.it 6 Marzo 2012 Architetture Architetture Applicative Introduzione Alcuni esempi di Architetture Applicative Architetture con più Applicazioni Architetture

Dettagli

Piano di gestione della qualità

Piano di gestione della qualità Piano di gestione della qualità Pianificazione della qualità Politica ed obiettivi della qualità Riferimento ad un eventuale modello di qualità adottato Controllo della qualità Procedure di controllo.

Dettagli

Processi per lo sviluppo rapido del software

Processi per lo sviluppo rapido del software Lezione 3 Processi per lo sviluppo rapido del software Sviluppo Rapido del Software Slide 1 Riferimenti bibliografici I. Sommerville Ingegneria del Software 8a edizione Cap.17 R. Pressman- Principi di

Dettagli

Progetto software 2008/2009. Docente Marianna Nicolosi Asmundo

Progetto software 2008/2009. Docente Marianna Nicolosi Asmundo Progetto software 2008/2009 Docente Marianna Nicolosi Asmundo Obiettivi del corso Coinvolgervi nello sviluppo di un progetto software in cui mettere a frutto le conoscenze che avete acquisito durante i

Dettagli

Lezione 5: Progettazione di Software e Database. Ingegneria del Software. Il Software 19/11/2011. Dr. Luca Abeti

Lezione 5: Progettazione di Software e Database. Ingegneria del Software. Il Software 19/11/2011. Dr. Luca Abeti Lezione 5: Progettazione di Software e Database Dr. Luca Abeti Ingegneria del Software L ingegneria del software è la disciplina che studia i metodi e gli strumenti per lo sviluppo del software e la misura

Dettagli

Software. Definizione, tipologie, progettazione

Software. Definizione, tipologie, progettazione Software Definizione, tipologie, progettazione Definizione di software Dopo l hardware analizziamo l altra componente fondamentale di un sistema di elaborazione. La macchina come insieme di componenti

Dettagli

SOA GOVERNANCE: WHAT DOES IT MEAN? Giorgio Marras

SOA GOVERNANCE: WHAT DOES IT MEAN? Giorgio Marras SOA GOVERNANCE: WHAT DOES IT MEAN? Giorgio Marras 2 Introduzione Le architetture basate sui servizi (SOA) stanno rapidamente diventando lo standard de facto per lo sviluppo delle applicazioni aziendali.

Dettagli

I Modelli della Ricerca Operativa

I Modelli della Ricerca Operativa Capitolo 1 I Modelli della Ricerca Operativa 1.1 L approccio modellistico Il termine modello è di solito usato per indicare una costruzione artificiale realizzata per evidenziare proprietà specifiche di

Dettagli

Realizzazione di un prototipo di un software web based per la gestione di un inventario comunale

Realizzazione di un prototipo di un software web based per la gestione di un inventario comunale tesi di laurea inventario comunale Anno Accademico 2009/2010 relatore Ch.mo prof. Porfirio Tramontana correlatore Ch.mo Ing. Luigi Pontillo candidato Michele Vitelli Matr. 534 2170 Redazione dell Inventario

Dettagli

12. Evoluzione del Software

12. Evoluzione del Software 12. Evoluzione del Software Andrea Polini Ingegneria del Software Corso di Laurea in Informatica (Ingegneria del Software) 12. Evoluzione del Software 1 / 21 Evoluzione del Software - generalità Cosa,

Dettagli

Paradigma object-oriented

Paradigma object-oriented Paradigma object-oriented Dati & Comportamento Implementazione trasparente dei servizi Facile mantenimento Omogeneità nella gerarchia dati-funzioni Procedural approach OO approach Data hierarchy Replaced

Dettagli

Prof. Pagani Corrado INGEGNERIA DEL SOFTWARE

Prof. Pagani Corrado INGEGNERIA DEL SOFTWARE Prof. Pagani Corrado INGEGNERIA DEL SOFTWARE INTRODUZIONE L ingegneria del software è la disciplina tecnologica e gestionalerelativa alla realizzazione sistematica e alla manutenzione di un software rispettando

Dettagli

Scope Management. IT Project Management. Lezione 3 Scope Management. Monitoring del progetto (Earned Value) Creazione diagrammi Pert/CPM/Gantt

Scope Management. IT Project Management. Lezione 3 Scope Management. Monitoring del progetto (Earned Value) Creazione diagrammi Pert/CPM/Gantt IT Project Management Lezione 3 Scope Management Federica Spiga A.A. 2009-2010 1 Check list del PM Identificare i requisiti del cliente Monitoring del progetto (Earned Value) Identificare i deliverable

Dettagli

Introduzione ad UML. Perché modelliamo

Introduzione ad UML. Perché modelliamo Introduzione ad UML Pag. 1 Perché modelliamo Un modello è una semplificazione della realtà I modelli ci aiutano a visualizzare un sistema come è o come vorremmo che fosse ci permettono di specificare la

Dettagli

Pattern Architetturali e Analisi Architetturale

Pattern Architetturali e Analisi Architetturale Pattern Architetturali e Analisi Architetturale Ingegneria del Software parte II Andrea Bei Pattern Architetturali Pattern Architetturale Descrive il modello organizzativo strutturale di un sistema software

Dettagli

Ingegneria del Software - Il Ciclo Lungo

Ingegneria del Software - Il Ciclo Lungo Ingegneria del Software - Il Ciclo Lungo Alessandro Martinelli alessandro.martinelli@unipv.it 10 Marzo 2014 Il Ciclo Lungo Il Versioning e la Condivisione di Codice Organizzazione dei Pacchetti La Modellazione

Dettagli

SCD IS. Processi software. Processi Software. UniPD - 2009 - Ingegneria del Software mod. A 1. Definizioni. Modelli di ciclo di vita

SCD IS. Processi software. Processi Software. UniPD - 2009 - Ingegneria del Software mod. A 1. Definizioni. Modelli di ciclo di vita Processi software Anno accademico 2009/10 Ingegneria del mod. A Tullio Vardanega, tullio.vardanega@math.unipd.it SCD IS Definizioni Ciclo di vita Copre l evoluzione di un prodotto dal concepimento al ritiro

Dettagli

Il linguaggio per la moderna progettazione dei processi aziendali

Il linguaggio per la moderna progettazione dei processi aziendali Il linguaggio per la moderna progettazione dei processi aziendali Organizzare un azienda sotto il profilo dei processi è oramai diventata una disciplina a cavallo tra la competenza aziendalistica ed informatica.

Dettagli

Laboratorio di Progettazione di Sistemi Software Introduzione

Laboratorio di Progettazione di Sistemi Software Introduzione Laboratorio di Progettazione di Sistemi Software Introduzione Valentina Presutti (A-L) Riccardo Solmi (M-Z) Indice degli argomenti Introduzione all Ingegneria del Software UML Design Patterns Refactoring

Dettagli

Metriche del software

Metriche del software Sviluppo di Software Applicativo Metriche del software Come misurare le diverse caratteristiche del software: dimensioni, qualità, impegno richiesto per lo sviluppo, ecc. Ercole Colonese IBM Global Services

Dettagli

Reti e sistemi informativi II Il ruolo delle IT nell organizzazione

Reti e sistemi informativi II Il ruolo delle IT nell organizzazione Reti e sistemi informativi II Il ruolo delle IT nell organizzazione Prof. Andrea Borghesan & Dr.ssa Francesca Colgato venus.unive.it/borg borg@unive.it Ricevimento: mercoledì dalle 10.00 alle 11.00 Modalità

Dettagli

7. Architetture Software

7. Architetture Software 7. Architetture Software progettare la struttura Andrea Polini Ingegneria del Software Corso di Laurea in Informatica (Ingegneria del Software) 7. Architetture Software 1 / 20 Scopo della fase di design

Dettagli

SISTEMI INFORMATIVI AZIENDALI

SISTEMI INFORMATIVI AZIENDALI SISTEMI INFORMATIVI AZIENDALI Prof. Andrea Borghesan venus.unive.it/borg borg@unive.it Ricevimento: Alla fine di ogni lezione Modalità esame: scritto 1 Sistema informativo. Prima definizione Un sistema

Dettagli

Novità di Visual Studio 2008

Novità di Visual Studio 2008 Guida al prodotto Novità di Visual Studio 2008 Introduzione al sistema di sviluppo di Visual Studio Visual Studio Team System 2008 Visual Studio Team System 2008 Team Foundation Server Visual Studio Team

Dettagli

Strumenti di modellazione. Gabriella Trucco

Strumenti di modellazione. Gabriella Trucco Strumenti di modellazione Gabriella Trucco Linguaggio di modellazione Linguaggio formale che può essere utilizzato per descrivere (modellare) un sistema Il concetto trova applicazione soprattutto nell

Dettagli

Progettazione orientata agli oggetti Introduzione a UML

Progettazione orientata agli oggetti Introduzione a UML Progettazione orientata agli oggetti Introduzione a UML Claudia Raibulet raibulet@disco.unimib.it Il processo di sviluppo software Rappresenta un insieme di attività per la specifica, progettazione, implementazione,

Dettagli

ALLEGATO 8.1 DESCRIZIONE PROFILI PROFESSIONALI

ALLEGATO 8.1 DESCRIZIONE PROFILI PROFESSIONALI PROCEDURA DI SELEZIONE PER L AFFIDAMENTO DEL SERVIZIO DI PROGETTAZIONE, ANALISI, SVILUPPO, MANUTENZIONE ADEGUATIVA, CORRETTIVA ED EVOLUTIVA DI SISTEMI INFORMATIVI SU PIATTAFORMA IBM WEBSPHERE BPM (EX LOMBARDI)

Dettagli

Basi di Dati. Introduzione ai sistemi di basi di dati. K.Donno - Introduzione ai sistemi di basi di dati

Basi di Dati. Introduzione ai sistemi di basi di dati. K.Donno - Introduzione ai sistemi di basi di dati Basi di Dati Introduzione ai sistemi di basi di dati Introduzione ai sistemi di basi di dati Gestione dei Dati Una prospettiva storica File system verso DBSM Vantaggi di un DBMS Modelli dei dati Utenti

Dettagli

Introduzione ai sistemi di basi di dati

Introduzione ai sistemi di basi di dati Basi di Dati Introduzione ai sistemi di basi di dati Alessandro.bardine@gmail.com alessandro.bardine@iet.unipi.it Introduzione ai sistemi di basi di dati Gestione dei Dati Una prospettiva storica File

Dettagli

Project Planning. Politecnico di Milano. Progetto di Ingegneria del Software 2. 15 novembre 2011. Elisabetta Di Nitto Raffaela Mirandola

Project Planning. Politecnico di Milano. Progetto di Ingegneria del Software 2. 15 novembre 2011. Elisabetta Di Nitto Raffaela Mirandola Politecnico di Milano Progetto di Ingegneria del Software 2 Project Planning Autori: Claudia Foglieni Giovanni Matteo Fumarola Massimo Maggi Professori: Elisabetta Di Nitto Raffaela Mirandola 15 novembre

Dettagli

Il Processo Software

Il Processo Software Il Processo Software 29-03-2012 Prodotto Software Prodotto di qualità Tempi e costi determinati Processo Software Attività portanti Famiglia di compiti Attività ausiliari Quadro di riferimento Processo

Dettagli

ALLEGATO 1.4 CICLI DI VITA DEL SOFTWARE

ALLEGATO 1.4 CICLI DI VITA DEL SOFTWARE ALLEGATO 1.4 CICLI DI VITA DEL SOFTWARE Allegato 1.4 Cicli di vita del software Pagina 1 di 16 Indice 1 CICLI DI VITA... 3 1.1 Ciclo di Sviluppo... 3 1.2 Ciclo di Manutenzione... 5 2 LE FASI PROGETTUALI...

Dettagli

CORSO I.F.T.S. "TECNICHE PER LA PROGETTAZIONE E LA GESTIONE DI DATABASE. Matricola 2014LA0033 DISPENSE DIDATTICHE MODULO DI PROGETTAZIONE SOFTWARE

CORSO I.F.T.S. TECNICHE PER LA PROGETTAZIONE E LA GESTIONE DI DATABASE. Matricola 2014LA0033 DISPENSE DIDATTICHE MODULO DI PROGETTAZIONE SOFTWARE CORSO I.F.T.S. "TECNICHE PER LA PROGETTAZIONE E LA GESTIONE DI DATABASE Matricola 2014LA0033 DISPENSE DIDATTICHE MODULO DI PROGETTAZIONE SOFTWARE Dott. Imad Zaza Lezione del 08/07/2014 Page 1 Elementi

Dettagli

Noi siamo quello che facciamo ripetutamente. Perciò l'eccellenza non è un'azione, ma un'abitudine. Aristotele. Qualità del Software

Noi siamo quello che facciamo ripetutamente. Perciò l'eccellenza non è un'azione, ma un'abitudine. Aristotele. Qualità del Software Noi siamo quello che facciamo ripetutamente. Perciò l'eccellenza non è un'azione, ma un'abitudine. Aristotele Qualità del Software Quality Assurance per tutte le esigenze Web Site Testing Mobile Application

Dettagli

Architettura del software: dai Casi d Uso al Modello

Architettura del software: dai Casi d Uso al Modello Architettura del software: dai Casi d Uso al Modello Lorenzo Barbieri Sono un Senior Trainer/Consultant in ObjectWay SpA (www.objectway.it), specializzato in architetture Microsoft.NET, Windows, SQL Server,

Dettagli

Lo Studio di Fattibilità

Lo Studio di Fattibilità Lo Studio di Fattibilità Massimo Mecella Dipartimento di Informatica e Sistemistica Università di Roma La Sapienza Definizione Insieme di informazioni considerate necessarie alla decisione sull investimento

Dettagli