Grâce à une question sur Code Review, j'ai eu un petit désaccord (qui est essentiellement une opportunité d'apprendre quelque chose) sur ce qu'est exactement la complexité cyclomatique pour le code ci-dessous.
public static void main(String[] args) {
try {
thro();
thro();
thro();
thro();
thro();
thro();
thro();
}
catch (NullPointerException e) {
}
}
private static Random random = new Random();
public static void thro() throws NullPointerException {
if (random.nextBoolean())
throw new NullPointerException();
System.out.println("No crash this time");
}
En écrivant ce code dans Eclipse et en utilisant le plugin de métriques Eclipse , cela me dit que la complexité cyclomatique McCabe pour la méthode principale est 2, et pour la thro
méthode, elle dit 2.
Cependant, quelqu'un d'autre me dit que la complexité d'appeler thro
plusieurs fois est number of calls * method complexity
, et affirme donc que la complexité de la méthode principale est 7 * 2 = 14.
Sommes-nous en train de mesurer des choses différentes? Peut-on avoir raison tous les deux? Ou quelle est la complexité cyclomatique réelle ici?
la source
Réponses:
Quand j'ai bien compris, la complexité cyclomatique de
main
est 8 - c'est le nombre de chemins linéairement indépendants à travers le code. Vous obtenez soit une exception sur l'une des sept lignes, soit aucune, mais jamais plus d'une. Chacun de ces "points d'exception" possibles correspond exactement à un chemin différent dans le code.Je suppose que lorsque McCabe a inventé cette métrique, il n'avait pas de langages de programmation avec une gestion des exceptions à l'esprit.
la source
main
méthode?Étant «l'autre gars», je vais répondre ici, et être précis sur ce que je dis (ce que je n'étais pas particulièrement précis avec sur d'autres formums).
En utilisant l'exemple de code ci-dessus, je calcule la complexité cyclomatique comme 8, et j'ai des commentaires dans le code pour montrer comment je calcule cela. Pour décrire les chemins, je considérerai une boucle réussie à travers tous les
thro()
appels comme le chemin de code «principal» (ou «CP = 1»):Donc, je compte 8 chemins de code dans cette méthode principale, qui, pour moi, est une complexité cyclomatique de 8.
En termes Java, chaque mécanisme pour quitter une fonction compte pour sa complexité, donc, une méthode qui a un état de réussite, et, par exemple, peut contenir jusqu'à 3 exceptions, a 4 chemins de sortie documentés.
La complexité d'une méthode qui appelle une telle fonction est:
Je pense que d'autres choses à considérer, c'est que, à mon avis, la
catch
clause ne contribue pas à la complexité de la méthode,catch
est simplement la cible d'unethrows
branche, et donc un bloc de capture qui est la cible de plusieursthrow
comptes s 1 fois pour chacunthrow
, et pas seulement une fois pour tout.la source
catch (Throwable t) {...
je pense que peu importe le nombre d'exceptions qu'elle déclare lever.