domenica 7 agosto 2011

La Stima del Software

Introduzione

Quotidianamente, migliaia di project manager e sviluppatori di tutto il mondo sono alle prese con un rompicapo ben più difficile del Sudoku. Essi sono chiamati da clienti impazienti a fornire una valutazione in termini economici dello sviluppo di una nuova applicazione o della evoluzione di una parte di essa. Generalmente i tempi sono stretti e alla fine il numero partorito viene preso come legge e utilizzato nella catena di autorizzazioni (il capo del capo ecc) come sempre più un numero definitivo.
La realtà dietro a queste azioni è purtroppo fatta di parecchie incertezze e spesse volte quel numero magico non si avvicina nemmeno lontanamente alla realtà. Per esempio dopo aver effettuato la stima il Project Manager si ritrova già con i primi cambiamenti e durante i primi incontri con gli utenti finali si capisce che il sistema da realizzare è csicuramente diverso da quello che si immaginava prima delle stime. 
Nel corso del tempo la "scienza dei calcolatori" ha sviluppato una serie di metodologie di stima dei progetti, che presenterò brevemente in questo post, a dimostrazione dello sforzo di tanti nel dare una struttura a questa arte. Personalmente posso dire che fra tutti i metodi utilizzati preferisco utilizzare quello degli Use Case Points (UCP) a cui ho apportato una modifica che tende a renderlo meno aleatorio e permette di calcolare non solo i giorni/uomo ma anche il costo stimato del progetto. 




Modelli di Stima


E' meglio prima di tutto sottolineare una cosa: la stima è la valutazione più probabile dello sforzo profuso nello sviluppo di un determinato sistema software (tralasciamo i costi per ora). La stima rappresenta quindi un modello e quindi una rappresentazione della realtà che non sarà mai la realtà stessa. La mia conclusione personale è stata quindi quella di prendere in considerazione un modello di stima, quello che più si avvicina alle realtà che gestisco cercando di adattarlo in base ai feedback ricevuti alla fine dei progetti. Lo scopo di questo post non è quello di dare dei consigli in quanto la strada va trovata in base alla propria organizzazione, ma di fornire una carrellata sui metodi più conosciuti cercando di fornire la bibliografia necessaira per poter scegliere da soli. Spero di potervi aiutare.

 

Lines Of Code - LOC ovvero linee di codice


E' stato il primo sforzo per rendere scientifico l'approccio alla misurazione del software e si basa sul computo del numero di linee di codice che compongono il software. Chiaramente è una misura che si può raccogliere solo a prodotto finito oppure utilizzata prima dello sviluppo ma in seguito alla stimo di qualche altro tipo di effort (per es. Function Point).
Cosa dobbiamo includere nel calcolo delle linee di codice? Esistono una serie di indicazioni che il Software Engineering Institute (SEI) ha rilasciato attraverso una cecklist e in cui vengono indicate le parti da conteggiare e quelle da escludere [1]. Il calcolo produce le DLOC (Delivered LOC) che sono le linee di codice utili al dimensionamento del software e quindi al calcolo dell'effort. Computando invece tutte le linee di codice (compresi per es. dichiarazioni e commenti) si ottiene invece il SLOC (Source LOC).
E' possibile convertire le LOC in effort mediante l'applicazione di indici di produttività che però sono legati all'organizzazione che rilascia i progetti per cui, in base alla propria esperienza pregressa potremmo avere, per esempio, un indice di produttività (IP) di 160 DLOC al giorno uomo e quindi calcolare l'effort: Effort (in gg/uu) = DLOC/IP. 
Se non si dispone di indici di produttività si può utilizzare una stima parametrica derivata anch'essa da progetti pregressi di altre organizzazioni e introdotta  da Boehm nel 1981 ([2]). Essa è la Basic COCOMO e si basa sul tipo di organizzazione di progetto:
  • Organic Project: progetti con piccoli team, requisiti stabili e tecnologie conosciute, pressione temporale bassa.
  • Semi-detached: progetti con team medi, requisiti variabili e pressione temporale anche se non rappresenta un vincolo
  • Embedded: grandi team, requisiti sconosciuti o con grande variabilità, forte pressione temporale e la data di rilascio rappresenta un vincolo, ambienti complessi con hardware complesso e tecnologie sconosciute.
Nel Basic COCOMO il calcolo dell'effort è il seguente:

