Nesting massimo per loop e condizionali? [duplicare]

14

Ho scritto un codice che ha dei nidi abbastanza profondi (una volta ho scritto qualcosa che era un controllo condizionale all'interno di un forloop all'interno di un controllo condizionale all'interno di un forloop all'interno di un forloop).

Esiste una linea guida generale sui limiti del numero di cicli / condizioni condizionali annidati?

    
posta Josh Brown 09.10.2013 - 19:50
fonte

6 risposte

14

Stai sfiorando una delle classiche metriche del codice: complessità ciclomatica . Non misura i livelli nidificati, ma piuttosto i cicli e condizionali (che in genere racchiudono i livelli annidati).

PMD (uno strumento di analisi statica Java) ha complessità come una delle sue misure e ha questo per dire al riguardo :

Complexity is determined by the number of decision points in a method plus one for the method entry. The decision points are 'if', 'while', 'for', and 'case labels'. Generally, 1-4 is low complexity, 5-7 indicates moderate complexity, 8-10 is high complexity, and 11+ is very high complexity.

Vedi anche Esperimenti che correlano le metriche del codice alla densità dei bug da P.SE che approfondisce le misure effettive.

    
risposta data 09.10.2013 - 20:30
fonte
9

Il linguaggio C consente fino a 127 livelli di blocchi nidificati; come 640 KB di RAM, questo è tutto ciò che chiunque dovrebbe mai avere bisogno.

In pratica, se ti trovi ad annidare più di 4 o 5 livelli di profondità, pensa di prendere in considerazione alcuni di quei livelli interiori verso le loro funzioni (o ripensare il tuo algoritmo). Se non altro, il codice sarà più facile da scansionare.

    
risposta data 09.10.2013 - 20:20
fonte
9

Ti consiglio vivamente di leggere "Codice pulito" di Robert Martin, un estratto di cui si parla delle strutture nidificate:

Blocks and Indenting

...the blocks within if statements, else statements, while statements, and so on should be one line long. Probably that line should be a function call. Not only does this keep the enclosing function small, but it also adds documentary value because the function called within the block can have a nicely descriptive name.

This also implies that functions should not be large enough to hold nested structures. Therefore, the indent level of a function should not be greater than one or two. This, of course, makes the functions easier to read and understand.

Quindi la raccomandazione di Bob Martin è che il reparto di struttura nidificata dovrebbe essere al massimo .

Sono d'accordo e, anche se non sempre lo rispondo, almeno ci provo.

Inoltre, secondo lo strumento di analisi statica della configurazione predefinita di PDM, la complessità ciclomatica di una funzione non deve superare 11, che può essere facilmente raggiunta se si supera un valore di due.

    
risposta data 09.10.2013 - 22:29
fonte
5

Come per la maggior parte delle domande sugli standard di codifica, la risposta è: Qualunque cosa renda il tuo codice più leggibile.

Direi che è di solito abbastanza vicino a zero livelli di logica incorporati. Ma a volte non lo è, e attaccare con veemenza le regole contro il buon senso è più dannoso che attenersi alla semplice politica di leggere il proprio codice o di indurre qualcun altro a farlo.

Tutto ciò che lo rende più leggibile, fallo.

    
risposta data 09.10.2013 - 20:23
fonte
2

Personalmente cerco di evitare più di quattro o cinque livelli in profondità in una singola funzione. Più di quello sarebbe un cattivo "odore di codice". Ti suggerirei di provare ad evitarlo regolando la struttura del programma o riformulando il tuo problema.

    
risposta data 09.10.2013 - 20:10
fonte
1

Uno svantaggio per i cicli annidati non menzionati ancora: se ogni ciclo esegue un'iterazione su un set di dati di grandi dimensioni, l'algoritmo avrà classi ad alta complessità. Ad esempio,

foreach(foo in foos) {
  foreach(bar in bars) {
    foreach(baz in bazzes) {
      foreach(buzz in buzzes) {
        do_a_thing(foo, bar, baz, buzz);
      }
    }
  }
}

Eseguirà all'incirca O(n^4) di tempo se foos , bars , bazzes e buzzes sono tutti della stessa dimensione.

Questo non è un problema se le collezioni saranno sempre piccole. Quindi, si applica il consiglio di tutti gli altri. Se le tue raccolte hanno una discreta possibilità di essere migliaia di elementi di dimensioni maggiori o maggiori, tuttavia, sarebbe opportuno cercare un algoritmo più veloce se possibile.

    
risposta data 10.10.2013 - 01:58
fonte

Leggi altre domande sui tag