Domanda

Recentemente l'azienda ha iniziato a misurare la complessità ciclomatica (CC) funzioni nel nostro codice, su base settimanale, e di segnalare che le funzioni hanno migliorato o peggiorato.Così abbiamo iniziato a prestare molta più attenzione ai CC di funzioni.

Ho letto che il CC potrebbe essere informalmente calcolato come 1 + il numero di punti di decisione in una funzione (ad es.istruzione if, for, selezionare, ecc), o anche il numero di percorsi attraverso una funzione...

Ho capito che il modo più semplice per ridurre il CC è quello di utilizzare l'Estratto Metodo di refactoring più volte...

Ci sono quarantina sono incerti, ad es.qual è il CC dei seguenti frammenti di codice?

1)

for (int i = 0; i < 3; i++)
    Console.WriteLine("Hello");

E

Console.WriteLine("Hello");
Console.WriteLine("Hello");
Console.WriteLine("Hello");

Hanno entrambi la stessa cosa, ma non la prima versione hanno una maggiore CC a causa della per la dichiarazione?

2)

if (condition1)
    if (condition2)
        if (condition 3)
            Console.WriteLine("wibble");

E

if (condition1 && condition2 && condition3)
    Console.WriteLine("wibble");

Supponendo che il linguaggio di valutazione di corto circuito, come C#, quindi questi due frammenti di codice hanno lo stesso effetto...ma è il CC del primo frammento superiore perché ha 3 punti di decisione/istruzioni if?

3)

if (condition1)
{
    Console.WriteLine("one");

    if (condition2)
        Console.WriteLine("one and two");
}

E

if (condition3)
    Console.WriteLine("fizz");

if (condition4)
    Console.WriteLine("buzz");

Questi due frammenti di codice fanno cose diverse, ma non hanno la stessa CC?O il se nidificata nel primo frammento di avere una maggiore CC?cioèif nidificate sono mentalmente più complesso da capire, ma che riflette in CC?

È stato utile?

Soluzione

  1. Sì. Il tuo primo esempio ha un punto di decisione e il secondo no, quindi il primo ha un CC più alto.
  2. Sì-forse, il tuo primo esempio ha più punti di decisione e quindi un CC più alto. (Vedi sotto per la spiegazione.)
  3. Sì, forse. Ovviamente hanno lo stesso numero di punti decisionali, ma ci sono diversi modi per calcolare CC, il che significa ...

... se la tua azienda sta misurando CC in un modo specifico, allora devi acquisire familiarità con quel metodo (speriamo che stiano usando strumenti per farlo). Esistono diversi modi per calcolare CC per situazioni diverse (dichiarazioni di casi, operatori booleani, ecc.), Ma è necessario ottenere lo stesso tipo di informazioni dalla metrica, indipendentemente dalla convenzione utilizzata.

Il problema più grande è quello che altri hanno menzionato, che la tua azienda sembra concentrarsi più su CC che sul codice che sta dietro. In generale, sotto 5 va benissimo, sotto 10 va bene, sotto 20 va bene, da 21 a 50 dovrebbe essere un segnale di avvertimento e sopra 50 dovrebbe essere un grosso segnale di avvertimento, ma quelle sono guide, non regole assolute. Probabilmente dovresti esaminare il codice in una procedura che ha un CC superiore a 50 per assicurarti che non sia solo un enorme mucchio di codice, ma forse c'è un motivo specifico per cui la procedura è scritta in quel modo e non è fattibile (per qualsiasi numero di motivi) per riformularlo.

Se usi strumenti per refactoring del tuo codice per ridurre CC, assicurati di capire cosa stanno facendo gli strumenti e che non stanno semplicemente spostando un problema in un altro posto. In definitiva, vuoi che il tuo codice abbia pochi difetti, funzioni correttamente e sia relativamente facile da mantenere. Se anche quel codice ha un CC basso, va bene. Se il tuo codice soddisfa questi criteri e ha un CC superiore a 10, forse è il momento di sederti con qualsiasi gestione tu possa e difendere il tuo codice (e forse farli esaminare la loro politica).

Altri suggerimenti

Dopo aver sfogliato la voce di Wikipedia e sul documento originale di Thomas J. McCabe, sembra che gli elementi sopra menzionati sono noti problemi con la metrica.

Tuttavia, la maggior parte delle metriche presenta pro e contro. Suppongo che in un programma abbastanza grande il valore CC potrebbe indicare parti forse complesse del codice. Ma quel CC più alto non significa necessariamente complesso.

Come tutte le metriche del software, CC non è perfetto. Utilizzato su una base di codice abbastanza grande, può darti un'idea di dove potrebbe essere una zona problematica.

Ci sono due cose da tenere a mente qui:

  1. Base di codice abbastanza grande: in qualsiasi progetto non banale avrai funzioni che hanno un valore CC davvero elevato. Così alto che non importa se in uno dei tuoi esempi, il CC sarebbe 2 o 3. Una funzione con un CC di diciamo oltre 300 è sicuramente qualcosa da analizzare. Non importa se il CC è 301 o 302.
  2. Non dimenticare di usare la testa. Esistono metodi che richiedono molti punti decisionali. Spesso possono essere rifattorizzati in qualche modo per avere meno, ma a volte non possono. Non seguire una regola come & Quot; Rifattorizza tutti i metodi con un CC & Gt; xy " ;. Dai un'occhiata a loro e usa il tuo cervello per decidere cosa fare.