Effort Applied (E) = a * (SLOC)^b [mesi uomo]
Development Time (D) = c * E ^  [mesi]
People required (P) = E / D [persone]
dove:

     c = 2.5 e 


abd
Organic2.41.050.38
Semi-detached3.0 1.120.35
Embedded3.61.200.32


Boehm ha successivamente introdotto il modello Intermediate COCOMO che utilizza 15 parametri di stima e il COCOMO II che rappresenta un modello completo di stima sganciato dall'uso delle LOC ma utilizza gli elementi di progettazione del software.



COCOMO II

Il COnstructive COst MOdel II è un modello di stima incrementale che può essere utilizzato nelle diverse fasi del ciclo di vita del software fornendo di volta in volta stime più precise. Le fasi in cui è possibile effettuare la stima sono:
  • Applications Composition. E' la stima che interviene durante la fase di prototipizzazione e quindi a monte del progetto.
  • Early Design. E' la stima che interviene durante la fase di startup del progetto e prende in considerazione fattori di complessità (o cost drivers) quali il linguaggio da utilizzare, gli skills del tersonale impiegato, la complessità del prodotto ecc.
  • Post-architecture. Si utilizza durantye lo sviluppo del progetto o addirittura in fase di manutenzione dello stesso. 
Le ultime due stime impiegano il concetto di Function Point per calcolare gli effort. Per una descrizione dettagliata del modello COCOMOII si rimanda a [3].


Function Points (FP)

Una misura della complessità del software alternativa all'effort è sicuramente quella legata ai Function Points che ha largo seguito in grandi istituzioni a tal punto che esiste un'organizzazione IFPUG - International Function Point User Group - che regola ufficialmente le attività legate ai FP e che pubblica regolarmente il Function Point Counting Practices Manual che rappresenta la metodologia di calcolo ufficiale [4].
Il concetto alla base della Function Point Analysis (FPA) è quello di scomporre il sistema da sviluppare in componenti elementari che possono essere facilmente censite e classificate in diverse tipologie. Il computo di tutti questi mattoncini elementari e la relativa classificazione determina la complessità del singolo componente e quindi del sistema nel suo complesso.  La FPA può essere impiegata nelle prime fasi del progetto per la stima complessiva dello stesso ma ha più efficacia quando si basa sui requisiti e quindi sulla relativa documentazione.

Vediamo quali sono i componenti da individuare nel sistema ma prima di tutto è necessario determinare i confini del sistema da analizzare, per cui è necessario stabilire quali funzioni rientrano nel sistema e quali invece sono erogate da sistemi esterni. Una volta determinato il confine (boundary) si possono identificare i seguenti componenti:

  • Data Function
    • ILF. Internal Logical File: raggruppamento logico di dati mantenuto all'interno del confine applicativo che ha lo scopo di memorizzare informazioni a supporto di processi elementari    (es. cliente, utente, fattura, ecc.)
    • EIF. External Interface File: sono strutture logiche di dati provenienti da sistemi esterni.
  • Transazionali 
    • EI. External Input. Transazioni elementari necessarie al mantenimento delle strutture logiche legate agli ILF 
    • EO. External Output. Transazioni elementari che fanno fluire informazioni dall'interno del sistema verso l'esterno. 
    • EQ. External Inquiries. Transazioni elementari necessarie a selezionare dati e visualizzarli all'utente finale. I dati possono provenire ed essere aggregati da più ILF e EI
 Ci sono poi dei calcoli accessori da effettuare per ognuna delle caratteristiche precedenti:


  • RET. Record Element Type. Sono sottogruppi legati ad un ILF o EIF. Per esempio il dato logico fornitore può avere collegati dei RET indirizzo, telefono, ecc.  
  • DET. Data Element Type: sono i tipi di dati elementari utilizzati all'interno di un ILF e EIF  
  • FTR. File Type Reference: numero di ILF o EIF legate ad una particolare transazione
Vediamo ora come calcolare il valore in FP della nostra applicazione. Tale valore viene chiamato Unadjusted Function Point (UFP) in quanto non prende in considerazione le caratteristiche generali dell'applicazione. Tali caratteristiche, dette GSC, verranno introdotte successivamente. 
Veniamo al calcolo del UFP: per ognuna delle caratteristiche elencate va calcolata la complessità in termini di bassa, media, alta (Low, Afvg, High) in base al numero di RET e DET e FTR calcolati per ogni caratteristica:


