risorse | pyramid

Overview Pyramid con SourceMonitor

Introduzione

L'Overview Pyramid è una rappresentazione sintetica dello stato di un progetto software.

esempio di overview pyramid

La piramide è suddivisa in tre parti: il vertice, con le metriche relative alle gerarchie ereditarie, la parte di sinistra, con quelle associate alla dimensione e alla complessità del codice, e la parte di destra, con quelle sull'accoppiamento del sistema.

Il vertice: system inheritance

Il vertice della piramide mostra due indici relativi all'ereditarietà:

ANDC (average number of derived classes)
numero medio di classi derivate;
AHH (average hierarchy height)
lunghezza media delle catene di derivazione.

ANDC misura l'ampiezza media degli alberi di derivazione: valori bassi di questo parametro denotano gerarchie “strette”, che si sviluppano prevalentemente in verticale, mentre valori alti caratterizzano gerarchie “larghe”, che si sviluppano prevalentemente in orizzontale.

AHH misura la profondità media degli alberi di derivazione: valori bassi denotano gerarchie che si sviluppano su pochi livelli, viceversa, valori alti caratterizzano gerarchie piuttosto “alte” che si sviluppano cioè su molti livelli.

Valori bassi di entrambi gli indici denotano l'assenza di strutture gerarchiche significative: il sistema è composto per la maggior parte di classi autonome.

La parte di sinistra: system size & complexity

La parte di sinistra della piramide riporta cinque indici relativi alla dimensione del codice e della sua complessità:

NOP (number of packages)
numero di componenti del sistema (in C++ coincide col numero di namespaces definiti);
NOC (number of classes)
numero di classi del sistema (in C++ coincide con il numero delle class e delle struct);
NOM (number of methods)
numero totale dei metodi definiti (in C++ comprende anche le funzioni globali);
LOC (lines of code)
numero di linee di codice;
CYCLO (cyclomatic complexity index)
somma delle complessità attribuite ai metodi del sistema.

L'analisi della dimensione e della complessità del codice avviene sulla base dei rapporti di queste metriche:

NOC/NOP (high-level structuring)
misura la granularità dei componenti: valori bassi denotano la presenza di componenti “poveri”, contenenti cioè poche classi, mentre valori alti sono caratteristici di sistemi con componenti troppo “ricchi”;
NOM/NOC (class structuring)
misura il livello di distribuzione delle attività del sistema tra le classi: valori bassi denotano la presenza di classi “stupide”, prive cioè di un numero adeguato di metodi, mentre valori alti indicano classi con troppe responsabilità;
LOC/NOM (operation structuring)
misura il grado di distribuzione delle funzionalità del sistema tra i metodi; valori alti denotano la presenza di metodi particolarmente “lunghi”, composti cioè da un numero eccessivo di operazioni, valori bassi sono invece associabili a metodi particolarmente “brevi”;
CYCLO/LOC (intrinsic operation complexity)
misura la complessità media di un'operazione: valori bassi denotano la presenza di metodi “semplici”, tendenzialmente lineari, mentre valori alti caratterizzano metodi con un numero eccessivo di istruzioni condizionali.

La parte di destra: system coupling

La parte di destra della piramide riporta due indici relativi all'accoppiamento dei componenti del sistema:

CALLS
numero di chiamate distinte effettuate (nel contesto di un singolo metodo, più chiamate alla stessa funzione conta come una);
FANOUT
numero di tipi distinti riferiti (nel contesto di un singolo metodo, più riferimenti ad uno stesso tipo conta come uno).

L'analisi del grado di accoppiamento del sistema avviene sulla base dei rapporti di queste metriche:

CALLS/NOM (coupling intensity)
numero medie di chiamate effettuate durante l'esecuzione di un'operazione; valori bassi denotano sistemi poco strutturati, viceversa alti valori sono caratteristici dei sistemi fortemente modulari, in cui le operazioni più complesse sono realizzate per composizione di attività più semplici;
FANOUT/CALLS (coupling dispersion)
numero medio di classi coinvolte nell'esecuzione di un'operazione: valori bassi denotano sistemi “coesi”, nei quali cioè le funzionalità sono realizzate da poche classi, valori alti sono invece caratteristici dei sistemi “frammentati”.

Creazione del prospetto

Per generalità, ho predisposto una trasformazione XSLT che produce la piramide a partire da un file XML contenente le metriche di base. Segue un esempio di file XML sorgente:

<?xml version="1.0" encoding="us-ascii"?>
<?xml-stylesheet type="text/xsl" href="pyramid.xsl"?>
<pyramid tool="SourceMonitor">
 <andc></andc>
 <ahh></ahh>
 <nop>49</nop>
 <noc>1500</noc>
 <nom>7215</nom>
 <loc>186497</loc>
 <cyclo>14009</cyclo>
 <calls>34714</calls>
 <fanout></fanout>
</pyramid>

Il prospetto HTML prodotto dalla traformazione (cfr. esempio) riporta, oltre alla piramide, i valori soglia applicati ai diversi indici della piramide (sezione Thresholds), nonché delle indicazioni circa le possibili cause associate a valori fuori norma (sezione Smells).

Raccolta delle metriche

Ho condotto il primo esperimento di costruzione della piramide con una versione beta di SourceMonitor, la 3.4.6.301 (quelle precedenti hanno qualche problema nell'esportazione dei dati da linea di comando).

La procedura si compone di due passi:

  1. esportazione delle metriche;
  2. analisi delle metriche e salvataggio degli aggregati su file XML.

Ho sfruttato la capacità di SourceMonitor di esportare le metriche di dettaglio del progetto e quelle di metodo su file CSV: ho perciò predisposto un file batch per SourceMonitor con i riferimenti alle cartelle del progetto software da analizzare e ho preparato uno script Python per ricavare dai due file CSV le metriche necessarie alla costruzione della piramide. Ho infine automatizzato la procedura di esportazione e aggregazione delle metriche con un ulteriore file batch per il prompt.

Nota: SourceMonitor non determina tutte le metriche necessarie all'istanziazione degli indici della piramide (nella fattispecie: ANDC, AHH, NOP e FANOUT); per questo motivo, alcuni di essi sono marcati come n/a – not available. NOP viene stimato dallo script python, che assume essere equivalente al numero di cartelle in cui sono stati suddivisi i file sorgente.

Conclusioni

Una volta copiati gli script pyramid.cmd e pyramid.py in una cartella dedicata, e aver salvato in una cartella denominata templates i due file pyramid.xsl e pyramid.css, il prospetto va generato lanciando il comando:

    pyramid.cmd <sourcemonitor-command-file> <output-dir>

ove <sourcemonitor-command-file> è il percorso al file batch di SourceMonitor, mentre <output-dir> è il nome della cartella dove il prospetto sarà salvato.

Se la procedura si conclude senza errori, l'apertura del file <output-dir>\pyramid.xml in un qualunque browser produrrà il prospetto atteso.

Aggiornamento [28/11/2013]

Alla luce delle considerazioni fatte in Overview Pyramid con CCCC, conviene valutare se inibire il conteggio delle linee vuote (cfr. comando ignore_blank_lines). Poiché SourceMonitor determina pure il numero di istruzioni di cui è composto un metodo, è stata realizzata una nuova versione degli script (qui quello Python, qui quello per il prompt) che utilizzano questa stima come indice LOC. Per attivare questa modalità è sufficiente invocare pyramid.cmd specificando il flag --stmt come ultima opzione da riga di comando.

Aggiornamento [02/12/2013]

Aggiunta la possibilità di specificare il nome e il numero di versione del progetto software da inserire nel titolo del prospetto:

Usage: pyramid.cmd <sourcemonitor-command-file> <output-dir> [options]

Options:
  --stmt             replace the LOC value with the statement count
  --name=NAME        supply the project's name
  --version=VERSION  supply the project's version number

Oltre all'indicazione dello strumento utilizzato per raccogliere le metriche, in testata ora viene riportata anche la data di creazione del prospetto stesso.

Riferimenti

  1. Girba, T., Lanza, M., Marinescu, R. "Pragmatic Design Quality Assessment". slideshare.net. <http://www.slideshare.net/girba/pragmatic-quality-assessment-tutorial-icse-2008>
  2. Lanza, M., Marinescu, R. Object-Oriented Metrics in Practice. Springer-Verlag Berlin Heidelberg, 2006.
  3. Pichler. M. "Using the Overview Pyramid". manuel-pichler.de. <http://manuel-pichler.de/archives/31-Using-the-Overview-Pyramid.html>
  4. VV.AA. "Exploring Smells and Metrics". Institut fur Informatik III – Universitat Bonn. <http://sewiki.iai.uni-bonn.de/research/cultivate/tutorial_exploring_smells_and_metrics>
  5. VV.AA. "SourceMonitor". Campwood Software. <http://www.campwoodsw.com/sourcemonitor.html>

Pagina modificata il 27/11/2013