Mi piace l'idea di un'analisi settimanale. Nel controllo di qualità, l'analisi delle tendenze è uno strumento molto efficace per identificare i problemi durante la loro creazione . È molto meglio che dover aspettare che diventino così grandi da diventare ovvi (vedi SPC per alcuni dettagli).

CC non è una panacea per misurare la qualità. Chiaramente un'istruzione ripetuta non è & Quot; migliore & Quot; di un loop, anche se un loop ha un CC più grande. Il motivo per cui il loop ha un CC più grande è che a volte potrebbe essere eseguito e talvolta no, il che porta a due differenti & Quot; case & Quot; che dovrebbe essere testato entrambi. Nel tuo caso il ciclo sempre verrà eseguito tre volte perché usi una costante, ma CC non è abbastanza intelligente da rilevarlo.

Lo stesso vale per gli if concatenati nell'esempio 2: questa struttura consente di avere una dichiarazione che verrebbe eseguita se solo condizione1 e condizione2 fossero vere. Questo è un caso speciale che non è possibile nel caso in cui si usi & Amp; & Amp ;. Quindi l'if-chain ha un potenziale maggiore per casi speciali anche se non lo usi nel tuo codice.

Questo è il pericolo di applicare ciecamente qualsiasi metrica. La metrica CC ha certamente molti meriti ma, come con qualsiasi altra tecnica per migliorare il codice, non può essere valutata divisa dal contesto. Indirizza la tua direzione alla discussione di Casper Jone sulla misurazione delle linee di codice (vorrei poter trovare un link per te). Sottolinea che se Lines of Code è una buona misura della produttività, gli sviluppatori di linguaggio assemblatore sono gli sviluppatori più produttivi sulla terra. Naturalmente non sono più produttivi di altri sviluppatori; ci vuole solo molto più codice per realizzare ciò che le lingue di livello superiore fanno con meno codice sorgente. Cito questo, come ho detto, in modo da poter mostrare ai tuoi manager quanto sia stupido applicare ciecamente le metriche senza una revisione intelligente di ciò che la metrica ti sta dicendo.

Suggerirei che, in caso contrario, la tua direzione sarebbe saggia nell'utilizzare la misura CC come modo per individuare potenziali hot spot nel codice che dovrebbero essere ulteriormente esaminati. Mirare ciecamente all'obiettivo del CC inferiore senza alcun riferimento alla manutenibilità del codice o ad altre misure di buona codifica è semplicemente sciocco.

La complessità ciclomatica è analoga alla temperatura. Sono entrambe misurazioni e nella maggior parte dei casi prive di significato senza contesto. Se dicessi che la temperatura esterna era di 72 gradi che non significa molto! ma se aggiungessi il fatto che ero al Polo Nord, il numero 72 diventa significativo. Se qualcuno mi dicesse che un metodo ha una complessità ciclomatica di 10, non posso determinare se questo è buono o cattivo senza il suo contesto.

Quando ripasso il codice di un'applicazione esistente, trovo la complessità ciclomatica un & # 8220 utile; punto di partenza & # 8221; metrica. La prima cosa che controllo sono i metodi con un CC & Gt; 10. Questi & # 8220; & Gt; 10 & # 8221; i metodi non sono necessariamente sbagliati. Mi forniscono solo un punto di partenza per la revisione del codice.

Regole generali quando si considera un numero CC:

  • La relazione tra CC # e # di test, dovrebbe essere CC # < = #test
  • Rifattore per CC # solo se aumenta manutenibilità
  • CC sopra 10 spesso indica uno o più Odori di codice

[Off topic] Se si favorisce la leggibilità sul buon punteggio nel metriche (Fu J. Spolsky che ha detto, "ciò che è misurato, ottenere fatto" ?- il che significa che le metriche sono abusato più spesso di quanto non, suppongo), spesso è meglio usare un nome booleano per sostituire il vostro complesso istruzione condizionale.

quindi

if (condition1 && condition2 && condition3)
    Console.WriteLine("wibble");

diventare

bool/boolean theWeatherIsFine =  condition1 && condition2 && condition3;

if (theWeatherIsFine)
    Console.WriteLine("wibble");

Non sono un esperto di questo argomento, ma ho pensato di dare i miei due centesimi. E forse è tutto ciò che vale.

La complessità ciclomatica sembra essere solo una scorciatoia automatica per trovare frammenti di codice potenzialmente (ma non sicuramente) problematici. Ma il vero problema da risolvere non è quello dei test? Quanti casi di test richiede il codice? Se CC è più alto, ma il numero di casi di test è lo stesso e il codice è più pulito, non preoccuparti di CC.

1.) Non vi è alcun punto decisionale lì. C'è un solo e unico percorso attraverso il programma lì, solo un possibile risultato con una delle due versioni. Il primo è più conciso e migliore, la complessità ciclistica è dannata.

1 caso di test per entrambi

2.) In entrambi i casi, scrivi " wibble " o non lo fai.

2 casi di test per entrambi

3.) Il primo non può provocare nulla, " uno " oppure " uno " e " uno e due " ;. 3 percorsi. Il secondo potrebbe non provocare nulla, né dei due, né di entrambi. 4 percorsi.

3 casi di test per il primo 4 casi di test per il secondo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top