Per ILF e EIF:

DETs
RETs1-1920-50>50
1LowLowAvg
2-5LowAvgHigh
>5AvgHighHigh
Per EI:

DETs
FTRs1-45-15>15
<2LowLowAvg
2LowAvgHigh
>2AvgHighHigh
per EO ed EQ:

DETs
FTRs1-56-19>19
<2LowLowAvg
2-3LowAvgHigh
>3AvgHighHigh


Quindi si calcola quante caratteristiche rientrano nelle classi Low, Avg, High e per ognuna di esse vengono calcolati i function point secondo la tabella che segue:


ComplessitàTotale
SourceLowAvgHigh
ILF - Internal Logic File _ * 7 = _ _ * 10 = _ _ * 15 = _
EIF - External Interface Files _ * 5 = _ _ * 7 = _ _ * 10 = _
EI - External Inputs _ * 3 = _ _ * 4 = _ _ * 6 = _
EO - External Output _ * 4 = _ _ * 5 = _ _ * 7 = _
EQ - External Queries _ * 3 = _ _ * 4 = _ _ * 6 = _

Quindi per esempio gli ILF di tipo Low valgono ognuno 7 function point, gli ILF di tipo Avg valgono ognuno 19 function point e tutti gli ILF di tipo high valgono ognuno 15 function point. 
La somma totale di tutti i function point per ognuna delle caratteristiche ILF, EIF, EI, EO ed EQ rappresentano, come detto, gli UFP Unadjusted Function Points.

In aggiunta ai precedenti componenti elementari di calcolo la Function Point Analysis considera una serie di fattori di complessità legati in generale al sistema da sviluppare. Sono 14 e precisamente:
  • Data communications. Complessità generale, valutata da 0 a 5, del trasferimento delle informazioni: 0 batch processing, 5 applicazione con front-end e diversi protocolli di trasferimento utilizzati
  • Distributed Data Processing. Complessità legata alla distribuzione della elaborazione dei dati: 0 nessuna distribuzione, 5 i dati soino raccolti e processati in differenti moduli e/o sistemi esterni
  • Performance. Livelli di performance e responsività richiesti al sistema: 0 nessun requisito di performance, 5 i tempi di risposta sono critici e sono richieste attività di performance analysis e impiego di tool di monitoraggio
  • Heavily Used Configuration. Grado di dipendenza dal tipo di hardware ad utilizzare: 0 nessuna specificità, 5 allocazione di parti di hardware per specifici moduli dell'applicazione.
  • Transaction Rate. Frequenza di esecuzione delle transazioni: 0 bassa, 5 molto alta
  • On-line data entry. Quale percentuale di transazioni richiede interazione con l'utente finale: 0 tutto in bacth mode, 5 più del 30% delle transazioni sono interattive
  • End-user efficiency. Grado di interattività del sistema. Esiste una tabella con 16 macro-caratteristiche dell'interfaccia utente e viene richiesto di valutare quali e quante di queste 16 caratteristiche sono necessarie al sistema finale. Il valore va da 0 - nessuna - a 5 - sei o più delle caratteristiche. Le sedici caratteristiche sono ad es.: uso di menu, scrolling, help online, pop-up, supporto multilingue, ecc.
  • On-line update. Quanti ILF sono gestiti e aggiornati da transazioni interative (on-line): 0 nessuno, 5 la maggioranza degli ILF e in aggiounta si richiedono politiche di recovery automatico dei dati.
  • Complex processing. Gradi di complessità dei calcoli matematici richiesti all'applicazione. Anche qui viene fornita una tabella con cinque modalità di calcolo e si computa quante di queste modalità sono utilizzate: 0 nessuna, 5 tutte.
  • Riusabilità. Grado di riusabilità del codice: 0 nessuna riusabilità, 5 l'applicazione è esplicitamente sviluppata per essere riutilizzata in altri contesti.
  • Installation ease. Grado di complessità della installazione: 0 nessuna richiesta particolare, 5 l'installazione è richiesta; ci sono particolari requisiti da verificare e testare.
  • Operational ease. Grado di complessità richiesto per la manutenzione applicativa (back-up, start-up applicativo e riavvio dei sistemi, procedure di recovery ecc.): 0 nessuna specifica attività, 5 tutto automatizzato
  • Multiple sites. Grado di distribuzione dell'applicazione: 0 stand-alone, 5 applicazione distribuita e utilizzata da più utenti di più organizzazioni, richiesta installazione su più ambienti e hardware.
  • Facilitate change. L'applicazione deve essere sviluppata per facilitare il cambiamento? Si utilizza una tabella di cinque caratteristiche richieste per la gestione del cambiamento. 0 indica nessuna delle caratteristiche, 5 tutte
