Miglioramento della qualità del software con attività di refactoring

Transcript

Miglioramento della qualità del software con attività di refactoring
Scuola Politecnica e delle Scienze di Base
Corso di Laurea in Ingegneria Informatica
Elaborato finale in Ingegneria del Softwer
Miglioramento della qualità del software con
attività di refactoring
Anno Accademico 2015/2016
Candidato:
Giovanni Montanile
matr. N46/0001061
“Ai mie gentori , a
tutte le per sone che
hanno credutto in
me”
Indice
Introduzione,
Capitolo 1: Refactoring,
1.1Bad code smells,
1.2Il Modello di qualità,
Capitolo 2: Refactoring e Analisi codice sorgente,
5
7
8
10
14
2.1 Strumenti di Refactory e Analisi,
2.2 AppPerfect java code,
2.3 Esempio Calendario,
2.3.1 Test,
2.3.2 Qualità del proramma prima,
2.3.3 Attività di refactoring,
2.3.4 Test regressivo,
2.3.5 Qualità del programma dopo,
Conclusioni,
14
14
15
18
19
22
34
34
37
Bibliografia,
38
Miglioramento della qualità del software con attività di refactoring
Introduzione
Se ci ritrovassimo coinvolti nella realizzazione di un progetto software, la
qualità del codice sorgente non sarebbe certamente il primo problema al
quale rivolgeremo i nostri pensieri. Al contrario, cercheremo di rendere il
progetto funzionante, di rispettare tutte le richieste espresse dal cliente.
Testando il nostro prodotto, sarà possbile notare i numerosi errori che
sono stati compiuti a discapito della qualità del nostro codice sorgente. La
pulizia del codice dovrebbe essere, invece, un processo da utilizzare durante
la stesura del software,la fase di testing e anche dopo il completamento del
prodotto. Qualsiasi momento è buono per controllare se ciò che abbiamo
scritto rispetta le leggi della “buona progettazione” migliorando cosi la
qualità del codice sorgente.
Per fare ciò viene usata l’attivita di recfatoring che permette di riscrivere il
codice in modo manuale
o semiautomatico cercando di individuare e
eliminare i cosidetti “bad small” del codice. Tale processo migliora i
parametri
di
legibilità,
di
manutenibilità,
della riusabilità,
della
estendibilità del codice e la riduzione della sua complessità.
La refactoring, molte volte, è paragonata alla pulizia della cucina , in cui si
preparano diversi pasti al giorno per più di una manciata di persone, in
4
Miglioramento della qualità del software con attività di refactoring
genere la pulizia e la riorganizzazione si verificano continuamente, esiste
un responsabile dei piatti, delle pentole, della cucina stessa, del cibo, del
frigorifero che deve tenere tutto pulito e organizzato , senza questo si
avrebbe una cucina sporca e caotica inadeguta alla continua preparazione
dei piatti. Per esempio si pensi alla nostra casa, dove possibile vedere gli
effetti non banali di refactoring: come il non lavare le pentole subito dopo
aver cucinato il cioccolato che porta da due secondi di risciacquo a 10
minuti di raschiamento e strofinamento aggressivo.
5
Miglioramento della qualità del software con attività di refactoring
Capitolo 1: Refactoring
Il refactoring é una tecnica di ristruturazione del codice sorgente di un
sistema software che ha l’obiettivo di migliorarne la struttura interna, senza
alterarne il comportamento esterno. Essa è una tecnica sistematica per
ripulire il codice dai bad small code, riducendo al minimo le possibilità di
introdurre bug .
Esempi di refactoring sono:

sostituire un identificatore poco chiaro con uno semanticamente più
valido.

spezzare un metodo lungo in più metodi compatti.

