Che cosa significa la "complessità ciclomatica" del mio codice?

37

Sono nuovo nell'analisi statica del codice. La mia applicazione ha una complessità ciclomatica di 17.754. L'applicazione stessa è solo 37,672 linee di codice. È valido dire che la complessità è alta in base alle linee di codice? Che cosa mi sta dicendo esattamente la complessità ciclomatica?

    
posta AngryBird 17.08.2011 - 20:37
fonte

4 risposte

40

What exactly is the Cyclomatic complexity saying to me?

La complessità ciclomatica non è una misura di linee di codice, ma il numero di percorsi indipendenti attraverso un modulo. La tua complessità ciclomatica di 17.754 significa che la tua applicazione ha 17.754 percorsi unici attraverso di essa. Questo ha alcune implicazioni, tipicamente in termini di quanto sia difficile capire e testare la tua applicazione. Ad esempio, la complessità ciclomatica è il numero di casi di test necessari per ottenere una copertura del 100% della filiale, presupponendo test ben scritti.

Un buon punto di partenza potrebbe essere l' articolo di Wikipedia sulla complessità ciclomatica . Ha un paio di snippits di pseudocodice e alcuni grafici che mostrano cosa sia la complessità ciclomatica. Se vuoi saperne di più, puoi leggere anche leggere il documento di McCabe in cui ha definito la complessità ciclomatica .

My application has a Cyclomatic complexity of 17,754 lines of code. The application itself is only 37,672 lines of code. Is it valid to say that the complexity is high based of the lines of code?

Assolutamente no. Un'applicazione con poche righe di codice e un numero elevato di condizionali nidificati nei loop potrebbe avere una complessità ciclomatica estremamente elevata. D'altra parte, un'applicazione con poche condizioni potrebbe avere una bassa complessità ciclomatica. Ciò semplifica enormemente la cosa, ma penso che dia l'impressione.

Senza saperne di più su ciò che fa l'applicazione, potrebbe essere normale avere una maggiore complessità ciclomatica. Suggerirei di misurare la complessità ciclomatica a livello di classe o di metodo, invece di un semplice livello di applicazione. Questo è un po 'più gestibile, concettualmente, penso - è più facile visualizzare o concettualizzare i percorsi attraverso un metodo piuttosto che i percorsi attraverso una grande applicazione.

    
risposta data 17.08.2011 - 20:50
fonte
33

La complessità ciclomatica è un modo per determinare se il codice deve essere sottoposto a refactoring. Il codice viene analizzato e viene determinato un numero di complessità. La complessità è determinata dalla ramificazione (se dichiarazioni, ecc.) La complessità potrebbe anche prendere in considerazione l'annidamento di loop, ecc. E altri fattori dipendenti dall'algoritmo utilizzato.

Il numero è utile a livello di metodo. Ai livelli più alti è solo un numero.

Un numero di 17.754 indica la complessità del livello di progetto (codice totale), che non ha molto significato.

Il drill-down in classe e la complessità del livello del metodo determineranno le aree del codice che devono essere refactored in metodi più piccoli o riprogettati per elminare la complessità.

Considera un'istruzione CASE con 50 casi in un metodo. Forse ogni stato ha una logica di business diversa. Ciò genererà una complessità ciclomatica di 50. Ci sono 50 punti decisionali. La dichiarazione CASE potrebbe dover essere ridisegnata usando un modello di fabbrica per eliminare la logica di ramificazione. A volte puoi refactoring (suddividere il metodo in parti più piccole) e in alcuni casi solo una riprogettazione ridurrà la complessità.

In generale, per la complessità a livello di metodo:

  • < 10 Facile da mantenere
  • 11-20 Difficile da mantenere
  • 21+ candidati per il refactoring / riprogettazione

Considera anche che complessità più elevate rendono il codice più difficile da testare in unità.

La più alta complessità che ho visto su un singolo metodo era 560. Si trattava di circa 2000 righe di istruzioni if in un metodo. Fondamentalmente non mantenibile, non testabile, pieno di potenziali bug. Immagina tutti i casi di test unitari necessari per quella logica di ramificazione! Non va bene.

Cerca di mantenere tutti i metodi sotto i 20 e renditi conto che esiste un costo per il refactoring di qualsiasi metodo per renderlo meno complesso.

    
risposta data 17.08.2011 - 21:27
fonte
1

È il numero di percorsi distinti nella tua applicazione. Dai un'occhiata a questo articolo IBM su CC .

Sembra alto, ma nel tuo caso è l'aggiunta del CC di tutti i tuoi metodi di tutte le tue classi e metodi. I miei esempi sono molto tesi perché non so come sia strutturato il tuo codice, ma puoi anche avere un metodo mostro con 37672 linee di codice o 3767 metodi con circa 10 righe di codice. Ciò che intendo è che a livello di applicazione, questo indicatore non significa molto, ma a livello di metodo può aiutarti a ottimizzare / riscrivere il tuo codice in metodi più piccoli in modo che siano meno inclini agli errori.

Quello che ho letto personalmente molte volte è che i metodi con un CC superiore a 10 hanno rischi maggiori di difetti.

Uso Sonar per testare la qualità del codice delle mie applicazioni e, per impostazione predefinita, penso che sollevi un avviso se hai metodi con +10 CC. Ciò potrebbe non significare nulla. Un esempio concreto: se usi Eclipse per generare un metodo equals basato sulle proprietà del tuo bean, il CC andrà molto rapidamente sopra il tetto ...

    
risposta data 17.08.2011 - 20:53
fonte
-1

Dipende da quale strumento hai usato. Alcuni degli strumenti open source disponibili prendono classe come modulo o altro livello di struttura come modulo. Pertanto, più grande diventa un progetto, maggiore è la complessità ciclomatica che tende a ottenere. Tuttavia, per la mia comprensione personale, dovrebbe essere basato su una funzione. Dal momento che più grande diventa un progetto, le funzioni che esso assiste.

Ti consiglio di utilizzare lo strumento chiamato Lizard e puoi trovare il codice risorsa e scaricare il file zip su github. Ha anche una versione online se non ci sono molte informazioni riservate nel tuo codice.

Il CCN significativo di cui ti dovresti occupare è su una base di funzioni diversa da qualsiasi altra. Inoltre, mantenere CCN di ogni funzione unber 15 sarebbe il range ideale.

    
risposta data 28.07.2016 - 19:20
fonte

Leggi altre domande sui tag