2017-02-14 5 views
1

dans un si la condition suivante commeComment réduire la complexité cyclomatique dans une condition if?

if(condition1 || condition2 || condition3 || condition4 || condition5) 
... 

où les conditions sont indépendantes les unes des autres, la complexité du code tend à être élevé, est-il un moyen de factoriser cette logique pour réduire la complexité?

conditions peuvent ici représenter des méthodes qui effectuent une validation et retournent une valeur booléenne.

l'ajout d'un extrait de code pour plus de clarté

public void doSomething(boolean val, boolean val2, boolean val3, boolean val4, boolean val5, boolean val6) 
    { 
     if(val || val2 || val3|| val4|| val5|| val6) 
     { 
      System.out.println("hello"); 
     } 
     else{ 
      System.out.println("hello world"); 
     } 
    } 

La complexité de l'extrait ci-dessus est 7

+0

vous devriez montrer plus de code, car ce code n'a pas la complexité cyclomatique: vous avez un seul chemin. – davidxxx

+0

Pourquoi êtes-vous préoccupé par la complexité cyclomatique? Seriez-vous prêt à réduire la lisibilité si vous pouviez réduire la complexité cyclomatique? –

+0

Si je comprends bien, la complexité cyclomatique est le nombre de chemins linéairement indépendants à travers le code. Un moyen facile de réduire serait d'utiliser '|' au lieu de '||' car cela forcerait une évaluation de toutes les conditions à chaque fois. J'ai du mal à voir l'amélioration, cependant. –

Répondre

0

Peut être obtenir des drapeaux booléens renseignés pour chaque condition et l'utilisation de ces drapeaux si la déclaration. Cela améliorerait la lisibilité à mon avis.

+1

Mais cela ne résoudrait pas la question de la complexité? –

0

Dans ce cas particulier, je voudrais rendre ce code plus universel:

public void doSomething(boolean... val) { 
    for (boolean v : val) { 
     if (v) { 
      System.out.println("hello"); 
      return; 
     } 
    } 

    System.out.println("hello world"); 
} 

Cela vous permettra ne portez pas d'arguments dans la méthode, si votre logique à l'intérieur de cette méthode est vraiment cette (c.-à- ACTION # 1 si l'un des arguments est true, sinon ACTION # 2).

0

Après votre édition:

« La complexité de l'extrait ci-dessus est 7 »

Je pense que le problème est l'outil que vous utilisez pour mesurer la complexité.

Si vous remplacez

if(val || val2 || val3|| val4|| val5|| val6) 

par

boolean condition = val || val2 || val3|| val4|| val5|| val6;   
    if(condition) 

Quelle est la complexité maintenant? En développement, la complexité cyclomatique fait généralement référence à des chemins potentiels dans le flux de code. Il est souvent assez lié à des blocs conditionnels imbriqués.

Nous parlons de code qui a une complexité cyclomatique importante en tant que code flèche lorsque les niveaux imbriqués dessinent une sorte de flèche.

Dans votre exemple de code, il est pas un problème que vous avez seulement trois chemins possibles:

public void doSomething(boolean val, boolean val2, boolean val3, boolean val4, boolean val5, boolean val6) 
    { 
     if(val || val2 || val3|| val4|| val5|| val6) 
     { 
      System.out.println("hello"); 
     } 
     else{ 
      System.out.println("hello world"); 
     } 
    } 
  • Premier chemin: if(val || val2 || val3|| val4|| val5|| val6)
  • Deuxième chemin: else{
  • troisième voie: Code entre le else et la fin de la méthode

Moins un code a des chemins possibles, plus il est plus facile à lire, à tester et à maintenir.

Dans votre cas trop simple, vous pouvez réduire la complexité en n'utilisant pas l'instruction else. Qui suppriment un chemin potentiel:

public void doSomething(boolean val, boolean val2, boolean val3, boolean val4, boolean val5, boolean val6) 
    { 
     if(val || val2 || val3|| val4|| val5|| val6) 
     { 
      System.out.println("hello"); 
      return; 
     } 

     System.out.println("hello world");   
    } 

Mais clairement vos exemples sont trop simples pour manifester des problèmes graves liés à la complexité.
Voici une version modifiée de votre exemple de code où les questions de complexité sur la refactorisation du code pour réduire la complexité cyclomatique.

public void doSomething(boolean val, boolean val2, boolean val3, boolean val4, boolean val5, boolean val6) 
    { 
     if(val || val2 || val3|| val4|| val5|| val6) 
     { 
      if (condition){ 
        if (val8 && val9){ 
        ... 
        } 
        else { 
         if (condition2 && condition3){ 
         System.out.println("hello"); 
         } 
        } 
      } 

     } 
     else{ 
      System.out.println("hello world"); 
     } 
    } 

En général, pour réduire la complexité cyclomatique vous devez réduire le nombre de chemins possibles. Vous pouvez y arriver:

  • en évitant pas nécessaire else
  • instructions de condition de regroupement qui sont séparés alors qu'il pourrait être une seule déclaration qui
  • sortant de la méthode lorsqu'une condition permet de le faire et ne pas attendre pour un seul point de sortie.

+0

Une petite note: un 'return; 'est nécessaire dans le bloc if, dans l'extrait sans l'autre, pour conserver la même sortie. – Linuslabo

+0

@Linuslabo En effet très important. Je vous remercie. – davidxxx