Al termine della valutazione delle caratteristiche precedenti può essere calcolato il valore aggiunto (VAF - Value) richiesto dall'applicazione nel seguente modo:

VAF = 0.65 + somma(caratteristiche)/100

Infine il valore finale in function point del nostro sistema si calcola come

 FP = UAF * VAF

Sintetizziamo i passi per calcolare i FP:
  1. Determinare tutti gli ILF, EIF, EO, EI, EQ
  2. Determinare tutti RET, DET e FTR
  3. Associare RET, DET e FTR alle caratteristiche del punto 1
  4. Calcolare, in base alle tabelle precedenti, il livello di complessità di ogni ILF, EIF, EO, EI ed EQ nei termini Low, Avg, High
  5. Calcolare gli UFP sommando tutti i valori ottenuti secondo la tabella di conversione complessità/function point
  6. Calcolare il VAF
  7. Calcolare i function point FP = UFP * VAF
Ottenuto il valore dei FP, si deve procedere con il calcolo dell'effort mediante l'applicazione di un indice di produttività. Ad oggi esistono una serie di  tabelle computate in base a dati storici che mostrano i valori delle ore/uomo necessarie a sviluppare un Function Point. Esiste un database generale di progetti ed effort mantenuto dal ISBSG (www.isbsg.org) ma in genere possiamo considerare per i progetti Java un indice di produttività pari a 0.9 FP al giorno/uomo per progetti medio/piccoli (max 350 FP) fino a 0.5 F/P per progetti grandi (>2000 FP).


Use Case Points


Un metodo di stima alternativa ai Function Point è basato sulla analisi dei casi d'uso del sistema che sono utilizzati principalmente dalla metodologia RUP (Rational Unified Process). Il metodo deriva da un lavoro del 1997 da parte di Gustav Karner ([5])  e prevede essenzialmente il computo e la classificazione degli attori del sistema e dei relativi casi d'uso mediati attraverso una serie di fattori che rappresentano gli elementi "ambientali" che influenzano il progetto di sviluppo. 
Il primo passo è quello di calcolare gli Unadjusted Use Case Point, UUCP: si parte con il censire e valutare la complessità gli attori del sistema e degli use case secondo le tabelle che seguono:


Complessità
Definizione
Peso
SIMPLE
Un attore ha complessità SIMPLE se rappresenta un altro sistema esterno e la comunicazione avviene attraverso l'uso di librerie o API (Application Programming Interface)
1
AVERAGE
Un attore è AVERAGE se interagisce con mediante:
1. un protocollo di comunicazione 
2. terminale di linea.
2
COMPLEX
Un attore è COMPLEX se interagisce con il sistema mediante interfaccia grafica.
3
 Attori

Complessità
Definizione
SIMPLE
Uno use case è SIMPLE se attiva al massimo 3 transazioni e può essere realizzato con meno di 5 oggetti di analisi.
AVERAGE
Uno use case è AVERAGE se attiva dalle 3 alle     7 transazioni ed è possibile realizzarlo usando dai 5 ai 10 oggetti di analisi.
COMPLEX
Uno use case è COMPLEX se utilizza più di 10 transazioni e deve essere realizzato von più di 10 oggetti di analisi.
Use Case



UUCP si ottiene sommando per ogni attore e ogni use case il peso ottenuto:

UUCP = somma(Ni*Wi)

Dopo il calcolo degli UUCP si devono valutare i fattori che influenzano il progetto di sviluppo e precisamente i TCF, Technical Complexity Factor, e gli EF, Environmental Factor. I TCF rappresentano i fattori tecnici che possono influenzare lo sviluppo del sistema, essi sono 13 e hanno pesi definiti e precisamente:

