Torna alla pagina di Ingegneria del software
:: Ingegneria del software - Appunti del 3 Marzo ::
Il modello iterativo
Se sto producendo un software e voglio dare la possibilità al committente di vedere e commentare ciò che sto facendo, non posso fare altro che iterare alcune fasi del modello waterfall. In questo modo avremo infatti l'occasione di raccogliere l'approvazione o la bocciatura degli ultimi progressi del prodotto da parte dell'utente, ma anche critiche suggerimenti e variazioni dei requisiti, e tenerne conto alla prossima iterazione.
Il prototipo è il prodotto di ogni passaggio iterativo e non è altro che il modello approssimato dell'applicazione che si sta sviluppando, seppur con funzionalità parziali. Nel capitolo sul waterfall della lezione del 2 Marzo abbiamo anticipato due tecniche di gestione dei prototipi durante l'iterazione: la prima era la throw away che ne prevedeva la riscrittura da zero ad ogni passaggio, la seconda era la onion skin che invece ottimizzava e ampliava il lavoro parziale.
Contrariamente a quanto detto sulle slide, le iterazioni non hanno sempre la stessa durata, ma c'è una certa accelerazione man mano che ci avviciniamo alla fine del processo produttivo dato che i requisiti da verificare sono sempre meno.
Il RUP (Rational Unified Process) è un particolare tipo di modello iterativo, non orientato al ciclo di vita. Se ad esempio lo adottassimo per sviluppare un word processor, potremmo fare nello stesso momento sia la progettazione delle nuove caratteristiche che l'implementazione di quelle già consolidate (i.e. la gestione dei file, magari riciclata da un altro progetto).
Fissiamo bene i concetti.
Se un'azienda usa il waterfall ogni fase le prenderà il 100% del tempo e delle energie, ne consegue una rigidità nell'acquisizione delle nuove caratteristiche.
Se un'azienda usa il modello iterativo seguirà più mini waterfall da iterare, e ad ogni iterazione avrà la possibilità di considerare nuove caratteristiche e funzionalità.
Se un'azienda usa il RUP e mi dice che è in fase di construction, significa che sta facendo per l'80% codifica e per il 20% pianificazione; se invece mi dice che è in fase di elaboration, significa che sta facendo per l'80% pianificazione e 20% codifica. In altre parole, vengono sempre portate avanti parallelamente diverse fasi del processo produttivo, così da spezzare la rigidità tipica del waterfall.
Le caratteristiche del ciclo di vita iterativo sono la pianificazione preventiva, la possibilità di gestire variazione dei requisiti in corso d'opera (così da far valutare i vari prototipi al committente), il coinvolgimento degli utenti e - soprattutto - la gestione del rischio. Il rischio è lo spazio di eventi non desiderati e sfavorevoli, valutato come il prodotto tra la probabilità che tali eventi si verifichino e l'impatto (soprattutto economico) che comporterebbero. Si tratta quindi di una grandezza numerabile, misurata in euro. Si parla di spazio di eventi perché è qualcosa di più di un semplice insieme, dato che ad ogni elemento è associato un valore di probabilità; ai nostri fini però li possiamo chiamare in entrambi i modi.
Con l'introduzione del concetto di rischio sarà possibile effettuare l'iteration planning basandola sulla risk analysis, facendo cioè in modo che tenga conto di interrogativi come: cosa succederebbe se una certa funzione del software non funzionasse? quale sarebbe l'impatto del suo fallimento? qual è la probabilità che fallisca lei piuttosto che un'altra?
In questo modo potremo fissare delle priorità su quali funzionalità portare avanti per prime e quali per ultime. Notare che in questo modo non avranno più importanza fattori come la complessità, ma altri come l'importanza che riveste quella funzione per il committente (magari a lui preme di più avere lo sfondo blu piuttosto che la facilità di utilizzo) o la capacità e l'esperienza dei programmatori che ho a disposizione.
Una volta prioritizzate le funzionalità potrei scegliere di affrontare per prime quelle con rischio più alto trascurando tutto il resto, ma è infinitamente più saggio - e spesso necessario - tenere conto di più fattori di scenario, volontà del committente comprese.
Ricapitolando, con il modello iterativo ho un'aggressione del rischio diluita nel tempo perché riesco a ridurlo progressivamente ad ogni iterazione grazie al feedback del cliente. Si dice che la riduzione avviene "a scalini" perché ogni passaggio iterativo elimina il fattore di rischio legato a una certa funzionalità del software. Con il metodo waterfall invece il rischio si abbatte in modo drastico solo alla fine, perché è solo in quel momento che il prototipo viene mostrato al committente: ci si gioca il tutto per tutto a prodotto finito.
Le attività del ciclo iterativo
Un processo software è suddiviso in varie attività dette task. Quelle del modello iterativo sono:
- pianificazione dell'iterazione (iteration planning). Ad esempio dico "in questa iterazione mi dedicherò a questa funzionalità, durerà tot settimane di cui almeno una di analisi e le altre di codifica e testing, e al suo termine avremo una milestone da valutare". La milestone è una verifica del work product della fase di codifica, e prevede il suo confronto con i requisiti stabiliti durante l'analisi. Può essere effettuata anche da un reviewer esterno, non necessariamente interno al team. In particolare se l'azienda è certificata ISO 9000 è obbligata a sottoporre i prodotti a un controllo di qualità da parte di gente qualificata. Infine, per quanto riguarda le durate di ogni fase, di solito si adotta la tecnica del
2-4-2
(2 settimane di analisi, 4 di codifica, 2 di testing), con relativi multipli e sottomultipli
- rilevazione dei requisiti
- progetto
- implementazione
- test
- rilascio (o demo)
In particolare le attività che vanno dalla 2 alla 5 sono quelle costitutive del mini waterfall.
Ingegneria dei requisiti
L'attività di raccolta dei requisiti non è sempre prevista o obbligatoria in tutti i processi software, tuttavia è molto importante conoscerla, presto sapremo perché.
L'ingegneria dei requisiti è il processo sistematico della messa a punto dei requisiti, ed è fondamentale per il successo dei progetti software. Chiedersi quali caratteristiche dovrà avere il software è infatti un punto chiave, ma anche critico dato che richiede abilità di comprensione e pianificazione che non devono necessariamente far parte el bagaglio di un programmatore. Storicamente questa attività era affidata agli analisti (generalmente laureati in economia e commercio), che sapevano come parlare la lingua dei clienti da un lato e quella dei tecnici dall'altro.
E' assodato che il 73% dei progetti software che falliscono è perché non rispondono alle aspettative dei committenti a causa di requisiti errati. Esistono diversi casi di studio, tra cui quello del servizio di prenotazione integrato CONFIRM (causa: non aver tenuto conto dell'avanzata del web) o quello di CorelOffice (causa: non era possibile stampare da stampanti locali, ma solo da quelle in rete).
Va inoltre considerato che meglio si mappano i requisiti e minore sarà l'impatto economico delle fasi successive, in particolar modo della manutenzione che è di gran lunga la più costosa.
Esistono linguaggi specifici per descrivere i requisiti, che hanno la caratteristica di non essere ambigui e di essere interpretabili dai calcolatori. Ad esempio la frase "una vecchia porta la sbarra" può significare sia che una anziana signora sta trasportando una sbarra, che una vecchia porta sta sbarrando il passaggio a qualuna. Questo è un caso detto di doppio parser, e non è accettabile per una macchina.
Su questi argomenti ci torneremo nel prossimo capitolo.
Andiamo sul pratico: devo raccogliere i requisiti, con chi devo parlare? Con gli stakeholder, ovvero con qualsiasi soggetto a cui interessa che il progetto software abbia buon esito; quindi non solo col cliente (colui che finanzia), ma anche con gli utilizzatori futuri. Se ad esempio sto sviluppando un software per un ospedale dovrò consultare anche medici e infermieri, poiché saranno loro che prima o poi dovranno utilizzarlo. Si considerano stakeholder anche i cosiddetti esperti di dominio, ovvero persone che conoscono bene il dominio applicativo del progetto e che possono fornire consigli e pareri sul programma anche se non ci avranno mai nulla a che fare.
Bene, ora che so a chi chiedere i requisiti, come gli parlerò? Da un punto di vista di forma dipende dal tipo di relazione esistente tra produttore e consumatore (vedi riepilogo alla fine di questo capitolo), mentre in generale dovrò fare una serie di domande utili al maggior numero possibile di stakeholder, raccogliendo le risposte e cercando e facendo notare ai clienti eventuali incongruenze.
Una volta eliminate le contraddizioni (requisiti che dicono l'opposto) mi resta un elenco più o meno corposo di requisiti scritti in linguaggio naturale, quindi soggetto ad ambiguità, cioè che può essere interpretato in due o più modi diversi. Nella prossima lezione vedremo come ovviare a questo problema.
I requisiti
I requisiti indicano cosa un prodotto software deve fare e non come deve implementarlo, anche se non è sempre facile scindere il cosa dal come.
Per capire a livello globale quali sono i requisiti è opportuno operare una classificazione:
- requisiti funzionali, che specificano una funzione che il sistema deve compiere. Qui mi aspetto di trovare più o meno tutti i comandi che compariranno nel menu del software
- requisiti non funzionali, che tengono conto di altre caratteristiche come ad esempio le prestazioni (magari in termini di tempo), affidabilità, efficienza, portabilità (su quale sistema operativo devono poter girare), ...
- requisiti inversi, che indicano cosa il software non deve fare, ad esempio non esaurire mai la memoria virtuale. In genere sono relativi a obiettivi di sicurezza, come il garantire la segretezza delle informazioni. Per questi requisiti i test sono molto più difficili da realizzare e documentare rispetto alle altre classi, quindi sono più critici
- requisiti tecnologici, che rientrano sempre tra quelli non funzionali, ma che sono talmente importanti che è utile metterli in rilievo. Un requisito tecnologico potrebbe essere quello di dover scrivere un software in Java piuttosto che in C++
Una volta che ho partizionato e classificato i requisiti, li prioritizzo secondo questa scala di priorità:
Must
: requisiti a massimo impatto, senza i quali il software è inaccettabile per il committente
Should
: se presenti aumentano il gradimento, se assenti il committente se ne lamenta
May
: se presenti aumentano il gradimento, se assenti non fa niente
Quando finisco di classificare e prioritizzare i requisiti li riscrivo in linguaggio semi-formale per eliminare le contraddizioni e li sottopongo al controllo degli stakeholder. Al termine della negoziazione con questi ultimi avrò il via libera per la fase di successiva di formalizzazione in linguaggi ancora più formali e controllati. Uno di questi è il control English, che elimina le ambiguità utilizzando la seguente sintassi per ogni requisito: soggetto + verbo + complemento
, in cui il soggetto è l'attore, il verbo è l'azione e il complemento è la risorsa su cui quest'ultima si compie. Ad esempio "l'utente stampa i file" è accettato perché la sintassi rispetta tutti i vincoli; invece "invia i file alla stampante quando l'utente clicca su stampa" non è accettato a causa delle evidenti inadempienze sintattiche. Nascono ambiguità anche quando si utilizzano i pronomi, ad esempio "il software confronta il file col template e lo salva su disco" non va bene perché deve essere specificato a quale complemento si riferisce il "lo". Quest'ultimo requisito per essere espresso in control English dovrà dunque essere diviso in due parti.
Dal control English si passa poi ad altri linguaggi ancora più formali (ad esempio i diagrammi), dopodiché andrà fatta l'importantissima analisi delle dipendenze che li collegherà a coppie per segnalare quale requisito dipende da chi. Una rappresentazione grafica di questa analisi si ha con il grafo delle dipendenze, che tratteremo nelle prossime lezioni.
Torna alla pagina di Ingegneria del software