Validare il codice Java

Preveniamo lo spaghetti codedi

Perchè validare il codice? Per semplificare la vita degli sviluppatori e prevenire una serie di problemi che possono compromettere la nostra applicazione. Come validarlo? Con quali regole? Con quali strumenti? Applicare in modo corretto le regole di codifica non è solo una questione di qualità fine a sè stessa.

Introduzione

Se è vero che scrivere codice che funzioni non è la cosa più semplice del mondo (soprattutto se deve fare esattamente quanto richiesto dall‘utente?..), scrivere codice che oltre a ciò sia anche di qualità  è decisamente più complesso. Forse anche per questo, in seguito alla enorme popolarità  di Java, si è ben presto diffusa anche una serie di regole su "come scrivere Java a regola d‘arte". Già , ma come districarsi tra queste "regole d‘arte", che sono numerose e di non sempre immediata applicazione? Per non parlare poi della necessità  di poter disporre di strumenti che ci aiutino ad applicarle e che ci forniscano un reale valore, facendoci risparmiare davvero tempo e denaro durante le fasi dello sviluppo e della manutenzione. In questo articolo analizzeremo un pò più da vicino la questione della qualità  del codice, esaminando il come e perchè esistono le regole di codifica, con uno sguardo anche a come sia possibile applicarle traendone beneficio. Col minimo sforzo, possibilmente!

Perchè validare il codice?

Come nelle migliori storie di Java, tutto comincia a casa Sun Microsystems, e stavolta sul suo sito web, che tanto per toglierci ogni dubbio sulla utilità  delle "regole di codifica", dedica loro una sezione apposita ([1]), dicendo testualmente che rispettarle è di fondamentale importanza per qualsiasi sviluppatore, e ciò in quanto:

  • la manutenzione costa mediamente quattro volte più dello sviluppo (la ben nota regola del 20-80%)
  • è molto complesso manutenere il software anche da parte di chi lo ha scritto
  • le regole di codifica migliorano la leggibilità , permettendo a chi sviluppa di comprendere meglio e più rapidamente dove e come inserire codice ulteriore

Persuasi del fatto che validare il codice secondo regole è utile e necessario, ci si chiede: e adesso, da dove incominciamo?

Quali riferimenti?

Una trattazione completa ed esaustiva delle regole di scrittura del codice Java si può trovare, sempre a cura di Sun Microsystems, nel testo [2], scaricabile in formato pdf. Non mancano nella letteratura numerosi altri importanti riferimenti, quali il testo fondamentale [3], di importanza vitale per comprendere cosa significa scrivere codice Java in modo efficace, ma anche [4], in cui il focus viene spostato in particolare sulla prevenzione dei problemi di memoria. Nei suddetti riferimenti, vengono illustrate e discusse numerose regole per evitare alcuni errori che tipicamente si commettono nello scrivere codice Java, legati all‘uso improprio di determinati costrutti, all‘abuso più che all‘uso di certi elementi sintattici, alla corretta a appropriata scelta di alcuni statement piuttosto che altri.
Tali regole vengono suddivise in gruppi, distinti a seconda del problema che provocano se vengono violate, e precisamente:

  • Correttezza. violare le regole di tale categoria causa con ogni probabilità  dei bug, e il codice non farà  ciò che ci si aspetta
  • Progettazione. regole conformi ai principi dell‘object oriented programming (OOP). Si tratta di regole molto più eficaci se applicate al codice da scrivere ex-novo piuttosto che pre-esistente. Violazioni ad esse possono portare con ogni probabilità  a bug quando il codice esistente venga modificato e/o esteso
  • Performance. regole che se violate possono portare a problemi in termini di velocità , memoria, utilizzo risorse

Successivamente, le violazioni registrate a tali regole vengono raggruppate secondo coefficienti di "severità ", e precisamente:

  • Elevato. La violazione può portare a errori a tempo di esecuzione, problemi di performance o evidenziare gravi difetti a livello progettuale
  • Medio. La violazione può causare problemi, ma ci sono diverse circostanze valide in cui l‘applicazione della regola in questione può essere ignorata
  • Basso. La violazione può impattare sulla manutenibilità  del codice ovvero essere sintomo della mancata applicazione di una "best practice", ossia di una metodologia che migliorerebbe di molto la qualità  complessiva di quanto prodotto

