Il formalismo dei casi d‘uso è senza dubbio uno standard de facto di analisi dei requisiti utente. In questa prima parte affrontiamo gli aspetti generali e approfonditi. Nel prossimo articolo analizzeremo un esempio concreto.
Introduzione
Obiettivo del presente articolo è analizzare i diversi modelli dei casi d‘uso previsti dai processi formali di sviluppo del software. Probabilmente molti lettori possiedono una certa familiarità con il formalismo dei casi d‘uso, ma forse non tutti sono consapevoli dell‘esistenza di diversi modelli dei casi d‘uso con diversi obiettivi, differente livello di astrazione, scope, e così via.
Studiando la letteratura in materia, ci si accorge anche che la terminologia utilizzata non è uniforme: ci proponiamo quindi di fare chiarezza sulla terminologia, proponendone una versione standard.
Il “lettore ideale” di questo articolo, dovrebbe avere almeno delle minime conoscenze del formalismo dei casi d‘uso e dei processi di sviluppo del software; ma vogliamo comunque presentare un breve riepilogo del formalismo e dei diversi modelli dei casi d‘uso, illustrando la fase in cui dovrebbero essere prodotti, gli obiettivi dell‘operazione, le figure professionali coinvolte nella produzione e i rischi progettuali introdotti da una mancata o errata produzione del modello.
Background
La maggior parte dei processi di sviluppo del software attualmente utilizzati nel mondo dell‘informatica, da quelli più formali via via a quelli più estremi, conferiscono particolare importanza all‘analisi dei requisiti utente: in effetti, i sistemi informatici dovrebbero essere realizzati per soddisfare specifiche esigenze dell‘utente. Pertanto è indispensabile chiarire, il prima possibile, la prospettiva del cliente, le sue necessità , le aspirazioni più o meno recondite, e, non u ciò di cui ha realmente bisogno l‘utente, e così via: tutto ciò che comunemente viene indicato con i termini di “specifiche utente”. Si tratta di un‘attività non sempre agevole per una serie di ben noti motivi: difficoltà di stabilire una piattaforma comune di intesa tra gli utenti ed il team di sviluppo, background e prospettive diverse, esigenze contrastanti, ecc. Quindi, focalizzare, fin dalle primissime fasi del ciclo di vita del software, l‘aderenza dei vari modelli alle richieste del cliente, continuando a monitorarle per tutto il processo di sviluppo, è un‘attività essenziale per il successo del progetto.
Gli ultimi decenni hanno visto lo sviluppo di metodologie e formalismi differenti per supportare il processo di “cattura” dei requisiti utenti. Attualmente, limitatamente all‘analisi dei requisiti funzionali, la quasi totalità della comunità informatica è unanime nel considerare il formalismo dei casi d‘uso come standard (de-facto) (NB in questo articolo i termini “casi d‘uso” e “use case” sono utilizzati come sinonimi). I processi di sviluppo del software che includono un approccio basato sul formalismo dei casi d‘uso (use case driven) sono probabilmente i più popolari nelle aziende di informatica. In ultima analisi, sono quelli utilizzati più o meno formalmente da sempre: si tratta di conferire la massima importanza ai requisiti funzionali di un sistema, e ciò da sempre ha costituito un criterio guida nello sviluppo del software.
Requisiti utente: funzionali e non funzionali
I requisiti utente, in prima analisi, possono essere suddivisi in due categorie: requisiti funzionali e requisiti non funzionali. I primi si occupano di descrivere, in modo chiaro e dettagliato, ciascun servizio che il sistema dovrà fornire, mentre i secondi, tipicamente, si riferiscono al sistema considerato nel suo complesso. In particolare, i requisiti funzionali dovrebbero stabilire, per ogni servizio, il comportamento del sistema quando tutto funziona correttamente (scenari principali, o di successo, e alternativi), così come situazioni di errore (scenari di eccezione), corredato dalla descrizione del comportamento richiesto al sistema. La definizione degli scenari principali permette di realizzare sistemi corretti (sistemi che effettivamente realizzano i servizi richiesti dall‘utente), mentre la definizione degli scenari di errore permette di realizzare sistemi robusti (sistemi in grado di intercettare situazioni anomale e di avviare, come risposta, prestabilite procedure [1].
I requisiti non funzionali, tipicamente, specificano caratteristiche del sistema considerato nel suo insieme. A questa categoria, appartengono requisiti come strategie di sicurezza, performance, disponibilità , procedure di backup e restore, e così via [1] e [2].
perché utilizzare il formalismo dei casi d‘uso?
La risposta è legata al fatto che il formalismo dei casi d‘uso:
- è uno strumento molto flessibile che si presta a essere utilizzato a diversi livelli di formalità , astrazione, etc.
- esistono molti tool e svariate metodologie che si basano sui casi d‘uso.
- permette di organizzare razionalmente l‘intera analisi dei requisiti in un insieme di piccoli documenti (use case) interrelati. Si evita quindi la produzione di un unico tomo, che, per forza di cose, tende a divenire arduo da consultare, impreciso, incompleto, difficile da organizzare e rivedere, e finisce per non supportare la gestione del progetto.
- fornisce ottime informazioni per la pianificazione e la gestione delle iterazioni su cui basare la produzione del sistema. La produzione del sistema dovrebbe avvenire attraverso una serie di iterazioni incrementali pianificate a priori e non per mezzo di un paio di consegne dipendenti dallo stato d‘ansia di manager e/o clienti. Ad esempio, la realizzazione del modello dei casi d‘uso permette di stabilire che una prima build deve implementare unicamente gli scenari principali dei casi d‘uso più rischiosi, che la seconda conterrà gli scenari degli altri casi d‘uso, che la terza includerà gli scenari di eccezione, e via discorrendo.
- semplifica la tracciabilità dei requisiti utente, non solo in termini di progettazione, ma anche in termini dei relativi costi.
- permette di derivare direttamente e meccanicamente i test case che permettono di verificare sia l‘esattezza, sia la robustezza del sistema.
- è abbastanza intuitivo e immediato da utilizzare sia per personale addetto allo sviluppo del sistema, sia per gli utenti che, solitamente, possiedono limitata conoscenza informatica.
Breve riepilogo del formalismo dei casi d‘uso
La prima versione del formalismo dei diagrammi dei casi d‘uso è frutto del lavoro svolto da Ivar Jacobson durante la sua collaborazione con la Ericsson nell‘ambito dello sviluppo di un sistema denominato AXE. Visto il successo riscosso dai diagrammi e percepitene le relative potenzialità , i Tres Amigos hanno pensato bene di inglobarli nello UML. I diagrammi dei casi d‘uso sono utilizzati per dettagliare le funzionalità del sistema, conferendo particolare rilievo alle entità esterne, denominate “attori”, che interagiscono con esso. In particolare, “un attore definisce un insieme coerente di ruoli che un ‘utente‘ di un caso d‘uso recita quando interagisce con esso”. Un attore non è necessariamente una persona: può essere un sistema automatizzato o un qualsiasi dispositivo fisico. L‘attore è l‘idealizzazione di una persona, di un processo, o di qualsiasi cosa interagisca con il sistema inviando e/o ricevendo messaggi e/o scambiando informazioni. A meno di stereotipi, gli attori sono rappresentati graficamente per mezzo di omini stilizzati (fig. 1)
Per ciò che concerne le relazioni, un attore può essere connesso ai casi d‘uso con i quali interagisce esclusivamente per mezzo di una relazione di associazione. Un attore può prendere parte a relazioni di generalizzazione in cui una descrizione astratta di un attore più essere condivisa e specializzata da una descrizione più specifica.
Le singole funzionalità (servizi) sono rappresentate graficamente attraverso elementi ellittici denominati “use case”. Da notare che sia i modelli, sia i diagrammi, sia la vista, sia la descrizione del comportamento sono indicati con i termini “casi d‘uso”… Grande aiuto per neutralizzare la confusione, no?
La notazione grafica dello UML prevede di rappresentare i casi d‘uso attraverso ellissi con il nome specificato all‘interno. Un‘alternativa consiste nel riportare il nome al di sotto dell‘ellisse. I casi d‘uso possono essere connessi sia ad altri casi d‘uso, sia, come riportato in precedenza, agli attori attraverso opportune relazioni di associazione.
Nel disegnare i diagrammi dei casi d‘uso si verifica spesso che diversi use case presentino delle somiglianze e condividano del comportamento (analogamente a quanto illustrato per gli attori). In questi casi gli insegnamenti dell‘OO prescrivono di raggruppare il comportamento comune in un apposito use case genitore (eventualmente astratto) e di estenderlo per mezzo di altri casi d‘uso figli che lo specializzino per gli usi originariamente individuati. La proprietà a cui si fa riferimento è ovviamente l‘eredità e la relazione dello UML è la generalizzazione.
L‘inclusione è una relazione tra uno use case base e uno incluso che specifica come il comportamento dell‘incluso possa essere inserito in quello dello use case base, il quale può avere visione dell‘incluso e, tipicamente, dipende dagli effetti generati dal‘incluso durante la sua esecuzione. Il concetto di inclusione è, per molti versi, analogo a quello di invocazione di funzione: viene eseguita la sequenza di azioni dello use case base; quando viene raggiunto un punto di inclusione, il controllo viene passato al caso d‘uso ivi indicato (incluso) e ne viene eseguita completamente la sequenza delle azioni; quindi il controllo ritorna allo use case base.
Una relazione di estensione (Extend) è una relazione tra un caso d‘uso estendente e uno base che specifica come il comportamento definito dal primo (l‘estendente) debba essere inserito nel comportamento di quello base. Pertanto si ha un comportamento speculare rispetto alla relazione di inclusione. Un‘altra peculiarità di questa relazione consiste nel fatto che l‘effettiva estensione avviene sotto il controllo di una condizione di guardia.
Figura 1 – Esempio di diagramma dei casi d‘uso relativo al servizio di noleggio CD
In fig. 1 è presentato un esempio di diagramma dei casi d‘uso: sebbene la notazione dei casi d‘uso possa sembrare addirittura banale, il suo corretto utilizzo richiede un adeguato studio teorico e una sperimentazione pratica. Un utilizzo non supportato da esperienza tende a produrre una serie di anomalie ben note: use case troppo dettagliati che cercano di disegnare il sistema, use case troppo astratti che non forniscono alcun chiarimento circa i requisiti dell‘utente, decomposizioni funzionali, etc.
La notazione dei casi d‘uso (i diagrammi) non permette di definire il comportamento dinamico. Queste ellissi, troppo “vuote”, in effetti, sono eccessivamente “leggere” per specificare le funzionalità che il sistema doveva prevedere: il solo nome non aiuta granché. Pertanto, ad ogni caso d‘uso deve essere associata una descrizione del comportamento dinamico. In pratica si utilizzano dei template con una struttura ben definita. Questi permettono di definire il nome del caso d‘uso, il codice, una breve descrizione, la priorità assegnata dall‘utente, gli attori, la definizione delle garanzie di successo e di fallimento, l‘evento che ne determina l‘avvio, gli scenari principali, quelli alternativi e quelli di errore, etc (Figura 2).
Figura 2 – Esempio di template utilizzato per descrivere il comportamento dinamico dei casi d‘uso. Ciascuna ellisse (caso d‘uso) deve essere corredata dalla descrizione del relativo comportamento dinamico e quindi da un template simile a quello di figura. (Per maggiori informazioni cfr. [2]). Successivamente presentiamo un esempio di utilizzo di questo template.
I diversi modelli dei casi d‘uso.
Dopo aver rispolverato la notazione dei casi d‘uso (per uno studio completo, si vedano i libri nei riferimenti), è giunto il momento di approfondire la discussione concernente i diversi modelli.
Diciamo innanzitutto che lo studio dei requisiti utente va affrontato da due diverse prospettive
- i servizi che il sistema dovrà erogare (utilizzando il formalismo dei casi d‘uso);
- i dati che permettono l‘espletamento di tali servizi (usando i diagrammi di struttura statica, ossia i diagrammi delle classi).
Nel contesto dell‘analisi dei requisiti, i diagrammi delle classi sono utilizzati essenzialmente per realizzare modelli a “oggetti” (in cui però sono presenti solo classi) focalizzati sulle uniche entità presenti, o derivanti, dall‘area business oggetto di studio.
Tornando ai casi d‘uso, i diversi modelli dei casi d‘uso individuati sono tre
- modello di business
- modello di dominio
- modello di sistema (che può essere considerato come un‘evoluzione del secondo)
I diversi autori individuano un diverso numero di modelli spesso con caratteristiche differenti e quindi anche indicati con nomi diversi. Riteniamo che la classificazione proposta da questo articolo possa essere razionale e condivisibile. Le differenze principali dei tre modelli sono:
- l‘area oggetto di studio (ossia i confini, boundaries)
- i processi considerati
- il livello di dettaglio
Per quanto concerne l‘area oggetto di studio, i modelli business sono focalizzati sull‘intera area business (da cui il nome) e non esclusivamente sulla parte (il dominio) che il sistema dovrà automatizzare (in altre parole, i primi sono focalizzati sul sistema informativo, mentre i secondi solo su quello informatico). Per esempio, nel contesto dello sviluppo di un‘applicazione per l‘acquisto di biglietti aerei via internet, il modello di business annovera tutti i processi, anche quelli manuali, che hanno luogo nell‘intero area business. Alcuni esempi di business model sono:
- la negoziazione che avviene direttamente con i vettori aerei per ottenere un certo pacchetto di biglietti a prezzi scontatissimi;
- il servizio relativo alla risoluzione in estremo di errori commessi dagli utenti del sito nell‘effettuare una prenotazione (per esempio, questo servizio si rende necessario qualora un utente si accorga, all‘ultimo momento, di aver commesso un errore nell‘acquisto di un biglietto e quindi effettua una chiamata per cercare di correre ai ripari).
Un modello del dominio di questo contesto, invece, considera solo i processi automatici che hanno luogo nel sistema di prenotazione, come per esempio il reperimento di un determinato volo aereo, la verifica della relativa disponibilità , la prenotazione, etc. Pertanto, l‘intera area business è ripartita in una serie di domini dai quali sono omessi i processi manuali.
Chiaramente, non sempre è necessario e/o possibile automatizzare tutte le diverse aree di dominio; o almeno non lo è da subito. L‘ideale sarebbe dar luogo a una perfetta ripartizione ove i diversi domini non prevedono intersezioni, anche se ciò non significa che, una volta realizzati i vari sotto-sistemi, questi non interagiscano tra loro. Tipicamente vi è una corrispondenza biunivoca tra un singolo sistema o sottosistema e uno specifico dominio, il che significa semplicemente che ogni specifico servizio è allocato in un solo dominio e quindi implementato da un unico sistema, per ridurre la ridondanza al minimo (eliminare completamente la ridondanza è realisticamente impossibile).
Questo scenario, purtroppo, è poco frequente, soprattutto in sistemi di grandi dimensioni e alla presenza di legacy system o di sistemi forniti da terze parti. La situazione più comune, purtroppo, prevede che specifici servizi siano replicati all‘interno di diversi sottosistemi (figura 3). Un problema serio si verifica quando specifici servizi sono realizzati in modo diverso in diverse parti del sistema: per esempio alcuni sottosistemi applicano algoritmi dissimili per il calcolo del rischio e quindi producono risultati non uniformi.
Figura 3 – Ripartizione concettuale di un modello di business in diversi domini. Per esempio, in un sistema bancario dell‘area finance, i diversi domini potrebbero corrispondere alle aree front-office, calcolo e gestione dei rischi, gestioni conto correnti, etc. Come si può notare, nella realtà , diversi domini prevedono intersezioni, ossia servizi replicati.
La relazione che lega i casi d‘uso business a quelli di dominio è di tipo molti-a-molti. Alcuni casi d‘uso business non generano casi d‘uso di dominio, magari perché manuali o perché si decide di non automatizzarli (caso precedente dei servizi di contrattazione prezzi biglietti, di risoluzioni di problemi utente, etc.); altri, invece, danno luogo a diversi casi d‘uso di dominio, magari perché il relativo espletamento richiede il coinvolgimento di servizi appartenenti a diversi domini; per esempio il singolo caso d‘uso a livello di business di prenotazione di un biglietto aereo dà luogo ai due casi d‘uso: prenotazione e aggiornamento del sistema legacy.
Un‘altra differenza tra i modelli business e quelli di dominio è relativa al diverso livello di astrazione. In particolare, è legittimo attendersi che i modelli di dominio presentano una maggiore aderenza ai dettagli. Aumentare il livello di dettaglio non significa assolutamente che il caso d‘uso specifichi il modo in cui realizzare un servizio: è anzi un‘anomalia assolutamente da evitare. Questo, quindi, è un aspetto importante: i requisiti utente, e quindi i casi d‘uso, devono specificare cosa il sistema dovrà realizzare, astenendosi dal come. Ciò è sbagliato per una serie di motivi: perché si vincola prematuramente il sistema a specifiche soluzioni, in una fase in cui non sia hanno ancora sufficienti informazioni circa tutti i requisiti del sistema, le scelte architetturali, e così via. Nel caso, per qualche motivo, si decida di cambiare soluzione, o strategia, o tecnologia (magari per una reingegnerizzazione) è necessario modificare di conseguenza i casi d‘uso.
Come accennato in precedenza, il modello di dominio prevede la specializzazione nel modello di sistema che si ottiene includendo feedback di carattere architetturale. Il modello di dominio e quello di sistema non sono due modelli completamente distinti, bensì rappresentano una logica evoluzione: man mano che i casi d‘uso includono dettagli architetturali, passano dalla versione iniziale del dominio a quella finale di sistema. In termini pratici è possibile pensare alla versione di sistema come all‘ultima base-line dell‘iniziale versione del dominio.
A questo punto qualche lettore potrebbe sentirsi smarrito… Ma come? Si sono versati fiumi di inchiostro per spiegare perché i formalismi di analisi dei requisiti, e quindi a maggior ragione i casi d‘uso, devono specificare cosa vuole l‘utente e non come realizzarlo, e ora abbiamo introdotto casi d‘uso di sistema con dettagli archietturali? Ebbene sì. Analizzando bene la situazione, non ci sono contraddizioni: organizzare i casi d‘uso in base all‘organizzazione architetturale non significa realizzare casi d‘uso che descrivono soluzioni. Semplicemente, l‘integrazione di dettagli architetturali nella fase più avanzata permette di fornire requisiti più rispondenti alla realtà e in più fornisce importanti suggerimenti in merito alla fruizione di alcuni sevizi (non a caso i processi attuali includono approcci centrati sull‘architettura, architecture centric). Per esempio, stabilire l‘architettura di riferimento, può rendere possibile asserire che un determinato servizio X attraverso una sequenza di attività Y diviene più facilmente fruibile, oppure che l‘implementazione presenterebbe tempi e quindi costi ridotti o migliori performance, o, ancora, che il servizio Z necessita di una specifica politica di sicurezza, etc. I casi d‘uso adottano ancora un linguaggio vicino all‘utente, ma, al tempo stesso, prevedono sia informazioni architetturali di alto livello, sia suggerimenti utili per un migliore sviluppo del sistema.
Quantunque possa sembrare bizzarro, l‘esperienza insegna che il vero problema non è realizzare la versione di sistema dei casi d‘uso di dominio, ma, viceversa, disporre di requisiti utente epurati da dettagli tecnici. Nel mondo del lavoro accade rarissimamente di realizzare sistemi completamente dal nulla. La stragrande maggioranza dei casi sono relativi a progetti di integrazione di sistemi o di reingegnerizzazione di applicazioni esistenti. Pertanto, gli utenti sono, più o meno, consapevoli dell‘architettura e utilizzano un gergo tecnico informatico (magari non sempre con cognizione di causa). Per esempio, può capitare di intervistare utenti di sistemi bancari che si esprimono in termini di “pubblicare un messaggio al sistema di matching o dal sistema di front office a quello di back office”, oppure “acquisire i valori di tolleranza dalla tabella dei default del database”, “notifica l‘anomalia al sistema di gestione delle eccezioni”, “monitorare il file di log”, e così via. Se gli utenti hanno una visione abbastanza corretta dell‘architettura (non delle soluzioni implementative) perché non sfruttarla? Magari aiutandoli a non fare confusione. Il fatto è che ormai i progetti non sono più come quelli di un trentennio fa in cui c‘era tutto da fare e quindi era possibile dividere nettamente le varie aree: nelle organizzazioni moderne i vari impiegati crescono professionalmente con l‘infrastruttura informatica fusa nel loro business; essa diventa parte integrante anche della loro forma mentis. Questo fa sì che nella pratica non sia infrequente il caso in cui dai casi d‘uso business si passi, attraverso qualche operazione di rifinitura, direttamente alla versione di sistema.
Come ripartire il modello business.
Il criterio da seguire per la ripartizione del modello di business in aree di dominio non può che essere basato sulle leggi del paradigma OO, e ancora una volta è possibile evidenziare l‘importanza del feedback architetturale. Architetti esperti, di solito, non hanno enormi difficoltà nel decomporre razionalmente il sistema generale in sottosistemi in modo da costruire sottosistemi intorno a “gruppi di dati” altamente coesi, tenendo conto anche delle funzioni che agiscono su di essi. Per questo fine, i modelli ad oggetti assumono un ruolo molto importante: attraverso l‘ispezione visiva è possibile raggruppare “oggetti” strettamente relazionati (coesi) tra loro e relativamente disaccoppiati dai restanti.
Per esempio, se si disponesse di un modello di dominio di un sistema di investimenti bancari, si potrebbe evincere l‘esistenza di un gruppo di oggetti strettamente legati ai dati provenienti dalla quotazioni di mercato, di un altro relativo a gruppi di dati (relativamente) statici, di un gruppo relativo alla gestione dei trade, di un altro afferente alla gestione della messaggistica e così via. Chiaramente ciò non significa assolutamente che i vari “mondi” non siano relazionati tra loro.
Una buona verifica consiste nel “bilanciare” le ripartizioni in sottosistemi in funzione dei servizi da erogare. Da tener presente che, una volta decomposto il sistema, la fornitura di diversi servizi richiede in genere l‘interazione dei sottosistemi attraverso opportune interfacce. Il bilanciamento, dalla prospettiva delle funzioni, permette di verificare che un sottosistema soddisfi i criteri base dell‘ingegneria dei sistemi:
- forte coesione interna;
- minimo accoppiamento tra sottosistemi;
- comunicazione ridotta al minimo tra sottositemi;
- servizi logicamente accomunabili.
e così via.
Approccio architecture-centric.
Processi di sviluppo del software esclusivamente basati sull‘analisi dei requisiti presentano un fattore di rischio troppo elevato: è sufficiente che alcuni requisiti non siano ben compresi o non correttamente analizzati, per compromettere il successo dell‘intero progetto; e inoltre non si conferisce la giusta considerazione ai rischi tecnici. Per esempio, un particolare servizio o scenario poterebbe richiede caratteristiche architetturali molto avanzate o performance molto stringenti oppure interazioni non standard con sistemi di legacy, tali da presentare un fattore di rischio molto elevato per l‘intero progetto. In queste situazioni è lecito attendersi che un corretto processo di sviluppo del software pianifichi disegno, implementazione e test di tali servizi nelle primissime interazioni per tutta una serie di motivi
- avere un maggiore spazio di tempo e minore livello di stress per analizzare problemi molto complessi, evitando quindi di ritrovarsi ad affrontarli quando magari il sistema è già in ritardo, il team di sviluppo presenta un livello non trascurabile di stress, alcuni manager cominciano a non divertirsi più a giocare con i videogiochi, etc.
- avere sufficiente tempo per intraprendere piani alternativi in caso in cui le cose comincino a presentare un pessimo andamento (reperire personale esperto, delegare esternamente l‘implementazione del servizio, etc.)
- in casi estremi, terminare prematuramente il progetto il prima possibile. Se il sistema è destinato a fallire, è meglio rendersene conto il prima possibili al fine di evitare di sprecare inutilmente importanti risorse.
Pertanto, la mitigazione dei rischi richiede ai processi moderni di incorporare approcci di tipo iterativo e incrementale (il sistema finale è raggiunto attraverso la realizzazione di una serie di sistemi parziali), conferendo particolare importanza all‘architettura (architecture centric) che non solo esiste, ma gioca anche un ruolo di primissima importanza.
Nei processi tradizionali si effettua l‘analisi dei requisiti, terminata la quale si avvia il processo di analisi e disegno: se, nel corso di questa, si individuano problemi, inconsistenze, possibilità di miglioramento dei requisiti e quindi del sistema, si torna alla fase precedente e si riprende il processo da capo. Si corre il grosso rischio di trovarsi nelle fasi finali del processo e rendersi conto di avere un grosso problema tecnico (magari un sistema esterno o una libreria non funzionano come dovrebbero, le performance non sono quelle attese, etc.) di difficile soluzione e che richiede un notevole lasso di tempo per la relativa gestione…
Nei processi iterativi e incrementali si conferisce molta enfasi sia allo svolgimento parallelo delle attività , sia alle procedure di verifica. Quindi non si attende la fine dell‘analisi dei requisiti per iniziare il disegno dell‘architettura, e tanto meno, si attende il consolidamento di quest‘ultima per fornire il feedback al processo di analisi dei requisiti. Come spesso avviene nel mondo dell‘informatica, si utilizza la famosa regola dell‘80/20. In particolare, si disegna una prima versione del modello statico dei casi d‘uso (attori, ellissi e relazioni varie) quindi, l‘architetto aiuta a selezionare i casi d‘uso da dettagliare per primi. Questi devono essere un 10-20% in grado sia di investigare gran parte dell‘architettura (il fattore 80%), sia di focalizzare requisiti non funzionali stringenti. Una volta prodotti questi primi casi d‘uso, l‘architetto è in grado di realizzare una prima versione dell‘architettura e quindi di fornire un iniziale feedback architetturale. Nei processi iterativi ed incrementali, il modello dei requisiti e il disegno dell‘architettura possono essere considerati come due curve, inizialmente abbastanza distanziate, che con il procedere del tempo, tendono ad avvicinarsi asintoticamente.
Nella realtà il livello di parallelismo del processo è ancora maggiormente accentuato dal fatto che gli architetti raramente disegnano nuove architetture da zero. Tipicamente, si adottano dei pattern predefiniti e/o delle soluzioni che si sono dimostrate efficaci in precedenti progetti. Pertanto sono in grado di fornire feedback fin dall‘elaborazione dei primissimi casi d‘uso. Questo è molto utile anche al fine di neutralizzare (o perlomeno evidenziare), il prima possibile, requisiti non fattibili, oppure la cui implementazione sarebbe eccessivamente esosa, fornendo strategie alternative per raggiungere i medesimi risultati.
È sempre necessario realizzare tutti e tre i modelli dei casi d‘uso?
Nel mondo lavorativo è abbastanza infrequente la produzione di tutti e tre i modelli dei casi d‘uso. Un simile processo sarebbe notevolmente formale, burocratico e costoso. Certamente, produrre tutte e tre le versioni dei casi d‘uso porterebbe molti vantaggi, ma il conseguente costo, probabilmente, non sarebbe facilmente giustificabile. Tuttavia, in alcuni casi eccezionali, è necessario realizzare tutti e tre i modelli, ciò, tipicamente, avviene in presenza di progetti di grandi dimensioni, gruppo di lavoro molto ampio e/o dislocato in diversi siti, e così via.
Molto più frequente è doversi occupare di un dominio da automatizzare o reingegnerizzare. Questo fa sì che il modello di business sia soventemente trascurato. Si tratta, comunque di un manufatto di grandissima importanza; formalizzando l‘intera aera business è possibile istruire facilmente nuovo personale, avere una base di partenza preziosissima per lo sviluppo di altri sistemi relativi a diversi domini, analizzare ed eventualmente razionalizzare i vari processi esistenti (anche manuali), etc.
Il problema è che però, di solito, questi modelli sono troppo esosi per la maggior parte dei progetti/organizzazioni per quanto rappresentino già di per sà© un “deliverable” di notevole valore rivendibile ad altre organizzazioni (anche se le organizzazioni tendono a considerare la struttura del proprio business come l‘arma vincente nella competizione contro i vari concorrenti). Si pensi a quale costo e quale valore potrebbe avere un caso d‘uso di business relativo all‘area investment di una banca.
Pertanto, nei processi di sviluppo del software, molto spesso, si tende a partire direttamente con la versione di analisi dei requisiti al livello di dominio (o addirittura di sistema). In altre parole si preferisce focalizzare l‘attenzione sulla sezione dell‘area business che dovrà essere implementata. Ciò però non significa che l‘analisi dell‘area business sia omessa in “toto”. Tipicamente è comunque necessario eseguirne un certo studio iniziale seguito da successive veloci incursioni nell‘area business, necessarie a integrare l‘analisi dei requisiti al livello di dominio.
Da tener presente che ogniqualvolta in un processo si decida di trascurare un manufatto, si introduce un fattore di rischio. La mancata produzione del modello dei casi d‘uso business può portare alla carenza della vista di insieme del business, con conseguenti servizi non correttamente realizzati, oppure realizzati svariate volte in diversi domini, magari con leggere variazioni, oppure trascurati completamente.
Come accennato in precedenza, molto spesso è più difficile produrre casi d‘uso al livello di dominio piuttosto che quelli al livello di sistema. Non è infrequente, infatti, il caso di dover raccomandare agli utenti di non esprimersi attraverso linguaggio pseudo-tecnico-informatico. Ciò per dire che, nella maggioranza dei casi, di tre modelli dei casi d‘uso, si finisce per produrne uno solo: quello di sistema, magari attraverso qualche iterazione volta a portare a termine l‘evoluzione del modello da una versione avanzata del dominio a quello di sistema. Come nel caso del modello di business, anche in questo caso la mancata produzione del modello di dominio introduce un fattore di rischio. In particolare, si corre il rischio di produrre casi d‘uso troppo legati ad una particolare architettura, troppo dettagliati e tecnici che finiscano per obbligare prematuramente il sistema a soluzioni basate su una visione ancora molto limitata.
Quando produrli
Qualora si decida di dar luogo al modello dei casi d‘uso di business, questo dovrebbe essere realizzato per primo durante le fasi iniziale del processo di sviluppo (Inizio, Inception). La produzione dei diversi modelli dei casi d‘uso in questa fase, tipicamente, non permette un grosso grado di parallelismo: questo è invece naturale tra le varie discipline (per esempio tra analisi dei requisiti e analisi e disegno). Quindi è necessario produrre prima il modello di business e poi i vari modelli di dominio. Questo anche perché raramente accade di disporre di diversi team di analisti ognuno assegnato a ciascun modello. Molto più frequente è il caso di un unico team con la responsabilità di produrre tutti i modelli.
Una volta prodotto il modello di business è possibile procedere alla realizzazione dei modelli di dominio. Ciò avviene tipicamente nella fase di elaborazione (Elaboration), anche se spesso la si avvia già nella fase precedente. L‘evoluzione del modello di dominio nella versione di sistema può avvenire in parallelo (in sostanza ogni volta sia disponibile il feedback dell‘architetto) e comunque avviene nella stessa fase di elaborazione.
La realizzazione dei casi d‘uso dovrebbe terminare durante la fase di costruzione (Construction), con la consegna dei servizi ritenuti di secondaria importanza, sebbene aggiornamenti siano frequenti anche durante la fase di transizione (Transition). Questo perché durante le fasi di test gli utenti potrebbero rendersi conto dell‘opportunità di implementare alcuni servizi secondo diverse modalità : i famosi cambiamenti dei requisiti.
Conclusioni
In questo articolo abbiamo investigato l‘integrazione del formalismo dei casi d‘uso nel contesto di processi di sviluppo del software con particolare riferimento a quelli iterativi e incrementali. In primo luogo abbiamo cercato di stabilire quanti e quali modelli dei casi d‘uso esitano, proponendo una terminologia standard, e una serie di linee guida per passare da un modello ad un altro.
I modelli individuati sono ben tre e in particolare: modello dei casi d‘uso di business, di dominio e di sistema. Sebbene la produzione di tutti e tre modelli fornisca numerosi vantaggi, non sempre è possibile/conveniente. Da tenere presente che trascurare la produzione di un artefatto, in questo caso di un modello dei caso d‘uso, introduce dei rischi progettuali che devono essere necessariamente mitigati con apposite contromisure.
Nella seconda parte presenteremo un semplice esempio pratico, con i relativi commenti. E a coloro che considerano certe tematiche come semplici discorsi accademici, diamo un “compitino” per la prossima volta: verificate (anche in maniera empirica, ma onesta) la percentuale di progetti software che fallisce o incontra enormi difficoltà nell‘avanzamento per mancanza di best practice nello sviluppo.
Riferimenti
[1] Luca Vetti Tagliati, “UML e Ingegneria Del Software. Dalla Teoria Alla Pratica”, HOPS/Tecniche Nuove, 2003
[2] IEEE Recommended Practice for Software Requirements Specifications IEEE Std 830-1998
[3] Frank Armour – Granville Miller, “Advanced Use Case Modelling. Software Systems”, Addison Wesley
[4] Ivar Jacobson, “Object Oriented Sofware Engineering. A Use Case Approach”, Addison Wesley
[5] Michael Jackson, “Software Requirements And Specification”, Addison Wesley
[6] Alistair Cockburn, “Writing Effective Use Cases”, Addison Wesley