Quali sono i potenziali compromessi per la complessità ciclomatica più in basso

4

Poiché l'alta complessità ciclomatica è dannosa e sarebbe vantaggioso abbassarla creando sottofunzioni. Tuttavia, potrebbe portare a una lunga coda di chiamate e portare a una funzione super nidificata che consentirebbe anche agli altri programmatori di sentirsi difficili da leggere.

Quale sarebbe la soluzione vantaggiosa o dove dovremmo impostare la linea di fondo per la profondità della coda di chiamata? Esistono metriche o strumenti per testare la profondità di chiamata di una funzione?

Qualsiasi aiuto o idea è apprezzata.

    
posta Jiahang Li 28.07.2016 - 19:24
fonte

3 risposte

5

Estraendo il codice alle funzioni secondarie non diminuisce la complessità ciclomatica di un programma. Ovviamente, può ridurre la complessità ciclomatica di una singola funzione se una certa complessità viene estratta in una funzione separata, ma ciò sposta semplicemente la complessità intorno, il che non migliora il programma in sé.

Un'elevata complessità ciclomatica di una funzione potrebbe essere un segnale di avvertimento che la funzione è scritta in modo troppo complesso. Se questo è il caso, dovresti considerare se la logica potrebbe essere semplificata.

Ovviamente il codice può essere complesso perché il problema che risolve è complesso. Dovresti cercare complessità accidentale , complessità che non è necessaria. Un tipico esempio:

bool isZero = false;
if (x==0) {
   isZero = true;
} else if (x > 0 || x < 0) {
   isZero = false;
} else {
   Logger.LogError("Invalid value of x");
   throw new FileNotFoundException();
}

Il modo per risolvere questa complessità accidentale non è di estrarlo in una funzione separata, ma piuttosto di riscriverlo come:

bool isZero = x==0;
    
risposta data 28.07.2016 - 20:58
fonte
3

L'alta complessità ciclomatica è dannosa? Lo affermi come se fosse un fatto evidente, ma è importante tenere presente che in molti casi il problema reale che stai modellando nel codice è un problema complesso.

L'unica volta in cui ho sentito affermare che la complessità ciclomatica è qualcosa da minimizzare (o qualcosa di cui la gente parla affatto, infatti) è nel contesto del test unitario. Se questo è il contesto giusto per la tua domanda, James Coplien lo mette meglio di me:

I had a client in northern Europe where the developers were required to have 40% code coverage for Level 1 Software Maturity, 60% for Level 2 and 80% for Le vel 3, while some were aspiring to 100% code coverage. No problem! You’d think that a reasonably complex procedure with branches and loops would have provided a challenge, but it’s just a matter of divide et impera. Large functions for which 80% coverage was impossible were broken down into many small functions for which 80% coverage was trivial. This raised the overall corporate measure of maturity of its teams in one year, because you will certainly get what you reward. Of course, this also meant that functions no longer encapsulated algorithms. It was no longer possible to reason about the execution context of a line of code in terms of the lines that precede and follow it in execution, since those lines of code are no longer adjacent to the one you are concerned about. That sequence transition now took place across a polymorphic function call — a hyper-galactic GOTO. But if all you’re concerned about is branch coverage, it doesn’t matter.

  • If you find your testers splitting up functions to support the testing process, you’re destroying your system architecture and code comprehension along with it. Test at a coarser level of granularity.

-- Why Most Unit Testing Is Waste

In situazioni come questa è bene ricordare una citazione notoriamente attribuita ad Einstein: "Rendi tutto il più semplice possibile, ma non più semplice." La priorità delle metriche secondarie come la complessità ciclomatica su cose più importanti come la leggibilità del codice è una grave violazione di questa importante linea guida.

    
risposta data 28.07.2016 - 19:42
fonte
0

Se disponi di un metodo di grandi dimensioni, la semplice suddivisione del metodo in unità più piccole potrebbe non apportare alcun ulteriore vantaggio se non la modifica delle metriche.

La complessità può essere risolta con:

  • refactoring
  • Ridisegnare

A volte il refactoring è appropriato. Abbiamo un metodo complesso che fa cinque cose, ha senso rifattorizzare in 1 metodo principale che chiama 5 metodi secondari. Questo dovrebbe rendere il codice più facile da capire e testare. Potremmo essere in grado di eliminare alcune righe di codice, ma alla fine probabilmente abbiamo la stessa quantità di linee di codice con cui abbiamo iniziato. Questi tipi di sforzi sembrano buoni a prima vista e possono produrre parametri migliori rispetto alla base di codice, ma nel complesso il valore aggiunto potrebbe essere inferiore al previsto. Devi determinare se l'analisi è appropriata. Ovviamente abbattere un grande metodo in 10 o 100 di chiamate sub o nidificate può introdurre un effetto cobra in cui le buone intenzioni hanno peggiorato le cose. Vuoi evitarlo.

A volte abbiamo un metodo troppo complesso per un semplice refactoring vecchio o scomposizione in blocchi più piccoli. In tal caso, potremmo aver bisogno di una riprogettazione. Una riprogettazione può introdurre nuovi modelli di progettazione e / o nuove classi che semplificano il codice. Quindi, invece di 1000 righe di codice, il risultato finale della riprogettazione è di 200 righe di codice. Questi sono sforzi molto più difficili, ma forniscono più valore da un punto di vista metrico e da un punto di vista generale del codice. Meno codice, meno complesso.

I compromessi sono sempre tempo e fatica. A volte il budget può consentire solo un piccolo refactoring come nel primo esempio. Altre volte una revisione complessa come nel caso 2.

Gli sviluppatori dovrebbero sempre monitorare lo stato di salute della base di codice controllando se stessi, fornendo revisioni tra pari e revisioni ufficiali del codice man mano che il codice viene aggiunto alla soluzione. Ciò manterrà la complessità a un livello gestibile.

    
risposta data 28.07.2016 - 21:38
fonte

Leggi altre domande sui tag