Chiarito il fatto che la documentazione inerente le regole di codifica esiste ed è abbondante, guardiamoci intorno per vedere se esistono strumenti che le supportano e come possono eventualmente aiutarci nel nostro lavoro.

Open Source!

Una prima risposta viene, come spesso accade, dalle community di Open Source. Esse ci mettono a disposizione diversi interessanti strumenti, adatti proprio allo scopo che stiamo trattando, come ad esempio CHECKSTYLE, presentato e descritto in [5]. Nel presente articolo, daremo un‘occhiata da vicino a PMD ([6]), che ci offre la possibilità  di "attraversare" letteralmente un insieme di codice Java identificando i potenziali problemi rilevati. Quali problemi? Ad esempio la presenza di blocchi di codice try/catch/finally/switch vuoti, variabili locali o metodi dichiarati come private che risultino inutilizzati, ovvero ancora espressioni ecccessivamente complesse, ad esempo a causa di numerose statement if annidate. Sempre sul medesimo riferimento [6] è possibile consultare la lista delle regole che PMD supporta, un elenco davvero completo ed esaustivo, che comprende anche regole di complessità  ciclomatica (McCabe).
L‘interfaccia di PMD è abbastanza semplice ed intuitiva, e permette anche di comprendere come PMD agisca in pratica quando deve analizzare un blocco di codice.
Alla maniera dei compilatori infatti, PMD costruisce un "albero sintattico" degli elementi di codice che processa. Tale albero, denominato AST (Abstract Syntax Tree), contiene la struttura del codice in esame, suddivisa in parti aventi ciascuna un ben determinato significato. E‘ proprio su questa struttura e sugli elementi che contiene che PMD effettua poi la sua analisi.
A titolo di esempio, può essere curioso vedere come PMD costruisca il proprio AST proponendogli il frammento di codice Java forse più famoso del mondo, il celeberrimo "Hello World".

Come procedere adesso?

Leggendo con attenzione la documentazione di PMD, magari incuriositi da quella finestra denominata "XPath" che compare nella figura 1 vista più sopra, si scopre che XPath non è altri che un linguaggio formale che permette di definire le proprie "custom rules" (qualora quelle già  supportate da PMD non dovessero bastare?..) e salvarle in un formato XML completamente compatibile con la sintassi presente nelle regole già  esistenti nel repository di PMD.

A questo punto, tutto quello che andrà  fatto sarà  di invocare PMD "passandogli" come parametri la dislocazione del nostro codice da processare, nonchè la dislocazione del "ruleset", ovvero del repository contenente le diverse regole secondo cui analizzare il codice stesso, eventualmente "puntando" a un differente "ruleset", contenente le nostre regole personalizzate. Il tutto espresso nella semplice chiamata (da linea di comando):

pmd.bat c:path	omysrc xml c:path	omycustomrules.xml

Non è questa la sede per discutere in modo approfondito della sintassi del linguaggio formale XPath, per la quale si rimanda ai riferimenti citati in bibliografia ([7] e [8]). Qui intendiamo comunque osservare che si tratta di un mezzo potente ed espressivo per poter "implementare" in modo efficace e relativamente veloce le proprie regole di codifica, salvo averle a disposizione in modo immediato per verificarle nel codice Java da analizzare. E se oltre alle regole di PMD potessimo avere anche la possibilità  di verificare sul codice quelle definite da Sun e presentate più sopra (le "effective Java", tanto per intenderci)? Vediamo un esempio concreto leggermente più significativo di "Hello World"?.

Un esempio pratico

Scegliamo una applicazione tipica e anche ben nota nel mondo Java, e cioè JMeter ([9]), e poniamoci il problema di verificare quante e quali violazioni sono presenti all‘interno del suo codice, e di quale categoria tra quelle disponibili e selezionate a priori.

Utilizziamo lo strumento Compuware OptimalAdvisor ([10]) e costruiamo come prima cosa il "design model" di JMeter in notazione UML (fig. 2).