trasformare un attributo pubblico in privato, fornendo gli opportuni
metodi di accesso.
L’attività di refactoring procede in modo sistematico applicando al codice
una sequenza di “semplici” tecniche di refactoring di base, ognuna delle
quali apporta una modifica al sistema portandolo da uno stato di partenza ad
uno stato di arrivo, preservandone il suo comportamento o perlomeno non
modificandone la conformità ai requisiti funzionali.
6
Miglioramento della qualità del software con attività di refactoring
Il problema principale legato al refactoring è il suo impatto globale sul
codice, ad esempio, se si sceglie di cambiare l’identificatore di un attributo,
dovranno essere modificate tutte le parti del codice che fanno riferimento ad
esso, dunque, se le modifiche non vengono effettuate correttamente, si
rischia di portare il codice alla regressione. In altri termini, applicando il
refactoring, si possono introdurre nel codice errori logici o sintattici che
erano originariamente assenti. Per questo motivo, dopo ogni azione di
refactoring, risulta importante effettuare un opportuno test di regressione,
in modo da individuare ed eliminare immediatamente errori eventualmente
introdotti.
Inolte si può vericare che un prodotto software può migliorare o peggiorare
la qualità del prodotto asseconda della metrica considerata. Ad esempio, se
si considera un unico metodo che con una singola scansione effettua due
operazioni su una collezione di oggetti può essere spezzato in due metodi
più chiari che effettuano le stesse operazioni ma con due scansioni differenti
, per tali ragioni si ha un miglioramento rispetto la metrica Cyclomatic
Complexity ma un peggioramento rispetto la metrica Weighted methods
per class.
1.1 Bad code smells
Il termine code smells introdotto da Kent Beck nel libro “Refactoring” ha
due significati:
7
Miglioramento della qualità del software con attività di refactoring
 Che gli smells sono subito individuabili in quanto solo guardando il
codice è possibile individuere i problemi, come trovare un metodo
che ha un numero di line di codice molto elevato.
 Che gli smells non sempre sono il problema ma indicatori di
problema.
Nome del gruppo
Gli smell in gruppo Descrizione
i Bloaters
Bloaters sono codici,
metodi e le classi che
hanno aumentato di
-Long Method
proporzioni
-Large Class
gigantesche, che sono
-Primitive Obsession difficili da lavorare. Di
-Long Parameter List solito questi smells non
affiorano subito,
-DataClumps
piuttosto si accumulano
nel tempo, come si
evolve programma
Gli abusanti
orientamento agli
oggetti
-Switch Statements
-Temporary Field
-Refused Bequest
-Alternative Classes
with Different
Interfaces
Sono quelle procedure
che non rispettano i
principi di orientameto
a oggetti
The Change
Preventers
-Divergent Change
-Shotgun Surgery
-Parallel Inheritance
Hierarchies
Questi odori significa
che se avete bisogno di
cambiare qualcosa in
un posto nel codice, è
necessario fare molti
cambiamenti in altri
posti.
i Dispensables
-Lazy class
-Data class
-Duplicate Code
Codice che è superfluo
cioè qualcosa inutile e
non necessaria la cui
8
Miglioramento della qualità del software con attività di refactoring
gli accoppiatori
-Dead Code,
-Speculative
Generality
assenza avrebbe reso il
codice più pulito, più
efficiente e più facile da
capire
-Feature Envy
-Inappropriate
Intimacy
-Message Chains
-Middle Man
Codici che
contribuiscono ad
accoppiamento
eccessiva tra le classi o
mostrano cosa succede
se l'accoppiamento è
sostituita dalla delega.
Tabella 1:Small code1
1.2 Il Modello di qualità
Lo standard più utilizzato per la descrizione di un modello di qualità del
software è lo standard ISO/IEC 9126. Esso è composto di 4 parti:
1. Quality Model: un insieme di caratteristiche di qualità che descrivono
i fattori di qualità di un prodotto.
2. External Metrics: un insieme di metriche indirette attraverso le quali
si può valutare la conformità di un prodotto in relazione all’ambiente
operativo in cui si trova.
3. Internal Metrics: un insieme di metriche applicabili al software non
eseguibile (come il codice sorgente), legate alle specifiche richieste
dall’utente, che permettono di individuare eventuali problemi nelle
metriche esterne, prima che il software sia eseguibile.
1
Mäntylä, M. V. and Lassenius, C. "Subjective Evaluation of Software Evolvability Using Code Smells: An
Empirical Study". Journal of Empirical Software Engineering, vol. 11, no. 3, 2006, pp. 395-431
9
Miglioramento della qualità del software con attività di refactoring
4. Quality In Use Metrics: un insieme di metriche, dipendenti dalle
metriche esterne ed interne, legate alle caratteristiche positive che un
utente riscontra nell’utilizzo del software.
Per determinare la qualità di un prodotto software si possono quindi
osservare tre punti di vista:
 La qualità esterna è quella rappresentata dalle prestazioni del prodotto
e dalle funzionalità che offre (il prodotto è visto come una black box da
testare).
– In sostanza, riguarda il comportamento “dinamico” del
software in un dato ambiente operativo.
– Va ricordato che il software non “funziona” mai da solo, ma è
sempre parte di un ambiente , che può contenere hardware,
persone, processi etc…
– Le caratteristiche di qualità esterne del software lo qualificano
in relazione a questo ambiente e permettono di osservarne il
comportamento mentre è utilizzato operativamente.
 La qualità interna rappresenta le proprietà intrinseche del prodotto
