Perché la complessità ciclomatica è importante per un singolo metodo?

10

Sto usando SonarLint per Eclipse da poco, e mi ha aiutato molto. Tuttavia, mi ha sollevato una domanda sulla complessità ciclomatica.

SonarLint considera accettabile un C.C di 10, e ci sono alcuni casi in cui sono oltre, circa 5 o 6 unità. Queste parti sono correlate ai mapper in cui i valori si basano su variabili diverse, ad esempio:

  • Il campo A si basa su String sA;
  • Il campo B si basa su String sB;
  • Il campo C si basa su String sC;
  • ecc.

Non ho altra scelta che mettere un if per ogni campo. Questa non è la mia scelta (fortunatamente) ma un sistema già esistente e complesso che non posso cambiare da solo.

Il nocciolo della mia domanda è: perché è così importante non avere un C.C troppo alto in un unico metodo ? Se sposti alcune delle tue condizioni in uno o più sotto-metodi per ridurre la complessità, non riduce il costo della tua funzione generale, è solo spostando il problema altrove, immagino?

(Ci scusiamo per piccoli errori, se ce ne sono).

Modifica

La mia domanda non si riferisce alla complessità ciclomatica globale, ma solo alla complessità del metodo singolo e alla suddivisione del metodo (ho un tempo approssimativo per spiegare cosa intendo esattamente, scusa). Sto chiedendo perché è possibile dividere le tue condizioni in metodi più piccoli se appartiene ancora a un "metodo super", che eseguirà solo ogni sottotema, aggiungendo così complessità all'algoritmo.