Fi
Fattori Tecnici di Complessità
Wi
1
Distributed systems.
2
2
Application performance objec­tives, in either response or throughput.
1
3
End user efficiency (on-line).
1
4
Complex internal processing.
1
5
Reusability, the code must be able to reuse in other applications.
1
6
Installation ease.
0.5
7
Operational ease, usability.
0.5
8
Portability.
2
9
Changeability.
1
10
Concurrency.
1
11
Special security features.
1
12
Provide direct access for third par­ties
1
13
Special user training facilities
1

Ad essi si assegna un valore da 0 a 5: 0 nessuna influenza o importanza, 5 massima influenza (o importanza) sul progetto.

il TCF si calcola nel seguente modo:  

TCF = 0.6 + somma(Fi*Wi)/100

Gli Environmental Factor (EF)  aiutano a calcolare l'efficienza del progetto e considera le seguenti caratteristiche: 

j
Fattori che contribuiscono alla 
efficienza del progetto
Pesi
F  1
Familiar with Objectory (*)
1.5
F  2
Part time workers
-1
F  3
Analyst capability
0.5
F  4
Application experience
0.5
F  5
Object oriented experience
1
F  6
Motivation
1
F  7
Difficult programming language
-1
F  8
Stable requirements
2

(*) Siccome il contesto in cui è possibile applicare gli use case è più ampio rispetto all'uso della metodologia Objectory, è possibile sostituire il fattore F1 con "Familiarità con la metodologia adottata".

EF = 1,4-0,03 * somma (Wi * Fj) 
 
Dove per gli Fj possiamo assegnare valori da 0 a 5: 0 irrilevante, essenziale 5
Infine possiamo calcolare il valore di UCP come segue:
 

UCP = UUCP * TCF * EF.
 
Nel suo articolo originale Kerner effettua una valutazione dell'effort necessario a sviluppare uno UCP, mediante l'analisi di tre progetti differenti ottenendo un range che va da 20 ore uomo a 28 ore uomo per lo sviluppo di uno UCP. In un lavoro successivo Ribu ([6]) riporta che il range dell'effort può variare da 15 a 30 ore per UCP mentre Shneider e Winters propongono di adottare l'applicazione parametrica dell'effort contandpo il numero di caratteristiche superiori al valore 3 e applicare il valore 20 o 28 (v. [7]). Il consiglio, come anche per i Function Point è di dotarsi di dati storici per la propria azienda in quanto ogni team di sviluppo e ogni azienda avrà i suoi indici di produttività per cui solo nel tempo, mediante l'analisi a posteriori dell'effort impiegato si potranno ottenere i valori corretti di quel team o azienda. Per iniziare è possibile applicare la regola di Shnider per cui si può utilizzare il valore 20 per progetti semplici e il valore 28 per progetti molto complessi.


Aggiornamento: ho creato un tool per la gestione delle stime che è possibile scaricare a questo link: download tool per la stima software
 
BIBLIOGRAFIA

Molte di queste informazioni sono state tratte dal buon libro di Shivprasad  sulla stima del software: "How to Prepare Software Quotation" , Draft 1.0. http://k.1asphost.com/UseCasePoints/UseCasePoints.pdf
 

Per i modelli COCOMO vedere:
[1].
http://greenbay.usc.edu/csci577/fall2005/projects/team23/LCA/Team23_COCOMOII-SourceLinesOfCodeDefinitionsV1.0.pdf
[2]. Software engineering economics. Englewood Cliffs, NJ:Prentice-Hall, 1981. Barry Boehm. 
[3]. COCOMO II Model Definition Manual. Jongmoon Baik. http://www.dicyt.gub.uy/pdt/files/6.2.1_-_cocomo_model.pdf


Function Point
[4]. Function Point Counting Practices Manual.  The International Function Point User Group
[5]. Karner Gustav.  Resource Estimation for Objectory Projects. 1993.


UCP
[6]. Ribu, Kirsten. 2001. Estimating Object-Oriented Software Projects with Use Cases.  Master of Science Thesis, University of Oslo, Department of Informatics. 
[7]. Schneider, Geri and Jason P. Winters. 1998. Applying Use Cases: A Practical Guide.  Addison Wesley.
[8]. Una sintesi eccellente della UCP si trovano in "Stima Con i Punti Use Case", Mike Cohn. 
[9]. Un articolo e una discussione sulla produttività delle UCP è l'articolo di Gianfranco Lanza "Function Point: come trasformarli nello sforzo Questo è il problema?"

Nessun commento:

Posta un commento