(quelle misurabili direttamente sul codice sorgente, sul suo flusso di
controllo). Si realizza a partire da:
– I
requisiti
di
qualità
dell'utente
(External
Quality
Requirements), che rappresentano le specifiche di qualità
così come le dà l’utente, fornendo il primo input alla
progettazione.
10
Miglioramento della qualità del software con attività di refactoring
– Le specifiche tecniche (Internal Quality Requirements), che
rappresentano la qualità richiesta dall’utente tradotta dallo
sviluppatore nell’architettura del software, nella struttura del
programma, nelle interfacce del software verso l’utente.
 La qualità in uso riguarda il livello con cui il prodotto si dimostra utile
all’utente nel suo effettivo contesto d’utilizzo, in particolare la capacità
del prodotto di dare efficacia ed efficienza al lavoro dell’utente, a fronte
di una sicurezza di utilizzo e di una soddisfazione nel far uso del
prodotto.
– In sostanza, è una misura dell’ interazione tra utente e
prodotto, in un determinato contesto d’uso.
I tre punti di vista si influenzano a vicenda, ma è ovvio che un prodotto
software percepito
positivamente dall’utente è sintomo di una buona qualità di base del codice
sorgente.
Per la misurazione della qualità
nei vari punti di vista, vegono usate
diverse metriche che sono in relazione al codice sorgente e si distinguono
in:
Nome metrica
Physical lines
Descrizione
Numero di ritorni a capo. Deve essere
un valore basso..
Numero di linee di commento. Deve
essere un valore alto.
Numero di linee di codice. Il progetto
che possiede meno righe di
codice ha un design superiore e
richiede una manutenzione minore
Numero di pacchetti.
Comment lines
Lines of code
Packages
11
Miglioramento della qualità del software con attività di refactoring
Classes
Numero di classi. Confrontando
progetti con le stesse funzionalità, il
progetto che possiede più classi è
quello che realizza l’astrazione
migliore.
Numero di files analizzati.
Numero di directories analizzate
Numero di metodi
Numero di test.
Tempo impiegato per effettuare un
test.
Numero di test falliti.
Linee coperte dal test.
Rami di un’espressione booleana
coperti (true e false).
Numero di linee duplicate
Numero di regole violate
Somma delle violazioni calcolate in
base ad un coefficiente di priorità
E’ calcolato come
[100-(weighted_violations / nloc *
100)]
E’ la posizione della classe all’interno
dell’albero di eredità. Si consiglia di
mantenere il numero dei livelli da
attraversare per giungere la radice, al
di sotto del 5.
E’ il numero di tutti i metodi
implementati da una classe più il
numero di metodi accessibili tramite
un oggetto della classe. Si
consiglia di mantenere questo numero
basso. Maggiore è la RFC, maggiore è
lo sforzo dato per apportare
modifiche.
E’ il numero delle classi che
utilizzano una classe.
E’ il numero delle classi che una
classe utilizza
Essa misura il numero di componenti
collegati ad una classe. Un valore
basso indica che il codice è semplice
da comprendere e riutilizzare. Un
valore alto suggerisce di dividere la
classe in classi più piccole. Si
consiglia di effettuare un refactoring,
Files
Directories
Methods
Unit tests
Unit tests duration
Unit test error.
Line coverage
Branch coverage
Duplicated lines
Violations
Weighted violations
Rules compliance index
Depth of inheritance tree
Response for class
Afferent couplings
Efferent couplings
Lack of cohesion of methods
12
Miglioramento della qualità del software con attività di refactoring
se questo valore diventa maggiore di
2.
E’ il numero medio di metodi
contenuti in una classe. Si consiglia di
mantenere tale numero al di sotto del
valore 14.
Essa misura il numero di cammini
linearmente indipendenti all’interno di
una parte di codice. Più il numero è
alto, più lo sforzo per effettuare un
testing del codice sarà alto. Si
consiglia di mantenere questo numero
al di sotto del valore 10.
Rappresenta la distanza dalla linea
ideale A+I=1. Identifica quanto una
categoria è lontana dal caso ideale.
Minore è la distanza del software
dalla linea, maggiore è la sua qualità.
Weighted methods per class
Cyclomatic Complexity (CC)
Distance
Tabella 2 : Metriche
13
Miglioramento della qualità del software con attività di refactoring
Capitolo 2: Refactoring e Analisi codice sorgente
Il processo di refactoring è molto difficile e lungo se si esegue con un’
analisi solo visiva
quindi é possibile trovare software che esaminano
automaticamente il codice , riuscendo ad individuare i vari “ bad smell” e
dare delle soluzioni; allo stesso modo è possibile verificare la qualità del
prodotto sia prima che dopo l’eseguzione dell’ attivita di refactoring.
Attraverso quest’ultima operazione emergeranno i vari miglioramenti o i
peggioramenti della qualità del prodotto.
2.1 Strumenti di Refactory e Analisi
Lo strumento che usereremo per la refactoring: AppPerfect java code é un
software con licenza trial, un prodotto che può essere ridistribuito con
validità di 15 giorni allo scadere di tali tempistiche per poter usufruire del
prodotto bisognerà pagare.
Per l’ analisi di qualità del codice sorgente useremo il programma: Stan4j
che é open sorce, software il cui codice sorgente è messo a disposizione di
tutti permettendone lo studio e la modifica.
Entrambi possono essere intregati ad un ulteriore programma: eclipse.
14
Miglioramento della qualità del software con attività di refactoring
2.2 AppPerfect java code
AppPerfect java code è un software di analisi statica del codice Java
progettato per eseguire i seguenti compiti fondamentali: revisione
automatica del codice java e implementazione di una corretta scrittura del
codice;
Le carateristiche fondamentali sono:
o
750 regole di buona codifica che il codice deve rispettare , suddivisi
in diverse aree funzionali come la sicurezza, l'ottimizzazione, la
portabilità, i18n, possibili errori, standard di codifica, etc.
o
Oltre
180
Correzioni
automatiche
per
le
eventuali
violazioni: Una volta che vengono rilevati errori, AppPerfect é in
grado di correggere automaticamente più di 180 tipi di violazioni. È
sufficiente rivedere e approvare le modifiche.
o
Metriche : forniscono informazioni dettagliate sui vari parametri per
il codice sorgente come il numero di linee di codice, commenti linee,
complessità di metodi, numero di metodi, ecc. Questa informazione è
di vitale importanza per la conformità codice Java.
o
Esportazione rapporti : AppPerfect Java Code Analyzer fornisce un
report che consente di individuare i problemi del codice e i suoi
parametri.
15
Miglioramento della qualità del software con attività di refactoring
2.3 Esempio Calendario
Consideriamo un semplice programma che fornendo una data in formato
giorno,in mese in caratteri
settimana
se
e anno ci restituisce il nome del giorno della
è giusta la data, altrimenti il programma restituirà un
messaggio di errore.
Il codice è il seguente
public class Calendario {
public static String calend(int d, String ms, int a)
{
int m=0;
if (ms=="gennaio")
m=1;
else if (ms=="febbraio")
m=2;
else if (ms=="marzo")
m=3;
else if (ms=="aprile")
m=4;
else if (ms=="maggio")
m=5;
else if (ms=="giugno")
m=6;
else if (ms=="luglio")
m=7;
else if (ms=="agosto")
16
Miglioramento della qualità del software con attività di refactoring
m=8;
else if (ms=="settembre")
m=9;
else if (ms=="ottobre")
m=10;
else if (ms=="novembre")
m=11;
else if (ms=="dicembre")
m=12;
if (d<1 || d>31 || m==0 || a<=1582)
return "Errore";
boolean bisestile= (a%4==0);
if (bisestile && a%100==0 && a%400!=0)
bisestile=false;
if ((m==2 && d>29)||(m==2 && d==29 &&
(!bisestile)))
return "Errore";
if ((m==4 || m==6 || m==9 || m==11) && d>30)
return "Errore";
if (m<=2)
{
m = m + 12;
a--;
};
int f1 = a / 4;
int f2 = a / 100;
int f3 = a / 400;
int f4 = (int) (2 * m + (.6 * (m + 1)));
int f5 = a + d + 1;
17
Miglioramento della qualità del software con attività di refactoring
int x = f1 - f2 + f3 + f4 + f5;
int k = x / 7;
int n = x - k * 7;
if (n==1)
return "Lunedi";
else if (n==2)
return "Martedi";
else if (n==3)
return "Mercoledi";
else if (n==4)
return "Giovedi";
else if (n==5)
return "Venerdi";
else if (n==6)
return "Sabato";
else if (n==0)
return "Domenica";
else
return "Errore";
}
2.3.1 Test
Per testare le funzionalità del codice useremo tool di eclipse junit, che ci
permette di testare
il codice in maniera
automatica
inserendo i vari
ingressi sia corretti che sbagliati, confrontandoli con i risultati che ci
aspetteremo di ricevere rispetto all’ ingresso inserito. Questo stesso test lo
utilizeremo come rigressione del programma dopo l’attivita di refactoring;
18
Miglioramento della qualità del software con attività di refactoring
così andremo a verificare se le funzionalità del proramma sono ancora
valide.
Eseguimo il test:
Figura 1: Test prima
Da cio si può vedere che i vari test sono andati tutti a buon fine.
2.3.2 Qualità del proramma prima
Analiziamo il programma prima dell’ attivita di refactoring tramite il
plugin open sorce stan4j che ci permette di verificare tutte le connessioni
tra metodi, le varie metriche fondamentali e le varie violazioni del
programma .
19
Miglioramento della qualità del software con attività di refactoring
 Composition View
La Composition View di questo progetto
mostra
che
esso
è
composto
semplicemente da un pacchetto, in cui ci
sono due classi
quella TestBlackBox
composta da 22 metodi che
Figura 2 : Composition View
invocano
l‘unica funzione della classe Calendario:
la funzione calend(…).
 Metriche
Stan4j copre un elevato numero di metriche. Le più interessanti per la
nostra analisi sono quelle che ci consentono di individuare eventuali
violazioni.
 Violazioni
Metric
calendario.Calendario.calend(...)
calendario.Calendario.calend(...)
Nel
Value
CC
39
ELOC
98
nostro caso abbiamo 39 violazioni nella metrica Cyclomatic
Complexity e 98 violazioni nel Estimated Lines of Code.
Visualiziamo il rapporto delle metriche
20
Miglioramento della qualità del software con attività di refactoring
Metric
Value
Number of Libraries
2
Number of Packages
1
Number of Top Level Classes
2
Average Number of Top Level Classes per Package
2
Average Number of Member Classes per Class
0
Average Number of Methods per Class
Average Number of Fields per Class
Estimated Lines of Code
12.50
0
189
Estimated Lines of Code per Top Level Class
Average Cyclomatic Complexity
94.50
2.52
Fat for Library Dependencies
0
Fat for Flat Package Dependencies
0
Fat for Top Level Class Dependencies
1
Tangled for Library Dependencies
0%
Average Component Dependency between Libraries
0%
Average Component Dependency between Packages
0%
Average Component Dependency between Units
21
50%
Miglioramento della qualità del software con attività di refactoring
Average Distance
0
Average Absolute Distance
0
Average Weighted Methods per Class
31.50
Average Depth of Inheritance Tree
1
Average Number of Children
0
Average Coupling between Objects
1
Average Response for a Class
Average Lack of Cohesion in Methods
22
13
126.50
Miglioramento della qualità del software con attività di refactoring
2.3.3 Attivita di refactoring
Analiziamo ora il codice del sorgente tramite il programma AppPerfect
Java code test , é un plugin di eclipse che viene visualizzato in questo
modo:
Figura 3: AppPerfect Java code
Violazioni
Il programma elenca le violazioni, che non rispettano le regole imposte per
relizzare l’analisi, le quali sono state trovate nel file Java . Viene inoltre
visualizzato il numero di riga in cui sono state osservate queste
violazioni. Se un numero di riga viene cliccato, apre il file in editor di
Eclipse con dato numero di riga evidenziata. Il menu pop-up contiene le
opzioni di correzione automatica o ignora le violazioni.
Auto-fix è la caratteristica in cui AppPerfect CodeTEST altera il
codice
sorgente per risolvere le violazioni.
Ignora
o una singola o tutte
le
violazioni di quel tipo, diventando
sospesa. Le Violazioni che sono sospese
23
possono essere riattivate
Miglioramento della qualità del software con attività di refactoring
successivamente, in modo da riportarle indietro nella vista violazioni.
Violazioni sospese
Questo punto di vista elenca le violazioni che sono state sospese. Menu
pop-up della vista contiene le opzioni per riattivare le violazioni sospese.
Una volta riattivate le violazioni ritornano di nuovo nelle finestra delle
violazioni.
Violazioni Auto risolvibili
Questo punto di vista è un sotto-insieme della vista violazioni. La finestra
violazioni auto risolvibili elenca solo quelle violazioni che possono essere
risolte automaticamente dal AppPerfect CodeTEST. Menu pop-up della
vista. Contiene le opzioni per auto-fix che permette di visionare la soluzine
per risolvere quel tipo di violazione.
Metrica
Essa mostra le Metriche statiche raccolte durante l'analisi:
 Classes Metrics numero di classi nel progetto,nei singoli
packages.
 Class wise Blank Lines numero di righe vuote in singole
classi.
 Class wise Commented Lines Commentate mostra il numero
di righe di codice commentato nei singole classi.
24
Miglioramento della qualità del software con attività di refactoring
 Method Complexity conta complessità del metodo , come il
numero totale di - if, for, while, do and switch che compaiono
nel corpo del metodo. Questo aiuta a identificare i metodi che
sono troppo complessi. Si può prendere in considerazione la
rottura di un metodo troppo complesso in più metodi con
minore complessità.
 Method Parameters numero di parametri dei singoli metodi
 Method numero di metodo per classe.
 Nested Block Depth numero massimo nidificazione che si
trovano in un metodo.
 Non-static attributes numero di attributi non statici per
classe.
 Static attributes numero di attributi statici per classe.
 Total Lines numero totale di linee.
Sintesi del progetto
Questo punto di vista ha due schede:
- Violazioni di Gravità.
- Violazioni Categoria.
25
Miglioramento della qualità del software con attività di refactoring
Tramite grafico a torta che fornisce rapidamente un quadro chiaro di
distribuzione di violazioni tra le categorie e gravità.
I problemi
Vista Problemi fornisce informazioni su gli errori di sintassi nel codice.
Esportazione Risultati
Una volta che l'analisi del codice è eseguito su progetto e diversi punti di
vista sono visibili come spiegato sopra, è possibile esportare questo punto di
vista in formati multipli.
Regole
Le regole che deve rispettare il codice sono organizzate dal AppPerfect
Role Manager per gravità : Critical, High, Low, Medium a loro volta
sono sudivise in categorie :
1. Optimization
2. OOPs
3. Garbage Collection
4. Code Convention
5. EJB
6. Security
7. Unused Code
8. Internationalization
9. Metrics
10. JSP Metrics
26
Miglioramento della qualità del software con attività di refactoring
11. Portability
12. 64 bits
13. Possible Errors
14. Java Docs
15. JSP
16. JUnit
17. Naming Convention
18. Servlet Rules
19. J2ME
20. Struts
21. Hibernate
Tramite la guida é possibile
visionare queste regole
esempi e soluzioni.
27
con gli appositi
Miglioramento della qualità del software con attività di refactoring
Selezioniamo le regole che deve sodisfare il programma:
Figura 4: AppPerfect Rule Manager
28
Miglioramento della qualità del software con attività di refactoring
Analiziamo il programma rispetto a queste regole che abbiamo imposto,
come quelle appartenenti alla categoria delle metrics e otteniamo questo:
Figura 5: Report violazione codice AppPerfect
Su questo rapporto é possibile vedere che il programma ha 111 linee di
codice che violano le regole che abbiamo stabilito in precedenza .
Per ciasuna regola vediamo come fare la refactoring, dove alcune sono
risolte automaticamente dal programma come:

Use_Equals_Instead_Equality_Operator
Ci
viene
l’operatore
sugerito
di
sostituire
== con la funzione il
metodo equals(“ ” ) della classe
String
Figura 6: Auto-fix
user_Equals_Instead_Equality_Operator
29
Miglioramento della qualità del software con attività di refactoring

Avoid_string_literals_except_in_constant_declarations
Viene suggerito di convertire la
stringa di carattere in una variabile
costante in tutte le sue occorenze
Figura7: Auto-Fix
Avoid_string_literals_except_in_constant_dec
larations

Avoid_duplicate_string_literals
Perchè viene usata una stringa di
carattere più volte, viene suggerito
di convertire la stringa in una
variabile costante
le occorenze
Figura 8: Auto-Fix
Avoid_duplicate_string_literals
30
e con essa tutte
Miglioramento della qualità del software con attività di refactoring
Altre hanno soluzioni tramite la guida con i rispettivi esempi e sugerimenti

Maximum_number_of_return_statements
Segnala la presenza di un grande numero di istruzioni return che
aumentano la complessità del codice .
public class MyClass
{
public boolean isNull ( Object s ) // VIOLATION
{
if ( s == null )
{
return true;
}
return false;
}
}
Soluzione
public class MyClass
{
public boolean isNull ( Object s) // CORRECTION
{
return s == null ? true : false;}}
sostituendo i vari return con un unico return.

Maximum_complexity
Indica che la complessità del programma, viene suggerita la divisione in più
metodi quindi si va a estrarre pezzi di codice ricavando nuovi metodi
tramite la funzionalità Extract Method notiva di eclipse.

Maximum_number_of_nested_control_statements
31
Miglioramento della qualità del software con attività di refactoring
Indica la presenza di if nidificati che aumenta la complessità del codice.La
soluzione di questo problema é la creazione di un metodo
nidificazioni vengono implementate come un ruten unico;
prendiamo il codice del genere presente nel metodo:
int m=0;
if (ms=="gennaio")
m=1;
else if (ms=="febbraio")
m=2;
else if (ms=="marzo")
m=3;
else if (ms=="aprile")
m=4;
else if (ms=="maggio")
m=5;
else if (ms=="giugno")
m=6;
else if (ms=="luglio")
m=7;
else if (ms=="agosto")
m=8;
else if (ms=="settembre")
m=9;
else if (ms=="ottobre")
m=10;
else if (ms=="novembre")
m=11;
else if (ms=="dicembre")
32
dove le
Miglioramento della qualità del software con attività di refactoring
m=12;
si costruisce una funzione di questo genere :
private static int mesestring2num(String ms) {
return ms.equals(GENNAIO)?
1:
ms.equals(FEBBRAIO)?
2:
ms.equals(MARZO)?
3:
ms.equals(APRILE)?
4:
ms.equals(MAGGIO)?
5:
ms.equals(GIUGNO)?
6:
ms.equals(LUGLIO)?
7:
ms.equals(AGOSTO)?
8:
ms.equals(SETTEMBRE)?
9:
ms.equals(OTTOBRE) ?
10:
ms.equals(NOVEMBRE)?
11:
ms.equals(DICEMBRE)?
12:0 ;
}
33
Miglioramento della qualità del software con attività di refactoring
Dopo l’attivita di refactoring il codice si sarà trasformato in questo:
public static String calend(int d, String ms, int a)
{
int m = mesestring2num(ms);
return verifica(d, a, m)? giorno(d, a, m):ERRORE;
}
private static boolean verifica(int d, int a, int m) {
boolean bisestile= (a%4==0);
if (bisestile && a%100==0 && a%400!=0)
bisestile=false;
return !( d<1
|| d>31
|| m==0
|| a<=1582
||(m==2 && d>29)
||(m==2 && d==29 && !bisestile)
||(m==4 || m==6 || m==9 || m==11) && d>30);
}
34
Miglioramento della qualità del software con attività di refactoring
private static String giorno(int d, int a, int m) {
int n = numgiorno(d, a, m);
return
n==1 ? LUNEDI:
n==2 ? MARTEDI:
n==3 ? MERCOLEDI:
n==4 ? GIOVEDI:
n==5 ? VENERDI:
n==6 ? SABATO:
n==0? DOMENICA:
ERRORE;
}
private static int numgiorno(int d, int a, int m) {
if (m<=2)
{
m = m + 12;
a--;
}
int f1 = a / 4;
int f2 = a / 100;
int f3 = a / 400;
int f4 = (int) (2 * m + (.6 * (m + 1)));
int f5 = a + d + 1;
int x = f1 - f2 + f3 + f4 + f5;
int k = x / 7;
int n = x - k * 7;
35
Miglioramento della qualità del software con attività di refactoring
return n;
}
private static int mesestring2num(String ms) {
return ms.equals(GENNAIO)?
1:
ms.equals(FEBBRAIO)?
2:
ms.equals(MARZO)?
3:
ms.equals(APRILE)?
4:
ms.equals(MAGGIO)?
5:
ms.equals(GIUGNO)?
6:
ms.equals(LUGLIO)?
7:
ms.equals(AGOSTO)?
8:
ms.equals(SETTEMBRE)?
9:
ms.equals(OTTOBRE) ?
10:
ms.equals(NOVEMBRE)?
11:
ms.equals(DICEMBRE)?
36
Miglioramento della qualità del software con attività di refactoring
12:0 ;
}
}
2.3.4 Test regressivo
Ritestiamo il codice con gli stessi ingressi provati in precedenza sempre
tramite junit, per verificare se l’attivita di refactoring
ha portato
cambiamenti di funzionalità al programma eseguiamo il test e otteniamo :
Figura 9: Test di rigressione
Con questa verifica ci permette di affermare che pur apportando modifiche
al codice tramite attività di refactoring le funzionalità del programma non
hanno subito alcuna modifica.
37
Miglioramento della qualità del software con attività di refactoring
2.3.5 Qualità del programma dopo
Riseguendo il programma con il pluing stan4j andiamo a visionare se ci
sono stati cambiamenti di qualità rispetto a violazioni e alle metriche
visionate in precedenza:
Violazioni
Artifact
Metric
CC
Calendario.Calendario.verifica(...)
Value
19
Da ciò é possibile notare, come le violazioni sono diminuite per la metrica
Cyclomatic Complexity e scomparse per quelle Estimated Lines of Code
pure se il valore 19 sarebbe un pò alto in quanto esso dovrebbe essere
minore
di 10. Rapportandolo all’ analisi precedente abbiamo un netto
miglioramento,in quanto ora si trova in una zona intermedia indicata con il
giallo tra 10 e 20. Precedentemente la metricaCyclomatic Complexity si
trovava in una zona rossa indicando una complessità peggiore.
visioniamo le altre metriche:
Metric
Value
Number of Libraries
1
Number of Packages
1
Number of Top Level Classes
2
Average Number of Top Level Classes per Package
2
Average Number of Member Classes per Class
0
Average Number of Methods per Class
14.50
Average Number of Fields per Class
10
38
Miglioramento della qualità del software con attività di refactoring
Estimated Lines of Code
223
Estimated Lines of Code per Top Level Class
111.50
Average Cyclomatic Complexity
2.34
Fat for Library Dependencies
0
Fat for Flat Package Dependencies
0
Fat for Top Level Class Dependencies
1
Tangled for Library Dependencies
0%
Average Component Dependency between Libraries
0%
Average Component Dependency between Packages
0%
Average Component Dependency between Units
50%
Average Distance
0
Average Absolute Distance
0
Average Weighted Methods per Class
34
Average Depth of Inheritance Tree
1
Average Number of Children
0
Average Coupling between Objects
1
Average Response for a Class
15
Average Lack of Cohesion in Methods
126.50
Mettendo a confronto le due tabelle
si evince un miglioramento nel
Cynclomatinc complexity, ma un pò di peggioramento secondo la mertrica
di weighted methods per class in quanto sono aumentati i metodi nella
classe.
39
Miglioramento della qualità del software con attività di refactoring
Conclusioni
Come visto dall’ esempio l’attivita di refatoring e quindi la pulizia del
codice oltre a un miglioramento della Cynclomatinc complexity cioè una
diminuzione della complessità del codice; ci ha permesso di dividere un
codice monolitico in più metodi rendendo cosi più leggibile, più facile da
interpetrare,
più semplice da modificare per eventuali interventi di
manutenzione che rappresentano la parte più costosa dell’intero progetto.
Una buona pulizia del codice permette non solo a chi scrive il programma di
lavorare più aggevolmente, ma soprattutto a chi lavora in un team di
comprendere ciò che l’autore del codice vuole fare. Ciò riduce il tempo di
interpetazione del codice e aumenta quello di sviluppo. Una buona pulizia
del codice
permette
di avere un programma molto più performante,
riusabile, manutenibile.
L’attivita di refatoring però, presenta anche degli effetti negativi. Se si
cerca di migliorare il programma rispetto a una qualità può verificarsi la
diminuzione di un’ altra come ad esempio la creazione di più metodi
partendo da uno. Attraverso questa operazione aumenta la leggibilità del
codice, contemporaneamente aumentano le interconnesioni tra metodi.
40
Miglioramento della qualità del software con attività di refactoring
D’altrocanto non si deve esagerare con la refatoring in quanto, un uso
estremo di questa attività, può causare degrado delle funzionalità del codice
e quinidi si é obligati dopo l’intervento di refactoring di fare un test di
regressione .
In fine é bene fare l’attivita di pulizia con estrema attenzione , poichè
un‘eccessiva pulizia del codice puo’ danneggiare le funzionalità del
programma.
41
Miglioramento della qualità del software con attività di refactoring
Bibliografia
 Mäntylä, M. V. and Lassenius, C. "Subjective Evaluation of
Software Evolvability Using Code Smells: An Empirical Study".
Journal of Empirical Software Engineering, vol. 11, no. 3, 2006, pp.
395-431.
 Stan4j, “http://stan4j.com/”
 AppPerfect java code, “http://www.appperfect.com/products/javacode-test.html”
 Martin Fowler “www.refactoring.com.”
 C.Ghezzi, M. Jazayeri, D. Mandrioli; Ingegneria del Software.
Fondamenti e principi, seconda edizione. Pearson
42