Métriques de code - Complexité cyclomatique

Quand vous utilisez des métriques de code, il peut être difficile de comprendre certains éléments, tout particulièrement la complexité cyclomatique. Avec la complexité cyclomatique, il faut surtout savoir que des valeurs élevées sont une mauvaise chose et des valeurs faibles une bonne. Vous pouvez utiliser la complexité cyclomatique pour avoir une idée de la difficulté de tester, de maintenir ou de dépanner un code donné, ainsi qu'une indication de la probabilité que le code produise des erreurs. De façon générale, nous déterminons la valeur de la complexité cyclomatique en comptant le nombre de décisions prises dans votre code source. Cet article vous propose d’abord un exemple simple de complexité cyclomatique, vous permettant de comprendre rapidement le concept. Il fournit ensuite des informations supplémentaires sur l’utilisation réelle et les limites suggérées. La dernière section fournit des références permettant d’approfondir le sujet.

Exemple

La complexité cyclomatique est définie comme mesure de « la quantité de logique de décision dans une fonction de code source » NIST235. En d’autres termes, plus il y a de décisions à prendre dans le code, plus il est complexe.

Découvrons-le en action. Créez une application console et calculez immédiatement vos métriques de code en accédant à Analyser > Calculer la métrique du code pour la solution.

Complexité cyclomatique - Exemple 1

Notez que la complexité cyclomatique a la valeur 2 (la valeur la plus faible possible). Si vous ajoutez du code n'impliquant pas de décision, vous voyez que la complexité ne change pas :

Complexité cyclomatique - Exemple 2

Si vous ajoutez une décision, la valeur de complexité cyclomatique augmente d’une unité :

Complexité cyclomatique - Exemple 3

Quand vous remplacez l’instruction if par une instruction switch avec 4 décisions à prendre, elle passe de 2 à 6 :

Complexité cyclomatique - Exemple 4

Observons une base de code (hypothétique) plus grande.

Complexité cyclomatique - Exemple 5

Quand vous explorez la classe Products_Related, notez que la plupart des éléments ont la valeur 1, mais que pour deux d’entre eux, la complexité a la valeur 5. Ceci n'est peut-être pas un gros problème en soi, mais comme la plupart des autres membres dans la même classe ont la valeur 1, vous auriez tout intérêt à examiner ces deux éléments de plus près et à déterminer ce qu'ils contiennent. Pour cela, cliquez avec le bouton droit sur l’élément et choisissez Atteindre le code source dans le menu contextuel. Examinons Product.set(Product) de plus près :

Complexité cyclomatique - Exemple 6

Le nombre d’instructions if explique pourquoi la complexité cyclomatique a la valeur 5. À ce stade, vous pouvez décider qu'il s'agit d'un niveau de complexité acceptable, ou vous pouvez refactoriser pour réduire la complexité.

Nombre magique

Comme pour de nombreuses métriques dans ce secteur, il n’existe pas de limite de complexité cyclomatique spécifique convenant à toutes les organisations. Toutefois, NIST235 indique qu’une limite de 10 est un bon point de départ :

« Le nombre précis à utiliser comme limite, cependant, reste quelque peu controversé. La limite initiale de 10 proposée par McCabe s’appuie sur de sérieux éléments de preuve. Cependant, des limites allant jusqu’à 15 ont également été utilisées avec succès. Les limites supérieures à 10 doivent être réservées aux projets qui présentent plusieurs avantages opérationnels, plutôt qu’aux projets classiques (équipes expérimentées, conception formelle, langage de programmation moderne, programmation structurée, procédures de programmation pas à pas, plan de test complet, etc.). En d'autres termes, une organisation peut choisir une limite de complexité supérieure à 10 seulement si elle est sûre de savoir ce qu'elle fait et qu'elle est prête à consacrer l'effort de test supplémentaire que nécessitent des modules plus complexes ». NIST235

Complexité cyclomatique et nombre de lignes

Le simple fait d’examiner le nombre de lignes de code peut, au mieux, donner une vague idée de la qualité du code. Il n’est pas toujours faux de penser que plus il y a de lignes de code dans une fonction, plus elle est susceptible de présenter des erreurs. Toutefois, en combinant la complexité cyclomatique avec le nombre de lignes de code, vous apprécierez beaucoup plus clairement le risque d’erreur.

Comme décrit par le SATC (Software Assurance Technology Center) de la NASA :

« Le SATC a déterminé que l'évaluation la plus efficace consiste à combiner taille et complexité (cyclomatique). Les modules présentant à la fois une grande complexité et une grande taille ont tendance à présenter une fiabilité plus faible. Les modules de faible taille et de complexité élevée présentent également un risque en termes de fiabilité, car ils ont tendance à reposer sur du code très succinct, difficile à changer ou à modifier ». SATC

Analyse du code

L’analyse du code inclut une catégorie de règles de maintenabilité. Pour plus d’informations, consultez Règles de maintenabilité. Quand vous utilisez une analyse du code héritée, l’ensemble de règles Extended Design Guideline inclut une catégorie de maintenabilité :

Complexité cyclomatique - Ensembles de règles de directives de conception

La catégorie de maintenabilité inclut une règle pour la complexité :

Complexité cyclomatique - Règle de maintenabilité

Cette règle émet un avertissement quand la complexité cyclomatique atteint la valeur 25. Elle vous permet donc d’éviter une complexité excessive. Pour en savoir plus sur cette règle, consultez CA1502.

En résumé

Il faut donc essentiellement retenir qu’une valeur de complexité élevée implique un plus grand risque d’erreur et donc plus de temps passé en maintenance et résolution des problèmes. Examinez de plus près toutes les fonctions qui ont une complexité élevée et déterminez si vous devez les refactoriser pour les rendre moins complexes.

Références

MCCABE5

McCabe, T. et A. Watson (1994), Software Complexity (CrossTalk: The Journal of Defense Software Engineering).

NIST235

Watson, A. H., et McCabe, T. J. (1996). Structured Testing: A Testing Methodology Using the Cyclomatic Complexity Metric (publication spéciale du NIST 500-235). Extrait le 14 mai 2011 du site web de McCabe Software : http://www.mccabe.com/pdf/mccabe-nist235r.pdf

SATC

Rosenberg, L., Hammer, T., Shaw, J. (1998). Software Metrics and Reliability (Proceedings of IEEE International Symposium on Software Reliability Engineering). Extrait le 14 mai 2011 du site web de l’Université Penn State : https://citeseerx.ist.psu.edu/pdf/31e3f5732a7af3aecd364b6cc2a85d9495b5c159