Con questo primo articolo avviamo una miniserie dedicata a un argomento infuocato, fonte di continue diatribe tra gli adepti delle varie ‘religioni’ delle metodologie di sviluppo del software: similarità e differenze tra la notazione dei casi d’uso e quella delle storie utente. Tuttavia, prima di addentrarci nel dibattito è necessario chiarire definizione e struttura dei requisiti con particolare riferimento a quelli funzionali. Solo alla fine di questo breve percorso sarà possibile addentrarsi del dibattito, chiarendo pro e contro di ciascuna notazione per comprendere appieno vantaggi e svantaggi. Ma iniziamo con i requisiti funzionali.
Iniziamo con qualche definizione
La definizione dei requisiti e del relativo modello rappresentano gli inevitabili punti di partenza di questa miniserie. Analizzando le letteratura informatica attualmente disponibile è possibile notare che sebbene si faccia largamente riferimento a un generico modello generale dei requisiti, la sua struttura interna e la corrispondente evoluzione durante il ciclo di sviluppo del software sono raramente analizzate e illustrate formalmente e nei dettagli [1].
In questo paragrafo riportiamo alcune definizioni attinte da diverse metodologie di sviluppo del software. L’intento non è di propendere per l’una o l’altra metodologia, ma fornire al lettore un quadro preciso della complessità del modello dei requisiti, complessità molto spesso ignorata. L’analisi dei requisiti è indubbiamente uno delle fasi più complesse del ciclo di vita del software, troppo spesso trascurata o non affrontata con la dovuta diligenza. Esula dai fini di questo articolo entrare nei dettagli di ciascun sottomodello dei requisiti.
RUP, IEEE e altro ancora
Una definizione attinta dalla letteratura RUP [2] sancisce che “un requisito descrive una condizione o un’abilità alla quale il sistema deve conformarsi; i requisiti possono derivare direttamente dalle esigenze degli utenti, o essere sanciti da un contratto, da uno standard, da una specifica o da un qualsiasi altro documento formalmente imposto”.
Lo standard IEEE 729-1983 [3] presenta una definizione simile ma leggermente più elaborata. In particolare, asserisce che un requisito è:
- una capacità software necessaria ad un utente per risolvere un problema o per raggiungere un determinato obiettivo;
- una capacità software che deve essere raggiunta o posseduta dal sistema o da un componente al fine di soddisfare un contratto, uno standard, una specifica, o un qualsiasi altro documento formalmente imposto;
- l’insieme dei requisiti software che formano le basi per un successivo sviluppo del software o di un componente software.
Secondo le raccomandazioni dello standard IEEE Recommended Practice for Software Requirements Specifications (Pratiche raccomandate per la specifica dei requisiti software [4]), un requisito può essere suddiviso nelle seguenti categorie:
- funzionalità: cosa deve fare il software?
- interfacce esterne: in che modo il software interagisce con gli utenti umani, il sistema hardware, altre parti hardware e altri componenti software?
- performance: qual è la velocità, la disponibilità, il tempo di risposta e di recupero delle varie funzioni software?
- attributi (proprietà): quali solo le considerazioni relative ad attributi del sistema come portabilità, correttezza, manutenibilità, sicurezze, etc.?
- vincoli imposti sul disegno e sull’implementazione: esistono requisiti relativi all’applicazione di standard esistenti, all’utilizzo di specifici linguaggi di programmazione, di politiche per l’integrità dei database, di limiti delle risorse, di ambiente operativo?
Secondo Robert Seacord, Daniel Plakosh, Grace A. Lewis [5] i requisiti possono essere organizzati nelle seguenti quattro categorie:
- utente: questi requisiti sono le capacità che devono essere fornite dal sistema, capacità frequentemente espresse come task e attività che devono essere supportate dal sistema.
- sistema: questi requisiti descrivono le capacità del sistema incluso il sistema stesso.
- vincoli: questi includono decisioni che devono essere prese, come interazioni con altri sistemi, standard del processo sviluppo, e costi.
- non funzionali: questi requisiti includono caratteristiche comportamentali che il sistema deve possedere, come per esempio: performance, usabilità e sicurezza.
Oltre alle definizioni formali di requisiti, è importante menzionare che di sovente nella realtà esiste un’altra dimensione di requisiti spesso non espressi esplicitamente fino alle fasi finali dello sviluppo del software. È appena il caso ricordare che il ruolo degli analisti business non è quello di meri scrivani di requisiti, ma di analizzatori. Quindi, parte fondamentale del ruolo del business analyst è comprendere e criticare i requisiti comunicati dagli utenti e formulare proposte alternative. Ciò non è sempre immediato in quanto una particolare categoria di esigenze degli utenti comprende anche desideri mai confessati, omissioni legate a motivazioni legali, a politiche aziendali o anche a interessi personali di particolari gruppi di utenti.
Citando Kruchten [2], “potrebbe aver senso tenere traccia dei desideri ambigui dei nostri interlocutori, così come si fa per le richieste formali, al fine di assicurarsi che vengano gestiti in qualche misura”.
Organizzazione del modello dei requisiti
Abbiamo quindi visto come i requisiti siano un manufatto complesso e multidimensionale del processo di sviluppo del software, e che è di fondamentale importanza organizzarli organicamente in apposite categorie. Ciò per far sì che i vari elementi non siano ripetuti in diversi manufatti, che siano analizzati dalle persone più idonee, modellati attraverso i formalismi più opportuni, e così via.
Rappresentazione formale
Il diagramma UML di figura 1 illustra una rappresentazione formale dell’organizzazione dei requisiti software: componenti principali e relative interdipendenze. Questo è il modello su cui si basa questa serie di articoli. Da notare che, indipendentemente dal fatto che all’interno di un progetto si decida o meno di “catturare” e gestire i requisiti nelle loro varie forme, queste di fatto esistono e un’analisi approssimativa dei requisiti utente è spesso il modo migliore per far fallire un progetto fin dalle prime fasi.
Il modello complessivo (rappresentato dalla grande icona del package) comprende una pluralità di altri manufatti che sono modellati come package annidati in quello principale, legati tra loro attraverso relazioni di dipendenza. Inoltre, ognuno di essi, a sua volta, può comprendere una pluralità di altri manufatti. Ad esempio, il modello dei requisiti funzionali può includere un insieme di storie utente o di casi d’uso (diagrammi e relative specifiche), tipicamente organizzati in aree funzionali. I package gialli rappresentano modelli che si prestano a essere realizzati attraverso la notazione UML.
Figura 1 – Rappresentazione del modello dei requisiti.
Aspetti della notazione
Le dipendenze tra i package annidati esprimono una serie di concetti semantici fondamentali. Per esempio le relazioni tra i requisiti funzionali e il modello a oggetti del business esprimono formalmente il fatto che, mentre i requisiti funzionali descrivono i servizi che il sistema deve fornire, il modello ad oggetti del business specifica le entità business che devono essere manipolate per fornire tali servizi.
Ancora, il glossario e il modello (a oggetti) del business catturano il vocabolario business attraverso due diverse notazioni, rispettivamente: il linguaggio naturale e la notazione dei diagrammi delle classi. I requisiti non funzionali (NFR, “Non-Functional Requirements”) specificano le proprietà del sistema considerato nel suo complesso. Questa categoria di requisiti comprende aspetti quali le prestazioni, le politiche di sicurezza, la disponibilità del sistema, le strategie di backup e ripristino, e così via. Il modello delle interfacce di sistema e il modello GUI descrivono l’interfaccia utilizzata dal sistema per interagire con i suoi attori: altri sistemi ed esseri umani. In questa fase, le varie interfacce incapsulano solo le informazioni richieste dalle esigenze di business e quindi dovrebbero trascurare dettagli implementativi.
Di seguito vediamo i dettagli dei vari modelli.
Requisiti funzionali
I requisiti funzionali rappresentano i servizi, i compiti e le funzioni che il sistema deve implementare: catturano il comportamento richiesto al sistema software. Questa categoria è spesso, erroneamente, considerata come l’unico documento dei requisiti necessario per lo sviluppo software.
Tradizionalmente, l’intero insieme dei requisiti veniva analizzato e documentato in un unico documento che, inevitabilmente, tendeva a diventare un tomo considerevole, mix diabolico tra requisiti e soluzioni: il famoso documento delle specifiche funzionali. All’interno di questo documento, era possibile trovare tutti i tipi di requisiti: funzioni da realizzare, descrizione delle GUI, delle interfacce utente, requisiti non funzionali, accenni di modelli di dati, etc. spesso mischiati tra loro e introdotti ad hoc. Sebbene attualmente esistano diverse filosofie relative a come gestire, analizzare e documentare i requisiti, vi è quasi unanimità nel considerare questo approccio come pesante e pericoloso. In particolare, la redazione del “tomo” dei requisiti software ha dimostrato di soffrire di tutta una serie di gravi limitazioni, tra cui le più significative sono quelle riportate di seguito.
Difficoltà di lettura e gestione
Il singolo documento delle specifiche è inevitabilmente destinato ad assumere dimensioni notevoli. Ciò ne scoraggia e ne complica la lettura e la comprensione. Inoltre, non supporta i classici approcci di gestione della complessità: limita l’applicazione della famosa strategia “divide et impera”. Tomi siffatti sono difficilmente suddivisibili in sotto-componenti atomiche da studiare e dettagliare separatamente.
Maggiore complessità dell’analisi
Redigere il singolo documento è un esercizio molto complesso: non favorisce il compito dell’analista (o del team) di potersi concentrare, di volta in volta, su un insieme ben definito di elementi e di analizzarli con i dovuti strumenti/skill. La logica conseguenza è che il documento risulta naturalmente ridondante e incompleto e tende a presentare incoerenze in diverse sue parti.
Ambiguità intrinseche
Il documento, per definizione, utilizza eccessivamente il linguaggio naturale, che in questo campo è decisamente ambiguo, per sua natura.
Organizzazione non compartimentata
Il singolo tomo non solo è difficile da consultare, da comprendere e mantenere, ma le varie parti sono tipicamente interrelate e non ben compartimentate. Inoltre, non c’è alcune argine alla mancanza di strutturazione. Per esempio, può accadere che durante la redazione di un requisito funzionale siano aggiunte informazioni relative alla GUI, al modello dati, etc.
Limitato supporto alla fase di test
Il supporto alla realizzazione dei casi di test è molto limitato e spesso il personale del test si ritrova a dover dar luogo ad un’altra analisi dei requisiti prima di poter procedere con il proprio lavoro.
Scarsa scalabilità del team
Documenti di questo tipo sono difficili da suddividere in diverse parti autonome da poter assegnare al team degli analisti di business/architetti (per esempio: un business analyst addetto all’analisi dei modello del business, uno ai NFR, uno al set di requisiti funzionali relativi all’amministrazione, etc.), e quindi non si presta a un’efficace sviluppo parallelo;
Non adatto allo sviluppo iterativo
La redazione del singolo documento, non si presta ad un approccio di sviluppo iterativo e incrementale che è alla base moderni processi di sviluppo software (da Scrum a MDA) e in particolare alla necessità di analizzare i vari requisiti in fasi;
Limitato supporto alla gestione del progetto
Il singolo documento rende il lavoro del project manager più complesso. La sua forma e struttura non si prestano alla facile estrapolazione di servizi e gruppi di requisiti da allocare alle varie iterazioni/sprint.
Limitato supporto al disegno dell’architettura
Il tomo dei requisiti non favorisce il disegno iniziale dell’architettura fin dalle prime fasi del processo di sviluppo del software (non si presta ad un approccio architecture-centric). Sebbene i requisiti debbano specificare cosa è richiesto al sistema e non il come (e questa è una di quelle regole che non deve mai prevedere eccezioni), è inevitabile che questi debbano vivere all’interno di un’architettura. Ciò equivale a dire che è vero che si parte dalla definizione dei requisiti (magari di un primo set ben definito), e che dalla loro analisi si comincia a disegnare un’architettura che possa soddisfarli: quindi si parte da due manufatti inizialmente abbastanza distanti tra loro. Ma deve essere chiaro che, con l’evoluzione del prodotto, questa distanza deve essere azzerata: l’architettura dipende dai requisiti, ma poi anche i requisiti devono necessariamente dipendere dall’architettura.
Casi d’uso e storie utente
Per risolvere i problemi che abbiamo appena descritto, ci vengono in aiuto le due principali metodologie utilizzate per affrontare i requisiti funzionali: use case (“casi d’uso”) e user story (“storie utente”); insieme a una corretta organizzazione del modello dei requisiti in sotto-modelli, come illustrato in figura 1, ci consentono di operare nel modo migliore. In questa serie ci concentriamo sui requisiti funzionali e sul confronto fra casi d’uso e storie utente. Riportiamo di seguito delle brevi descrizioni di base dei due sistemi.
Breve cenno alla notazione dei casi d’uso
L’embrione iniziale della notazione dei casi d’uso può essere fatta risalire al 1967 quando Ivar Jacobson lavorava allo sviluppo del sistema AXE presso Ericsson. Durante tale esperienza, Jacobson iniziò ad utilizzare, in maniera abbastanza informale, una nuova notazione per catturare i requisiti utente. Come detto dallo stesso Jacobson: “Quando ho usato il termine nel 1986, si trattava dell’evoluzione dei lavori in corso dal 1967” [11]. Tuttavia, la vera svolta nella comunità OO è avvenuta solo nel 1992, con la pubblicazione del libro “Object-Oriented Software Engineering: A Use Case Driven Approach” [12].
Comprese le potenzialità della notazione dei casi d’uso, Booch e Rumbaugh decisero di includerla nella prima versione dello standard OMG UML. Così standardizzata, la notazione dei casi d’uso prevede due manufatti:
- i diagrammi dei casi d’uso (sebbene si tratti della modellazione della struttura dei casi d’uso, e quindi di un modello statico, spesso viene definito come comportamentale);
- la specifica dei casi d’uso: la parte dinamica.
I diagrammi dei casi d’uso includono attori, e funzioni, rappresentate per mezzo di ellissi dotate di un nome, chiamate a loro volta use case. Questi sono opportunamente organizzati attraverso esclusivamente tre tipi di relazioni: include, extend ed eredità. Con i suoi “omini”, gli “ovali” e le “linee”, la notazione dei diagrammi dei caso d’uso può apparire piuttosto semplice o addirittura naif; in realtà, la sua corretta applicazione richiede una adeguata e approfondita esperienza. Non è raro analizzare pessimi casi d’uso che soffrono di problemi ben noti: eccessivo livello di dettaglio, casi d’uso che tentano di progettare il sistema, o al contrario, casi troppo astratti che finiscono per non specificare il comportamento richiesto del sistema, quelli che sono frutto di una decomposizione funzionale, e così via.
Per quanto attiene alla specifica dei casi d’uso, la componente dinamica, ci sono diverse correnti di pensiero. C’è chi predilige definire il comportamento per mezzo di altri diagrammi dello UML, come sequence diagram o activity diagram, e chi preferisce descrivere il flusso degli eventi attraverso un semplice documento. Anche questo argomento verrà dettagliato negli articoli successivi, tuttavia l’approccio suggerito consiste nel ricorrere ad appositi template come illustrato in figura 2.
Figura 2 – Diagramma dei casi d’uso con relative specifiche.
Breve cenno alla notazione delle storie utente
Le storie utente sono un formato spesso utilizzato nell’ambito di progetti gestiti tramite metodologie agili (Scrum in primis). Lo scopo è quello di definire un bisogno di “business” dell’utente tramite l’utilizzo di un linguaggio naturale e comprensibile sia al personale tecnico ma anche a utenti e/o a esperti di dominio.
Nella compilazione della storia ci si concentra quindi nel definire in modo estremamente sintetico e ad alto livello la funzionalità che si dovrà andare a implementare per rispondere a tale bisogno. Esula invece dagli obiettivi della storia la definizione dei dettagli tecnici, del design o dell’analisi di dettaglio della funzionalità, tutte cose che verranno dettagliate al momento dell’effettivo bisogno, e solo se ritenuto necessario, tramite altri strumenti (per esempio i casi d’uso). Tale modus operandi nella raccolta dei requisiti, è espressione, ma al tempo stesso precondizione di un processo iterativo incrementale tipico delle metodologie agili.
Fra i vari formati utilizzabili per la compilazione delle storie, uno dei più frequenti è quello che segue il seguente schema:
- in qualità di…
- vorrei che…
- affinche’…
Un esempio di una storia potrebbe quindi essere:
“In qualità di utente del sistema di home banking, vorrei poter effettuare il login in modo univoco, affinche’ tutte le operazioni eseguite siano collegate al mio account.”
Questo formato è stato proposto da Ron Jeffries, personaggio al quale la comunità internazionale deve molto, essendo non solo uno dei padri firmatari dell’Agile Manifesto, ma anche fra gli inventori dell’eXtreme Programming.
Il formato proposto da Jeffries (noto come il formato delle 3C) prevede di includere sul fronte di un cartoncino una descrizione come quella appena vista (“in qualità di…”), mentre sul retro viene riportato un elenco di criteri di accettazione (Acceptance Criteria o AC), necessari per determinare i requisiti di completezza e correttezza della funzionalità che si andranno a implementare.
Benche’ il formato di una storia sia relativamente semplice, esso si basa su una serie di concetti e su una visione molto profonda. Una completa trattazione esula dagli scopi di quest’articolo; per maggiori informazioni e approfondimenti sul significato e sulla filosofia di base di una storia, rimandiamo alla lettura dell’articolo di Giovanni Puliti “Guida galattica per scrummmers – V parte: Le storie utente”, pubblicato proprio questo mese su MokaByte.
Modello a oggetti del business
Non è infrequente il caso in cui ai business analyst viene detto “Gli use case sono fantastici: ccrivi tutto nei casi d’uso”. Simili pericolose raccomandazioni si possono trovare anche nell’area delle user story. Ma i casi d’uso non sono validi per analizzare ogni requisito. Questa notazione è veramente valida solo per descrivere il comportamento del sistema [6].
Sebbene, i casi d’uso e le storie utente siano uno strumento molto utilizzato per modellare i requisiti funzionali di un sistema, questi descrivono solo una parte dei requisiti: appunto la parte dei servizi e delle funzioni da implementare.
Quindi, i casi d’uso o user story da soli non sono assolutamente sufficienti, ne’ adatti, per raccogliere tutti i tipi di requisiti che un sistema deve realizzare. Questi devono essere completati e validati attraverso un altro insieme di manufatti, tra i quali uno di particolare importanza è il modello ad oggetti del business. Il disegno di tale modello permette di realizzare un’analisi dei requisiti qualità superiore, fornisce un insieme di informazioni fondamentali per lo sviluppo del software, permette di scrivere casi d’uso/storie utente più concise e comprensibili, permette di dar luogo a tutta una serie di modelli necessari durante le fasi di sviluppo del software, come il disegno dell’API, della GUI, dello schema del database, etc. fondamentali per lo sviluppo del software.
Modello di dominio
Secondo Jacobson, Booch and Rumbaugh (i famosi “tres amgos”, [7]): “Un modello di dominio (altro nome del modello ad oggetti del business) cattura i tipi di oggetto più importanti nel contesto del sistema. Questi oggetti di dominio rappresentano le ‘cose’ che esistono o gli eventi che traspaiono nell’ambiente in cui il sistema funziona. Pertanto, le classi di dominio possono emergere nelle loro tre forme tipiche:
- oggetti di business che rappresentano le cose che sono manipolate dal business stesso, come ad esempio gli ordini, gli account, i contratti, etc.;
- oggetti reali e concetti di cui un sistema ha bisogno di tenere traccia, come per esempio: aerei nemici, missili, le varie traiettorie, etc.;
- eventi che esistono o trapelano, come per esempio l’arrivo degli aeromobili, la partenza dell’aeromobile, la pausa pranzo.”
Come si nota, il focus è posto esclusivamente su entità (classi) di tipo business: classi necessarie per lo sviluppo o per l’applicazione di pattern come per esempio MVC, manager, handler, etc. non devono apparire in questo modello: si tratta di un’analisi business.
Secondo Doug Rosenberg e Kendall Scott: “Il termine dominio del problema si riferisce all’area che comprende oggetti reali e i concetti relativi al problema che il sistema deve risolvere. La modellazione del dominio è il compito di scoprire ‘oggetti’ (classi, più precisamente) che rappresentano queste cose e concetti. […] La modellazione del dominio implica lavorare verso l’esterno dai requisiti dei dati per costruire un modello statico del dominio del problema relativo al sistema proposto”.
Molti nomi
Questo modello è definito con nomi diversi, quali Domain Object Model (“modello a oggetti di dominio”), Business Object Model (“modello ad oggetti del business”) o semplicemente Business Model (“modello del business”): si tratta di nomi non ideali che spesso finiscono per confondere. In effetti, il modello non descrive tutti gli aspetti del “business” (non è da solo un business model), è popolato di classi e non di oggetti, e inoltre queste classi non sono vere e proprie classi dal punto di vista OO: sono completamente prive dell’aspetto comportamentale, vale a dire i metodi. Probabilmente un nome più appropriato potrebbe essere modello statico del business. Pertanto, sebbene giustamente la notazione selezionata sia quella dei diagrammi delle classi, si tratta in effetti di un modello molto simile ai tradizionali diagrammi entità-relazioni.
Il modello a oggetti del business è un grafo di entità del business interconnesse: è la somma di tutte le entità, comprese le loro relazioni. Ciascuna di queste entità (classi) racchiude un insieme coerente di informazioni business, ed è manipolata da opportuni processi presenti nell’area business (descritti dai casi d’uso/user story) che il sistema intende automatizzare in qualche misura.
Un esempio
Il diagramma presente nella figura 3 rappresenta un frammento (package) del modello a oggetti del business relativo ad un sistema di trading bancario che manipola oggetti quali Request, Request For Quote e Order Request. Come si può vedere, il modello non include alcuna classe di natura tecnica: si “limita” a descrivere le relazioni tra le varie entità presenti nel business.
Figura 3 – Frammento di un modello a oggetti del business.
Il modello a oggetti del business è di fondamentale importanza nel contesto dello sviluppo del software e spesso è un delivery di per se’: è rivendibile a varie organizzazioni che lo possono utilizzare per automatizzare i propri dipartimenti. Un modello a oggetti del business di buona qualità ha un valore enorme e si presta all’implementazioni di un numero di diversi sistemi implementati in diverse organizzazioni, con diverse tecnologie, etc.
Il diagramma di figura 4 mostra gli utilizzi principali, nel contesto del processo di sviluppo del software, del modello a oggetti del business. In particolare, facendo riferimento al diagramma seguente, in ordine, esso fornisce la struttura per poter definire:
- lo schema del database;
- l”API del sistema, inclusi eventuali messaggi;
- il disegno della GUI;
- dettaglio dei vari processi
- l’organizzazione del sistema in componenti e le relative interfacce;
- i grafi di oggetti utilizzati per scambiare informazioni tra i vari layer dell’architettura;
- le strutture da implementare.
Figura 4 – Modelli prodotti a partire dal modello ad oggetti del business.
Business rules
Le business rules (regole di business, nel senso di “elementi che regolano logica applicativa del sistema”) sono un altro aspetto fondamentale dell’attività di raccolta e analisi dei requisiti, tanto per cambiare, non esente da una serie di malintesi. Vediamo subito un paio di definizioni.
“Le regole di business sono definite come procedure dettagliate, relazioni e orientamenti, che guidano il comportamento di un’azienda in determinate situazioni. Un sistema dovrà attuare queste regole se si vuole automatizzare gli aspetti del business in cui tale regole si applicano. Tali procedure e regole sono requisiti che devono essere catturati” [9].
“Dal punto di vista aziendale, una regola di business è una norma che sancisce un obbligo relativo a condotta, azioni, prassi o procedura all’interno di una particolare attività o sfera. Dal punto di vista del sistema informativo, una regola aziendale è una dichiarazione che definisce o vincola qualche aspetto del business. Esso è destinato a valutare la struttura aziendale, o per controllare o influenzare il comportamento del business [10].
Il ruolo delle business rules
Le business rules sono quelle regole che hanno un ruolo importante nell’organizzazione e/o nel mondo degli affari che il sistema informativo tenta di automatizzare. Spesso non si limitano alla specifica organizzazione, ma possono includere le leggi imposte dal governo, i requisiti della clientela, certe direttive interne, norme, regolamenti e anche il sempre valido “senso comune”. Quindi, possono variare in funzione del luogo in cui il sistema dovrà funzionare. Ad esempio, lo sviluppo di un sistema di trading, tipicamente, deve tener in considerazione che non è consentito eseguire il trading per prodotti finanziali di una lista ben definita di Paesi. Una simile regola si applica anche alle agenzie di viaggio: alcuni governi non consentono di offrire come meta delle proprie vacanze località sgradite al governo.
Dalle definizioni di cui sopra, emerge che ogni regola aziendale, indipendentemente dalle sue caratteristiche specifiche, disciplina uno o più elementi di business e quindi ha un impatto importante su diverse parti sistema.
Per esempio, la limitazione del trading citata sopra non solo richiede la definizione e implementazione di una serie di controlli pre-deal, ma richiede anche che il modello a oggetti del business riferito ai prodotti finanziari includa informazioni come: country of incorporation e country of residence per poter eseguire questi controlli. Queste informazioni poi devono essere presenti nelle tabelle relative al prodotto finanziario, nelle API, e così via.
I classici esempi di regole di business sono vincoli, norme e leggi che possono risultare operanti nella particolare area di business che il sistema intende automatizzare e quindi la loro raccolta e analisi può iniziare fin dalle prime fasi dell’analisi dei requisiti. Tuttavia, la maggior parte di queste regole tendono a essere scoperte durante le fasi di analisi dei vari processi. Giacche’ i requisiti funzionali si prestano a essere modellati attraverso opportuni casi d’uso/storie utente, ne consegue che un gran numero di regole di business emergono durante la stesura di tali casi d’uso.
Davvero serve un modello a parte?
A questo punto ci si potrebbe interrogare sulla effettiva necessità di realizzare un modello a parte. In effetti, un certo numero di praticanti considerano i casi d’uso/storie utente come il luogo “naturale” per memorizzare le regole di business. Questa soluzione, ahime’, raramente rappresenta una valida strategia. questo per una serie di problemi. Il primo è che, in genere, le medesime regole di business sono riferite da diversi casi d’uso/storie utente e da altri modelli (ad esempio il modello di disegno, il codice, etc.). Pertanto, la decisione di mantenere le business rule in use case/user story, finisce per generare la necessità di copiare e incollare le medesime regole in tutta una serie di modelli con evidenti problemi legati alla loro manutenzione. Inoltre, le regole di business, a seconda della loro natura (vincoli, algoritmi , etc.), si prestano ad essere documentate per mezzo di diverse notazioni. Ad esempio, uno dei modi migliori per esprimere un algoritmo è quello di realizzare un apposito activity diagram. Pertanto, la notazione dei casi d’uso/storie utente non sempre rappresenta lo strumento appropriato per esprimere regole di business. Per finire, anche il documento delle business rules rappresenta un ottimo delivery di per se’.
Per questi motivi, un’ottima strategia per catturare e gestire le regole del business consiste nel memorizzarle in un unico manufatto, anche un semplice documento o addirittura un foglio elettronico, sempre caro al pubblico degli utenti, e di referenziarle ovunque necessario attraverso il relativo codice univoco. Chiaramente non bisogna commettere l’errore opposto: svuotare i casi d’uso / user story in quanto tutto il comportamento è descritto nel documento delle regole business. Di seguito è riportato un esempio di business rule.
BR::EXEC:instrument_tradability
I messaggi di avvertimento devono essere mostrati sullo schermo se si verifica una delle seguenti condizioni. Se indicato, la conferma dell’utente è richiesta, seguendo un messaggio di pop-up prima che la request possa essere inviata. Si può verificare anche più di una sola condizione in maniera concomitante, nel qual csao devono essere mostrati tutti i messaggi e ciascun pop-up deve contenere la sua casella di conferma da selezionare. Il messaggio deve essere prefissato da “Warning – “.
Figura 5 – Esempio di business rule.
Requisiti non funzionali (NFR)
I requisiti non funzionali (Non Functional Requirements, NFR) definiscono le proprietà del sistema e i vincoli che devono comunque essere presenti nel sistema, anche se non vanno a soddisfare una specifica esigenza utente. I NFR devono in definitiva essere soddistatti anche dall’architettura del sistema. Si tratta di proprietà e vincoli che dovranno esserci per definizione e pertanto non presentano grandi margini di negoziazione. Le proprietà che il sistema deve avere tipicamente coprono aspetti di particolare interesse per degli stakeholder del sistema, e quindi, in ultima analisi, hanno un notevole impatto sulla valutazione del grado di soddisfazione nell’utilizzo del sistema. Esempi di NFR sono la sicurezza, la disponibilità, le prestazioni, l’usabilità, l’affidabilità, la sicurezza dei dati, e così via.
Dove si raccolgono i NFR?
Esistono persone che consigliano di specificare i NFR come informazioni supplementari da aggiungere nelle descrizioni dei casi d’uso/storie utente. La logica alla base di questo approccio è abbastanza comprensibile: è comodo fornire al team di sviluppo una specifica funzionale completa di tutti i relativi requisiti; ma questo approccio tuttavia presenta una serie di problemi. Per esempio, non tutti i NFR sono relativi a servizi specifici, ma comunque devono essere propriamente analizzati; alcuni di essi influenzano diversi requisiti funzionali (e più generalmente diversi ambiti): replicare lo stesso NFR in un numero di manufatti li rende più difficili da manutenere e complica il mantenimento della storia dei vari cambiamenti. Pertanto la classica strategia di definire tutti i NFR in un apposito documento e di linkarli in tutti i necessari manufatti sembra ancora una volta una strategia ottimale.
Secondo le raccomandazioni dello standard IEEE Recommended Practice for Software Requirements Specifications (pratiche raccomandate per la specifica dei requisiti software, [4]), i NFR comprendono le seguenti proprietà: affidabilità, disponibilità, sicurezza, manutenibilità e portabilità. Considerazioni relative alle performance, data la loro importanza, sono trattate in un apposito paragrafo. Inoltre, concetti come interfacce del sistema, interfacce utente, interfacce hardware e software, memoria, etc. sono incluse in una sezione definita prospettiva del prodotto (mettono il prodotto in prospettiva con altri prodotti correlati).
Infine, la sezione caratteristiche dell’utente comprende la descrizione delle caratteristiche generali dei potenziali utilizzatori del prodotto, tra cui il livello di istruzione, esperienza tecnica e competenza.
Esempi di NFR
Nel caso del sistema di trading bancario, alcuni esempi di NFR sono:
- NFR::EXEC:Auto-negotiation service. Il sistema deve essere in grado di gestire un’autonegoziazione proveniente da un mercato elettronico entro un secondo. Questo include il momento da cui la richiesta (RFQ) arriva nel sistema fino al momento in cui la corrispondente risposta (RFQ-response) diviene disponibile per il mercato elettronico.
- NFR:: EXEC:StreamPrices. Durante il momento di picco, in genere identificato con le ore 12 del Regno Unito, quando i mercati USA cominciano le transazioni, il sistema deve essere in grado di gestire in tempo reale un intervallo compreso tra le 1000 e le 2000 nuove quotazioni per secondo. Al sistema è consentito di perdere meno dell’1% dei messaggi durante l’ora di punta.
- NFR:: EXEC:availability. Il sistema deve essere disponibile 24 ore al giorno per 5 giorni a settimana. I finesettimana possono essere impiegati per la manutenzione. I giorni di festività nazionale dovrebbero essere considerati normali giorni lavorativi, poiche’ il sistema sarà impiegato in molte parti diverse del mondo, da Tokyo a New York.
I NFR rappresentano uno strumento di fondamentale importanza per il lavoro dell’architetto. In effetti la situazione tipica prevede che uno stesso insieme di requisiti funzionali si presti a essere risolto da diverse possibili soluzioni: tra queste però sono alcune sono veramente in grado di soddisfare anche i requisiti non funzionali. Quindi i requisiti non funzionali sono uno dei tool che l’architetto utilizza per filtrare le soluzioni veramente fattibili tra l’insieme di quelle possibili.
Interfacce business
Dato un modello ad oggetti del business, è possibile ricavare altri importanti tipologie di requisito tra cui l’interfaccia utente e l’interfaccia di sistema. Per convenienza, si consideri la notazione dei casi d’uso: le interfacce sono presenti in tutti i punti in cui un attore (sia umano, sia tecnico) interagisce con un caso d’uso (figura 6). Se l’attore è un essere umano, allora l’interfaccia è ovviamente una GUI, almeno per il momento, mentre, quando l’attore è un altro sistema o processo, allora l’interfaccia è software: è un’interfaccia di sistema.
Figura 6 – Esempio di uno use case digram relativo a un’applicazione di trading, con evidenziati gli spazi delle interfacce.
Nel diagramma di figura 6 è interessante notare che gli attori non umani presenti nel diagramma dei casi d’uso precedente sono stati raffigurati per mezzo di un’icona a forma di sistema invece della rappresentazione classica della figura stilizzata. Questo al fine di sottolineare il fatto che questi attori non sono esseri umani, ma sistemi. UML permette questo approccio per mezzo dell’uso del meccanismo comune dello “stereotipo”.
Formalismo della notazione
Sebbene il formalismo ideale per rappresentare le interfacce di sistema sia costituito dai diagrammi delle classi, e quindi le varie interfacce dovrebbero essere rappresentate come grafici di oggetti opportunamente estrapolati dal modello ad oggetti di dominio, gli utenti spesso preferiscono una notazione basata sugli spreadsheet. Pertanto, spesso vi è una tensione fra la necessità del team di sviluppo per poter disegnare e implementare l’API e gli utenti che raramente si sentono a loro agio con notazioni ad alto contenuto tecnico. Il risultato è che spesso si devono accontentare gli uni e gli altri: diagramma delle classi con opportuna spiegazione di ogni classe ed attributo.
Il diagramma di figura seguente mostra il grafo degli oggetti che devono essere scambiati dal componente che si occupa di fare lo streaming delle quote. Questo grafo deve essere derivato dal modello a oggetti del business.
Figura 7 – Frammento del diagramma delle classi relativo agli oggetti scambiati dallo streaming delle quote.
Una situazione analoga accade con le interfacce utente. Nonostante la possibilità di poterle rappresentare attraverso formalismi tecnici, la stragrande maggioranza degli utenti si sente a proprio agio con notazioni più descrittive come screenshot e/o una storyboard (figura 8).
Figura 8 – Snapshoot dela UI del Price Blotter.
Sebbene non sia infrequente il caso di trovare descrizioni dettagliate delle interfacce sia utente e sia di sistema, all’interno dei casi d’uso o delle storie utente, si tratta di una pratica che verosimilmente è meglio evitare per tutta una serie di motivi. Per esempio, i casi d’uso e le storie utente non sono la notazione più idonea per rappresentare questo tipo di informazioni, requisiti funzionali con all’interno queste informazioni tendono ad essere fragili ai cambiamenti, rigidi nella definizione e dipendenti da una specifica interfaccia.
“In molti casi d’uso scritti male, è possibile spesso trovare riferimenti ai clic del mouse, list box, frame e window. In situazioni normali, i requisiti funzionali sono redatti come una serie di requisiti che il sistema deve soddisfare ” [6].
Tuttavia, la comprensione delle specifiche funzionali richiede di tanto in tanto di menzionare un livello minimo di informazioni relative all’interfaccia utente. Il suggerimento consiste nel minimizzare questi riferimenti, utilizzabili limitatamente nei casi importanti. Il giusto livello di compromesso, come al solito, rappresenta un’ottima strategia.
Conclusioni
Con questo primo articolo abbiamo avviato una miniserie che ha come obiettivo finale capire bene vantaggi e svantaggi delle due principali notazioni utilizzate per documentare i requisiti funzionali: use case e user story. Si tratta di un tema molto dibattuto e fonte di alcune guerre “religiose”. Prima però di entrare nel dettaglio di questo dibattito è necessario risolvere alcune precondizioni, chiarire alcuni aspetti fondamentali: cos’è un requisito? Quanti tipi di requisiti esistono? Come sono relazionati tra loro?
Molte persone sono cresciute professionalmente lavorando in progetti in cui i requisiti venivano forniti attraverso un unico documento che, inevitabilmente, diventava un tomo difficile la leggere, da comprendere, da suddividere in parti atomiche da assegnare a diverse persone, che non supportava processi iterativi, e così via.
In questo articolo abbiamo suggerito di organizzare il modello dei requisiti nelle seguenti parti: requisiti funzionali (quali servizi/funzioni deve fornire il sistema?); modello a oggetti del business (quali sono e come sono organizzate le entità che operano nello spazio business che il sistema intende automatizzare?); vocabolario del sistema (descrizione in linguaggio naturale del punto precedente); requisiti non funzionali (che performance deve fornire il sistema? quale disponibilità? quale livello di affidabilità? che tipo di sicurezza? e così via); interfacce business (che tipo di esperienza utente è richiesta? quali sono le interfacce di sistema?).
Nel prossimo articolo vedremo nel dettaglio i casi d’uso con una serie di esempi concreti.
Riferimenti
[1] Luca Vetti Tagliati, PhD, “Software Evolution Using Requirement Patterns”, July 2009
[2] Philippe Kruchten, “The Rational Unified Process: An Introduction”, 2nd edition, Addison Wesley Longman, 2003
[3] ANSI/IEEE Standard 729-1983
[4] IEEE standard 830-1998. (Revision of IEEE Std 830-1993). IEEE Recommended Practice for Software Requirements Specifications
[5] Robert Seacord – Daniel Plakosh – Grace A. Lewis, “Modernizing Legacy Systems: Software Technologies, Engineering Processes, and Business Practices”, Addison Wesley Professional, 2003
[6] Steve Adolph – Paul Bramble – Alistair Cockburn – Andy Pols, “Patterns for Effective Use Cases”, Addison Wesley
[7] Ivar Jacobson – Grady Booch – Jim Rumbaugh, “Unified Software Development Process”, Addison Wesley Longman, 1999
[8] Doug Rosenberg with Kendall Scott, “Use case driven object modelling with UML. A practical approach”, Addison Wesley
[9] Frank Armour, Granville Miller “Advanced Use Case Modeling. Software Systems”, Addison Wesley, 2001
[10] Business Rule Group
http://www.businessrulesgroup.org
[11] Ivar Jacobson, “Use Cases: Yesterday, Today, and Tomorrow”
http://www.jaczone.com/papers/use_cases-2002-11-26.pdf
[12] Ivar Jacobson “Object-Oriented Software Engineering: A Use Case Driven Approach”, Addison Wesley 1992