Visitando la "tab page" corrispondente alle regole di codifica, notiamo che abbiamo la possibilità  di impiegare tanto le regole prescritte da Sun (presentate nei primi paragrafi e relative alla efficacia del codice Java), quanto tutte quelle supportate da PMD.
Per ciascuna di esse, in particolare, abbiamo a disposizione una "finestra" che ne illustra il significato e l‘utilizzo (v. fig. 4). Si noti, nella figura citata, anche la possibilità  di definire le proprie regole di validazione invocando un apposito wizard che le memorizza poi in formato XML secondo quanto previsto dalla sintassi XPath (bottone "New" in basso nella fig. 3)

A questo punto è sufficiente ricorrere al cosiddetto "Rule Filter" per selezionare, tra tutte le regole di validazione disponibili - e cioè sia le PMD, sia le "effective Java" - quelle secondo cui si intende analizzare il nostro codice.

Con un click sul bottone "OK", il codice applicativo in esame viene analizzato, e le violazioni individuate vengono immediatamente evidenziate in un apposito report, suddivise secondo "severity", come più sopra specificato. Nella figura 5 si immagina di aver voluto verificare quante violazioni alle regole di correttezza erano state rilevate in JMeter. Si noti, sempre in figura 5, la possibilità  di esportare in diversi formati il report cosଠottenuto

Desideriamo ottenere informazioni più approfondite sulle diverse violazioni riscontrate sul codice? Nella figura 6 sono state visualizzate le violazioni più gravi (severity = high) e si può notare come vengano evidenziate direttamente sulla riga "colpevole" nel codice sorgente, fornendo anche una traccia documentale del tipo di violazione riscontrata e di alcuni dei possibili workaround per eliminare il problema.

Conclusioni

Perchè validare il codice? Perchè un codice scritto "a regola d‘arte" è più facile e meno costoso da manutenere, sia per noi che lo abbiamo sviluppato, sia per coloro che un giorno lo prenderanno in carico....Esiste una quantità  di regole, norme, prescrizioni, metodologie e best practice, basta cercare - magari iniziando a casa Sun - e si trova ampia documentazione. Ma nessun ricettario potrà  mai farci diventare grandi cuochi, perchè occorre una naturale (e notevole) predisposizione e tanta esperienza. Chi può aiutarci allora? Per nostra fortuna, le community di Open Source - ma non soltanto - offrono diversi strumenti che permettono di analizzare il nostro codice, anche secondo insiemi preselezionati ovvero personalizzati di regole, e di produrre le relative reportistiche, in vari formati e spesso di qualità . Non dobbiamo cadere nella tentazione di scrivere codice e basta, uno sguardo attento alla qualità  di ciò che produciamo o analizziamo oggi costituisce un investimento sulla efficienza e sul valore di domani.

Riferimenti bibliografici

[1]
SUN Microsystems, "Code Conventions for the Java Programming Language"
http://java.sun.com/docs/codeconv/

[2]
Achut Reddy, "Java Coding Style Guide", SUN Microsystems
http://java.sun.com/docs/codeconv/

[3]
Joshua Block, "Effective Java Programming Language Guide", SUN Microsystems
http://java.sun.com/docs/books/effective/

[4]
William Pugh, "The Java Memory Model is Fatally Flawed", University of Maryland
http://www.cs.umd.edu/~pugh/java/broken.pdf

[5]
"Qualità  del software",
http://www.mokabyte.it/2004/11/auditing.htm

[6]
PMD official website
http://pmd.sourceforge.net/

[7]
XPath Tutorial
http://pmd.sourceforge.net/xpathruletutorial.html

[8]
Tom Copeland "Custom PMD Rules"
http://www.onjava.com/pub/a/onjava/2003/04/09/pmd_rules.html

[9]
JMeter, Apache Community
http://jakarta.apache.org/jmeter/

[10]
Compuware OptimalAdvisor
http://javacentral.compuware.com/products/optimaladvisor/documentation/v3.1/1820-20-15-0-32.html
http://www.compuware.com/products/optimalj/2911_ENG_HTML.htm

Condividi

Pubblicato nel numero
99 settembre 2005
Doriano Gallozzi è nato a Roma nel 1964 e si è laureato in Ingegneria Elettronica (indirizzo Informatica) nel 1989. Da sempre interessato a problematiche di analisi, progettazione e sviluppo di Sistemi Informativi, ha lavorato per diversi anni in aziende del settore informatico italiano (gruppo ENI, gruppo Telecom Italia), dove ha…
Ti potrebbe interessare anche