Il secondo link tuttavia ( sull'anti-pattern ) è di grande aiuto.

    
posta Yassine Badache 02.12.2016 - 14:49
fonte

7 risposte

31

La cosa fondamentale qui: "capacità cerebrale".

Vedete, una delle funzioni principali del codice è ... essere leggere . E il codice può essere facile da leggere e capire; o difficile.

E avere un alto CC implica semplicemente molti "livelli" all'interno di un unico metodo. E ciò implica: tu, come lettore umano, avrai un difficile tempo a capire quel metodo.

Quando leggi il codice sorgente, il tuo cervello cerca automaticamente di mettere le cose in prospettiva: in altre parole cerca di creare una qualche forma di "contesto".

E quando hai un piccolo metodo (con un buon nome) che consiste solo di poche righe e CC molto basso; allora il tuo cervello può facilmente accettare questo "blocco". Lo leggi, lo capisci; FATTO.

D'altra parte, se il tuo codice ha un CC elevato, il tuo cervello impiegherà molti "cicli" in più per dedurre ciò che sta accadendo.

Un altro modo per dirlo: dovresti sempre inclinarti a preferire una rete complessa di cose semplici su una semplice rete di cose complesse. Perché il tuo cervello è più bravo a capire le piccole cose.

    
risposta data 02.12.2016 - 15:02
fonte
6

C.C, come tutte le altre regole pratiche per gli odori del codice, è un euristico . Non è un criterio di sicurezza che ti dice una verità assoluta. Se lo fosse, la cosa ragionevole da fare sarebbe semplicemente quella di rendere tali metodi illegali nella lingua e costringere le persone a raggiungere i loro scopi in un altro modo.

Ma non è così che funzionano gli indicatori. La maggior parte delle volte la loro funzione è di avvisare le persone di cose di cui non erano consapevoli. Nel tuo caso, sei consapevole del fatto che la logica è complicata e che le soluzioni alternative lo renderebbero ancora più complicato. Quindi non ha senso cercare di soddisfare la primitiva regola empirica, quando il suo scopo principale è quello di inviare avvertimenti a persone che non sono consapevoli del fatto che c'è un problema.

    
risposta data 02.12.2016 - 15:01
fonte
3

La complessità ciclomatica di un metodo è correlata al numero di casi di test richiesti per un metodo. Specificamente, una complessità ciclomatica di 10 significa che 10 è il limite superiore per i casi di test per avere una copertura totale della branca per il tuo metodo. È anche correlato al numero di percorsi che devono essere testati, al netto di tutti i percorsi impossibili.

Oltre a ciò, sono d'accordo con le altre risposte per altre considerazioni - capacità mentale di uno sviluppatore o un indicatore di potenziali problemi o refactoring o una misura di leggibilità e manutenibilità del codice .

    
risposta data 02.12.2016 - 15:09
fonte
2

In breve: si tratta di leggibilità e quindi di manutenibilità del codice.

Se hai un metodo lungo e complesso con un sacco (nidificato) if , diventa difficile dire cosa effettivamente fa. Se estrai alcuni metodi privati e li assegni in modo significativo, è molto più semplice.

    
risposta data 02.12.2016 - 15:02
fonte
0

CC è solo un euristico, e quanto "cattivo" un determinato punteggio dipende da molte cose.

Detto questo, dovresti sempre vedere un CC alto come qualcosa che evidenzia codice che potrebbe / dovrebbe essere rifatto. Dici che spostare l'istruzione if su un altro metodo nasconde il problema, ma esiste un modello che puoi astrarre invece di copiare e incollare n volte? Se è una lunga catena di if-else , puoi trasformarla in un'istruzione switch o forse usare il polimorfismo o qualcos'altro? Se esiste una nidificazione profonda, alcune delle tue clausole condizionali possono essere unite o indica responsabilità separate che dovrebbero essere suddivise in classi diverse?

    
risposta data 02.12.2016 - 15:10
fonte
0

Vedo la complessità ciclomatica come un avvertimento. Se riesci a leggere il codice e non è troppo complesso da capire, non mi preoccuperei molto di questo, probabilmente ci sono cose più importanti di cui preoccuparsi, ci sono sempre.

Un modo per ridurre il tipo di CC che hai menzionato è usare il polimorfismo, dato che hai taggato la tua domanda con il tag Java. Pertanto, anziché i percorsi di codice che sono digitati a caratteri stringenti puoi utilizzare classi ben definite. Questo può aiutare, ma a volte è eccessivo e può rendere il tuo codice ancora più difficile da capire.

Tuttavia, può essere un segno di codice che sarà difficile da mantenere. Quando leggi il metodo, è facile vedere quale percorso di codice andrai giù per ogni caso? Sareste in grado di saltare questo metodo se non conoscete bene il codice base e stavate cercando qualcosa di relativo ma più avanti nel codice? So che alcune persone sostengono metodi di suddivisione in un sacco di metodi di 1/2 linea con nomi descrittivi, ma a volte penso che sia ancora più difficile da leggere rispetto al codice che doveva sostituire.

In definitiva la manutenibilità è un problema difficile e spetta a te decidere quale pensi sarà più facile da leggere. Il fatto che tu stia pensando a questo significa che sei sulla buona strada. Ricorda, il maintainer che deve cercare di decifrare questo codice tra un anno potrebbe essere tu. Quindi rendilo il più semplice possibile per loro.

    
risposta data 02.12.2016 - 15:10
fonte
0

Dipende da quanto tempo si impiega a guardare (i cicli del cervello) al codice e capire cosa sta facendo il codice.

  • Considera un metodo a 10 righe - Probabilmente ci vorranno alcuni minuti per comprenderlo cosa sta facendo.
  • Considera un metodo a 100 righe - Probabilmente impiega un'ora o più per farlo capire cosa sta facendo.
  • Considera un metodo da 1000 righe - Probabilmente impiega un giorno o più a farlo capire cosa sta facendo.

Anche i metodi più grandi sono più difficili da testare e più difficili da prevedere quale tipo di comportamento potrebbe verificarsi.

La complessità ciclomatica è una misura. In questo caso, valori più alti sono indicatori di potenziali problemi. Il codice complesso richiede più tempo per comprendere e probabilmente non viene testato con la massima cura dei metodi meno complessi. Pertanto, è importante notare quali aree del codice sono complesse con questa misura ai fini del refactoring e della manutenzione.

Un'altra cosa da considerare è l'aggiornamento del codice complesso. Quando si effettua l'analisi, uno sviluppatore potrebbe segnalare che la modifica del codice è più o meno rischiosa osservando la sua complessità.

Quindi, c'è molto valore nella misurazione della complessità che può essere sfruttata e utilizzata per scopi decisionali.

    
risposta data 02.12.2016 - 15:35
fonte

Leggi altre domande sui tag