Introduzione
Tra
i fattori che determinano la qualità di un software,
ve ne sono alcuni che sono più appariscenti, rilevabili
da qualunque utente privo di competenze specifiche di sviluppo
software (fattori esterni), altre che riguardano direttamente
solo chi produce il software (i fattori interni). I fattori
interni possono diventare esterni se l'utente è in
qualche modo coinvolto in attività di produzione/fornitura
di software (ad esempio una libreria per programmatori ha
come utenti altri programmatori e non semplici operatori).
Alcuni
tra i principali fattori esterni rilevabili dall'utente finale
generico sono: Correttezza di funzionamento e affidabilità,
Robustezza, Estensibilità, Facilità e flessibilità
d'uso, Portabilità e Scalabilità.
I fattori interni o rilevabili da un utente specialistico
sono fondamentalmente due: Menutenibilità e Riusabilità.
Il raggiungimento di questi ultimi requisiti ha notevoli ripercussioni
anche sui fattori esterni, o meglio sulla facilità
con cui la qualità esterna può essere ottenuta.
I contributi forse più noti per ciò che concerne
la qualità del SW sono gli standard ISO relativi ai
processi produttivi e di servizio ed ai prodotti software
(vedere [QPS]). In particolare, la serie di standard ISO 9000
non è specifico dei prodotti software e si occupa di
definire le caratteristiche e i requisiti di un sistema di
qualità aziendale (standard di processo), mentre lo
standard ISO 9126 (vedere [ISO9126]) definisce alcune nozioni
generali concernenti la qualità dei prodotti software
(standard di prodotto).
Figura 1: Lo standard ISO 9126
Il contenuto dello standard ISO 9126 è costituito da
un elenco di caratteristiche di qualità di un generico
prodotto software:
- Functionality
(Suitability, Accuracy, Interoperability, Compliance, Security)
- Reliability
(Maturity, Fault tolerance, Recoverability)
- Usability
(Understandability, Learnability, Operability)
- Efficiency
(Time behaviour e Resource behaviour)
- Maintainability
(Analysability, Changeability, Stability, Testability)
- Portabilità
(Adaptability, Installability, Conformance, Replaceability)
Ogni
qual volta si vuole valutare la bontà di un bene o
di un servizio risulta pressocchè indispensabile esprimere
il giudizio attraverso una metrica.
Per
misurare la qualità di un prodotto software le caratteristiche
di qualità devono essere tradotte in metriche concrete
(che devono tenere conto delle specifiche caratteristiche
del prodotto desiderato) che permettano di esprimere una valutazione
quantitativa della qualità del bene o servizio osservato.
Una
metrica è una funzione che permette di associare ad
un attributo di un'entità un valore numerico o scalare.
Il numero di metriche potenzialmente utilizzabili per valutare
beni e servizi IT è estremamente elevato. Le metriche
dimensionali per il software si basano sul conteggio del numero
di istruzioni del programma (come LOC -Lines Of Code, e/o
NLOC-Non-commented Lines Of Code) o sul numero di funzionalità
presenti nel programma (function points). Altre metriche di
prodotto sono quelle che valutano la difettosità di
un programma (espresse attraverso rapporti: per esempio numero
di errori rilevati per modulo oppure numero di errori rilevati
in un periodo di tempo) e altre si riferiscono al lavoro richiesto
per sviluppare o modificare un programma (anni/uomo o mesi/uome
per indicare il lavoro).
Un
programma di misura è costituito dall'insieme di informazioni
che specificano quali dati raccogliere e secondo quali modalità
operative tale raccolta deve essere condotta.
La
definizione di un processo/programma di misura e la relativa
creazione è un processo complesso che richiede pianificazione,
organizzazione e utilizzo di risorse adeguate.
La qualità del codice
Data
la vastità e la complessità dell'argomento,
ci concentreremo ora su uno specifico aspetto: la qualità
del codice.
Come
è possibile misurare la qualità del codice?
Quali metriche e/o regole utilizzare per misurare tale qualità
?
In
generale è sempre opportuno che tutti coloro che lavorano
nell'ambito della stessa azienda o dello stesso progetto seguano
le stesse regole nelle varie fasi della costruzione del software.
La
motivazione che spinge a definire una convenzione stilistica
da seguire per la stesura del codice è quella di aiutare
nella realizzazione di un prodotto finale che sia comprensibile
nel minor tempo possibile e che consenta di evitare di incorrere
in errori banali, ma dagli effetti imprevedibili.
L'aderenza
a certe metodologie e tecnologie tipicamente fornisce già
degli standard e delle linee guida, che assicurano un buon
grado di omogeneita in tutti i prodotti, in particolare a
livello di regole di codifica (anche se in taluni casi è
opportuno specificare ulteriormente il metodo di lavoro con
l'elaborazione di regole linee guida).
Ad
esempio SUN fornisce delle Code Convention (vedere [CCJPL])
che riportano indicazioni sulle regole sintattiche da seguire,
sull'organizzazione del codice, naming convention e pratiche
di programmazione per aiutare gli sviluppatori a scrivere
codice uniforme, omogeneo e consistente.
La
rilevanza dell'utilizzo delle Code Convention, rispetto alla
riusabilità del software e all'intercambiabilità
delle risorse umane, è intuitiva.
Metodologie
agili come XP enfatizzano l'uso delle Code Convention tanto
da inserirle come parte integrante della metodologia; infatti
la pratica Coding standards (vedere [XP_CS]) fa parte delle
12 pratiche XP cosiddette "core" (vedere [XP_12P]
e [MOKA_MET_2]).
In
XP la pratica Coding standards è fondamentale anche
per agevolare la pratica Collective Code Ownership (vedere
[XP_CCO]) che definisce la proprietà collettiva del
codice da parte dell'intero gruppo di lavoro: chiunque può
modificare e migliorare una qualsiasi parte del sistema.
Tool di auditing del codice
Esistono sul mercato ed in ambito open source diversi prodotti
che permettono di effettuare l'auditing del codice secondo
specifiche regole e/o metriche.
Il
funzionamento di questi tool si basa sull'analisi del codice
in cerca di potenziali problemi come blocchi try/catch/finally
vuoti, variabili e/o proprietà e/o metodi non utilizzati,
statements vuoti, naming convention disattese, import non
utilizzati, ecc
In
questo modo è possibile avere un'oggettiva (ed automatica!)
misurazione della qualità del codice rispetto a specifiche
regole di audit.
Figura 2: Funzionamento di un tool di code auditing
Tali tool mettono a disposizione dei file di regole per verificare
la bontà del proprio codice rispetto alle cosiddette
"well-known convention" che nel caso di Java sono
le Code convention di Sun. Generalmente questi tool sono facilmente
configurabili per permettere di analizzare il codice anche
con regole di audit ad hoc per specifiche esigenze.
Prendiamo
ad esempio il seguente codice Java che gestisce una semplice
conversione da lire in euro e proviamo ad applicare le regole
di audit relative alle Sun Code Convention utilizzando il
prodotto Open Source Checkstyle (vedere[CHECKSTYLE]):
import
java.sql.Connection;
import java.io.File;
import java.net.Socket;
public
class myconverter{
private File file;
private Connection connection;
private double lire = 0;
private static final double euro = 1936.27;
public static double Convertilireineuro(String somma, int
val) throws ConversionException{
if(somma==""){
String errMsg = " ERRORE ! Somma NON valida!";
System.out.println(errMsg);
throw new ConversionException(errMsg);
}
double valoreSomma=0;
try{
valoreSomma=Double.parseDouble(somma);
}
catch(NumberFormatException nfe){
}
return valoreSomma/euro;
}
}
Applicando
le regole di audit sul codice, Checkstyle crea un report HTML
che riporta ben 11 violazioni delle Sun Code Convention (vedere
figura 2).
<taskdef
resource = "checkstyletask.properties"
classpath = "${checkstyle.dir}/checkstyle-all-3.3.jar;
${checkstyle.dir}/checkstyle-optional-3.3.jar"/>
<target name = "checkSrc" description ="ciclo
di verifca src" depends="init">
<checkstyle config = "${checkstyle.config.file}"
failureProperty="checkstyle.failure"
failOnViolation="false">
<formatter type = "xml"
toFile = "${checkstyle.error.output.file.xml}"/>
<fileset dir="${base.src.dir}">
<include name="**/*.java" />
</fileset>
</checkstyle>
<style in="${checkstyle.error.output.file.xml}"
out="${checkstyle.error.output.file.html}" style="${result.dir}/checkstyle_errors.xslt"/>
</target>
Figura 3 - Report di Checkstyle
(clicca sull'immagine per ingrandire)
Dalle segnalazioni riportate si vede come la Naming Convention
consigliata da SUN sia clamorosamente disattesa: il nome della
classe è minuscolo così come il nome della costante
ed il nome del metodo è maiuscolo (vedere [CCJPL]).
Oltre
a queste segnalazioni sulla naming convention ci sono altre
segnalazioni importanti come
quella che indica che sono dichiarate tre proprietà
(file, connection e lire) che non vengono mai utilizzate all'interno
del codice.
Sono
inoltre segnalati gli import inutilmente referenziati (java.net.Socket)
ed il parametro val del metodo Convertilireineuro() che non
è mai utilizzato. Quest'ultimo errore sicuramente metterà
in difficoltà l'utilizzatore del metodo che si chiederà
cosa deve specificare come valore del parametro.
Tutte
queste segnalazioni indicano in generale codice "sporco"
e poco leggibile, alcuni dei problemi segnalati rendono anche
più complesso il reverse engineering del codice in
esame presentando dipendenze non strettamente necessarie.
Un'altra
segnalazione importante è relativa alla presenza del
catch vuoto in corrispondenza della NumberFormatException
(è buona pratica non lasciare mai blocchi catch vuoti
inserendo almeno una trace che tenga traccia dell'eccezione
avvenuta).
L'ennesima
segnalazione riguarda l'uso improprio dell'operatore di uguaglianza
al posto del metodo equals. L'ultima segnalazione, ma non
la meno importante, è relativa alla completa assenza
di Javadoc.
La versione del Javadoc che si ottiene è quella di
default e risulta essere poco utile ad un eventuale utilizzatore
della classe.
Risultato:
la qualità del codice dell'esempio visto lascia alquanto
a desiderare rispetto alle Code Convention Sun.
Figura 4 - La "qualità" del codice
della classe myconverter
Mettiamoci
all'opera per eliminare le segnalazioni di audit che abbiamo
ottenuto.
/**
* <p>Title: EuroConverter</p>
* <p>Description: Classe che gestisce la conversione
€uro in £ire</p>
* <p>Copyright: Copyright (c) 2001</p>
* <p>Company: Mokabyte</p>
* @author S. Rossini - srossini@mokabyte.it
* @version 1.0
*/
public class EuroConverter{
/** Valore in lire dell'euro */
private static final double EURO = 1936.27;
private EuroConverter(){}
/** Converte le lire in euro
* @param somma il valore delle £ire da convertire
* @return il corrispondente valore in €uro
* @throws ConversionException se la somma <b>non</b>
e' un valore valido
*/
public static double convertiLireInEuro(String somma)throws
ConversionException{
if(somma.equals("")){
String errMsg = "convertiLireInEuro: ERRORE ! Somma NON
valida!";
System.out.println(errMsg);
throw new ConversionException(errMsg);
}
double valoreSomma=0;
try{
valoreSomma=Double.parseDouble(somma);
}
catch(NumberFormatException nfe){
nfe.printStackTrace();
}
return valoreSomma/EURO;
}
}
Dal
punto di vista della qualità sintattica e stilistica
del codice, le cose sono nettamente migliorate sia in termini
di leggibilità che in termini di coerenza (si dichiara
ed usa lo stretto necessario).
Da tutto ciò ne trarranno vantaggio sia i programmatori
che dovranno utlizzare la classe, sia chi dovrà effettuare
la manutenzione e/o le modifiche successive.
Il
reverse che si ottiene è veritierio e non riporta inutili
dipendenze ed il Javadoc generato semplificherà la
vita agli utilizzatori della classe essendo chiaro e utile.
Figura 5 - la "qualità" del codice
della classe EuroConverter
Da
notare come i tool di auditing del codice tipo Checkstyle,
PMD (vedere [PMD]), CodePro (vedere [CODEPRO]) mettano a disposizione
gli (ormai) immancabili plugin per eclipse. Grazie ha queste
integrazioni è possibile configurare tutto graficamente
ottenendo in "tempo reale" i report durante lo sviluppo.
Ad
esempio, per avviare il check di audit con il plugin Eclipse
di CodePro, è sufficiente selezionare i file Java d'interesse
e selezionare la voce Quality Assurance\Audit per ottenere
immediatamente le (eventuali) violazioni delle regole all'interno
dell'IDE di Eclipse.
Figura 6 - Quality Assurance Audit
Ovviamente sia le regole di audit che i relativi livelli di
severity (info, warning, error e fatal) sono configurabili.
Figura 7 - Configurazione regole di audit e livello
di severity
Da
notare che non solo le regole di audit sono configurabili
(si possono attivare/disattivare, modificare il livello di
severity,
), ma è anche possibile creare nuovi
controlli ad hoc estendendo le classi del tool di Audit Code.
In questo modo è possibile creare regole ad hoc per
le proprie specifiche esigenze di audit.
Ad
esempio con Checkstyle, per creare nuovi controlli, è
sufficiente estendere la classe base com.puppycrawl.tools.checkstyle.Checker
ed implementare gli opportuni metodi di callback del framework.
Figura 8 - Un controllo personalizzato di CheckStyle
Nel metodo beginTree() bisogna inserire la logica di inizializzazione
del controllo mentre la logica del controllo vero e proprio
deve essere implementata nel metodo visitToken() (vedere [CS_DOC]).
La
regola custom risulta essere "pluggabile" in Checkstyle
come una qualsiasi regola standard:
<module
name="it.mokabyte.mokarules.MokaSampleControl">
<property name="severity" value="error"/>
</module>
Da
notare infine come i tool di audit code mettano a disposizione
anche la possibilità di applicare al codice diverse
metriche.
Ad esempio con il plugin Eclipse di CodePro è sufficiente
selezionare i file Java d'interesse e selezionare la voce
Quality Assurance\Metrics per ottenere informazioni sul numero
di linee per codice (LOC), il numero medio dei commenti (CR),
il numero dei parametri per ogni metodo (NOP), il numero delle
proprietà public (NOPA), gli accessi alle proprietà
locali (ALD), il numero delle classi importate(NIC), il numero
dei metodi di cui si è fatto override (NNOM), ecc
Figura 9 - Quality Assurance Metrics
Conclusioni
In questo articolo abbiamo introdotto alcuni concetti relativi
alla determinazione della "qualità del codice".
Abbiamo
visto poi un semplice esempio di verifica di regole base di
audit, attraverso alcuni strumenti Open Source.
Bibliografia
e riferimenti
[MOKAMET_1]
S. Rossini:Processi e metodologie di sviluppo(I)-Mokabyte
85 Maggio 2004
[BM_OOSC]B.Meyer: Object-Oriented Software Construction 2nd
Edition, Prentice Hall
[ISO9126] ISO 9126: The Standard of Reference
http://www.cse.dcu.ie/essiscope/sm2/9126ref.html
[QPS] A. Fuggetta: La qualità nei prodotti s servizi
IT
http://web.cefriel.it/~alfonso/WebBook/Documents/qualita.pdf
[CCJPL]Code Conventions for the Java Programming Language:
http://java.sun.com/docs/codeconv/
[JDTH] JavaDoc Tool Home Page: http://java.sun.com/products/jdk/javadoc/
[WKCC] http://c2.com/cgi/wiki?CodingConventions
[XP_12P] http://www.xpexchange.net/english/intro/practices.html
[XP_CS] http://www.extremeprogramming.org/rules/standards.html
[XP_CCO] http://www.extremeprogramming.org/rules/collective.html
[CHECKSTYLE] http://checkstyle.sourceforge.net
[CS_DOC] Writing checks: http://checkstyle.sourceforge.net/writingchecks.html
[PMD] http://pmd.sourceforge.net
[CODEPRO] http://www.instantiations.com/codepro/default.htm
|