CCN
CCN
Ο αριθμός κυκλοματικής πολυπλοκότητας CCN είναι μια από τις παλιότερες μετρικές πολυπλοκότητας. Για πρώτη φορά αυτή η μετρική αναφέρθηκε από τον J. McCabe το 1975. Η μετρική αυτή μετρά τα διαθέσιμα μονοπάτια αποφάσεων σε ένα τμήμα πηγαίου κώδικα για να βρει την πολυπλοκότητα του. Κάθε μονοπάτι απόφασης αρχίζει με ένα statement από αυτά της παρακάτω λίστας, συνεπώς είναι σχετικά εύκολο να ανιχνευθούν στον πηγαίο κώδικα.
?
case
elseif
for
foreach
if
while
Παρατηρούμε ότι από τη λίστα λείπουν τα else και τα default. Γίνεται η υπόθεση ότι αυτά τα statement περιέχουν την εξ ορισμού διαδρομή εκτέλεσης του προγράμματος που ήδη υπάρχει και συνεπώς δεν υπάρχει ειδική περίπτωση.
Κάθε μονοπάτι απόφαση παίρνει την τιμή 1 και το άθροισμα όλων των τιμών εκφράζει τo CCN του αναλυόμενου τμήματος κώδικα. Σημειώνουμε ότι κάθε συνάρτηση και μέθοδος επίσης παίρνει την τιμή 1. Με τα παραπάνω υπολογίζουμε την πολυπλοκότητα του παρακάτω παραδείγματος:
NEED TO FINISH FORMATING THIS EXAMPLE
CCN | |
class CyclomaticComplexityNumber | 0 |
{ | 0 |
public function exampe( $x, $y ) | 1 |
{ | 0 |
if ( $x > 23 || $y < 42 ) | 1 |
{ | 0 |
for ( $i = $x; $i >= $x && $i <= $y; ++$i ) | 1 |
{ | 0 |
} | 0 |
} | 0 |
else | 0 |
{ | 0 |
switch ( $x + $y ) | 0 |
{ | 0 |
case 1: | 1 |
break; | 0 |
case 2: | 1 |
break; | 0 |
default: | 0 |
break; | 0 |
} | 0 |
} | 0 |
} | 0 |
file_exists(‘/tmp/log’) or touch(‘/tmp/log’); | 0 |
} | 0 |
– | 5 |
Βασισμένοι στα παραπάνω η μετρική CCN του παραδείγματος είναι 5. Παρατηρήστε όμως ότι αυτή η προσέγγιση δεν πιάνει όλα τα μονοπάτια απόφασης. Δεν έπιασε τα μονοπάτια που προκύπτουν από τη λογική έκφραση || στη γραμμή 8 και && στη γραμμή 10 και το λογική έκφραση OR στη γραμμή 27. Μια παραλλαγή του CCN που καλύπτει και αυτά τα μονοπάτια ονομάζεται CCN2. Η CCN2 είναι ο ποιο ευρέως χρησιμοποιούμενος από αυτές τις μετρικές. Εργαλεία όπως το PHPUnit, PMD και το CheckStyle την αναφέρουν ως Κυκλοματική Πολυπλοκότητα του αναλυόμενου τμήματος κώδικα.
Αν εφοαρμόσουμε την μετρική CCN2 στο προηγούμενο παράδειγμα, παίρνουμε την τιμή 8, που σημαίνει αύξυση της πολυπλοκότητας κατά 60%.
Ο CCN αρχικά δημιουργήθηκε για procedural γλώσσες προγραμματισμού, αυτός ο ορισμός του ακόμη δεν περιλαμβάνει ένα στοιχείο για την μέτρηση της πολυπλοκότητας σε ένα αντικειμενοστραφή κώδικα. Με την έννοια των εξαιρέσεων το λογισμικό προσλαμβάνει ένα ακόμη μονοπάτι απόφασης για κάθε catch που χρησιμοποιήτε στον κώδικα. Το try που περιέχει τον κώδικα για την κανονική διαδρομή εκτέλεσης, είναι όπως το else και το default.
?
&&
||
or
and
xor
case
catch
elseif
for
foreach
if
while
Τι μπορούμε να κάνουμε με την CCN; Μπορούμε να εντοπίσουμε σημεία αυξημένης πολυπλοκότητας σε ένα σύστημα, για παράδειγμα τα δέκα στοιχεία μεγαλύτερης πολυπλοκότητας. Αλλά αυτό είναι χρήσιμο για την αρχικό έλεγχο ενός συστήματος. Για την συνεχή ανάλυση απαιτούνται κατώφλια που θα μας βοηθήσουν να κατηγοριοποίησουμε τις υπολογιζόμενες τιμές. Από την πράξη έχουν προκύψει τα παρακάτω: ΑΝΑΦΟΡΑ?
Ένα τμήμα λογισμικό με τιμή CCN μεταξύ 1-4 έχει μικρή πολυπλοκότητα
Τιμή μεταξύ 5-7 είναι μέτρια και ο κώδικας είναι ακόμη δυνατό να κατανοηθεί
Μεταξύ 6-10 έχει μεγάλη πολυπλοκότητα και πάνω από 10 είναι πολύ πολύπλοκο και δύσκολο να κατανοηθεί.
Το όφελος της μετρικής αυτής ποιο είναι;
Τα πολύπλοκα κομμάτια μιας εφαρμογής συνήθως περιέχουν την επιχειριματική λογική. Αλλά η πολυπλοκότητα έχει αρνητικό αντίκτυπο στην αναγνωσιμότητα και κατανόηση του πηγαίου κώδικα. Αυτά τα τμήματα είναι πηγές σφαλμάτων και δυσχέριας στην συντηρηση τους γιατί κανείς δεν θα καταλαβαίνει πλήρως τις συνθήκες, τις παρενέργειες στο συστημα και γενικώς τις συμβαίνει εκεί. Από αυτή την κατάσταση φτάνουμε συνήθως στο “Never touch a running system”. Η κατάσταση μπορεί να γίνει ακόμη πιο κρίσιμη αν ο αρχικός προγραμματιστής φύγει από την ομάδα ανάπτυξης.
Ο Glover προτείνει ότι για κάθε μονάδα του CCN πρέπει να υπάρχει και ένα unit test για να καλυφθεί κάθε μονοπάτι αποφάσεων. Επειδή αυτό δεν είναι εφικτό, για παράδειγμα για μια μέθοδο με CCN=22 πρέπει να γραφτούν 22 unit tests!! Για πολλούς λόγους δεν είναι δυνατό να γίνει. Άρα η ευκολότερη λύση είναι να κάνουμε refactoring ώστε να μειωθεί η πολυπλοκότητα.
IEEE Transactions on Software Enginerring; A Complexity Measure; Thomas J. McCabe; 1976
http://www.literateprogramming.com/mccabe.pdf
Code Improvement Through Cyclomatic Complexity, Andrew Glover
http://www.onjava.com/pub/a/onjava/2004/06/16/ccunittest.html?page=1 13/9/2013
Bergman σελ 259 λέει ότι μέχρι 10 είναι καλά, από εκεί και πάνω χαλάει.