Une méthode de 1000 lignes ou 100 méthodes de 10 lignes ?

La réponse à cette question est évidement: 100 méthodes de 10 lignes …

Nombre de lignes de code ou LoC

Parmi les métriques de bases de la qualité logicielle, s’il y’en a une bien qui est vraiment LA métrique de base, c’est le nombre de ligne de codes. On ne va pas expliquer ici comment on calcule ce nombre, Wikipedia en anglais contient une page LoC (Lines of Code) sur le sujet.

Le nombre de ligne de codes d’un projet, d’une application, d’une classe ou d’une méthode est une métrique intéressante pour évaluer la complexité de chacun de ces éléments.

Le mot “évaluer” est délibérément choisi, car effectivement ce n’est qu’une évaluation et non pas une vision exacte de cette complexité, néanmoins c’est un indicateur  convenable. Ceci n’est pas du à la précision du calcul, mais au fait que la complexité, comme la simplicité ou l’intelligibilité sont des critères subjectifs et donc difficilement quantifiables.

Un exemple simple pour démontrer cela. Prenons le code Java suivant que l’on va nommer code A:

 int i = 0;
 System.out.println("ligne " + i);
 i++;
 System.out.println("ligne " + i);
 i++;
 System.out.println("ligne " + i);
 i++;

Et ce code ci que l’on nomme code B:

 for( int i = 0; i < 3;i++) {
 System.out.println("ligne " + i);
 }

Bien que ces deux codes fassent la même chose, et que le code B comporte moins de lignes que le code A, d’un point de vue intellectuel, le code B est plus complexe que le code A. Pour vous en convaincre, rappelez-vous que lorsque vous avez appris à programmer, vous avez d’abord appris ce qu’était une instruction, puis une série d’instructions, puis une boucle.

Je ne parle pas ici d’une autre métrique qui est la Complexité Cyclomatique, que l’on développera dans un autre article, mais purement de complexité au sens intellectuel du terme. Cette même complexité qui est proportionnelle à l’effort de réflexion ou de conceptualisation nécessaire à la compréhension d’un raisonnement, d’un algorithme et par extension d’un code.

Évidemment, cet exemple est un cas extrême, et si votre application ne ressemblait qu’à des successions de lignes identiques (du copier coller du code A), il y’aurait probablement un sérieux problème. Dans la majorité des cas, votre application ressemble plutôt à une succession ou à un enchevêtrement du code B avec en plus des tests (instructions if, else, switch/case, etc…), des appels de méthodes, de l’introspection et tout un tas d’autres choses assez complexe à appréhender.

Globalement, le nombre d’instructions et donc de lignes va en croissant avec la complexité de ce qui est développé.

Revenons à notre sujet : La méthode de 1000 lignes

Récemment, j’avais une discussion intéressante avec un chef de projet technique qui a pas mal travaillé sur une application grandissante et vieillissante et qui était confronté à des problématiques de méthodes de plus de 700 lignes, voire 1000 lignes. Il va sans dire que la maintenance était éprouvante.

Les méthodes en question réalisaient les écritures comptables des transactions journalières d’une application d’encaissement et de facturation. Cette application était soumise à de nombreuses évolutions de ses règles de calcul, notamment du fait de l’existence de “promotions” et de “barèmes dérogatoires”. Si bien qu’au bout d’un temps, les méthodes qui réalisaient le calcul étaient criblées de portions de code de ce type:

if( je suis dans ce cas) {
  +20 lignes de code
}

Les méthodes ont rapidement atteint plusieurs centaines de lignes, dépassant parfois le millier.
Ce à quoi j’ai répondu simplement:

– Il suffit de remplacer “+20 lignes de code” par une méthode privée au sein de ta classe.
– Oui, mais au final la classe fera toujours plus de 1000 lignes et sa taille continuera de croître.
– C’est vrai, mais il vaut mieux avoir 100 méthodes de 10 lignes que 10 méthodes de 100 lignes ou pire une méthode de 1000 lignes

A ce niveau là, il y’a deux points de vues:

– Effectivement on aura toujours +1000 lignes donc autant laisser comme ça

et dans ce cas, la lecture de cet article ne devrait plus vous intéresser. Ou alors

– 100 méthodes de 10 lignes, on peut mieux faire et améliorer encore cette classe en la découpant en plusieurs classes

Pour ceux qui sont en accord avec le premier point de vue voici tout de même quelques arguments pour finir de vous convaincre et vous rallier à la cause de la qualité logicielle. Pour les autres, vous pouvez passer à la conclusion.

Les numéros de téléphone ne dépassent pas 10 chiffres

Cette affirmation est vraie pour la quasi totalité des pays et lorsque ce n’est pas le cas, il existe une numérotation locale qui permet de descendre en dessous de ce nombre.

Nous ne sommes pas tous rainman

La raison à cela se trouve entre nos deux oreilles. Généralement, notre mémoire à court terme ne retient qu’un nombre restreint d’éléments (entre 7 et 10). C’est cette mémoire que nous utilisons dans des tâches qui nécessitent de la concentration ou de la conceptualisation. Comme c’est le cas de manière intensive lorsqu’on programme une application informatique.

Au delà, on entre dans un processus de mémorisation à plus long terme basé sur de la matérialisation d’idées plus que sur des faits. Comme c’est le cas lorsqu’on lit un roman: On ne retient pas toutes les pages et toutes les actions, mais on mémorise et construit globalement l’histoire. Ce qui est sujet à l’imagination et non pas à la mémorisation. C’est ce qui fait d’ailleurs qu’un même lecteur  peut lire plusieurs fois un même extrait et le percevoir de manière comme  différente.
La lecture d’une méthode de plusieurs centaines de lignes s’apparente davantage à ce processus ce qui fait que le développeur perds en concentration et en précision.

Mémoriser peu, retenir beaucoup

Dans le cas contraire, la mémorisation de 7 verbes ordonnés ne pose généralement aucun problème à la plupart des individus. C’est encore plus simple si il existe un ordre “logique” entre ces verbes: Par exemple:

se lever
se laver
s'habiller
manger
partir travailler
rentrer chez soi
dormir

Il est ensuite possible d’entrer dans le détail de chacun de ses verbes, je peux par exemple détailler en 7 actions le fait de “se laver” ou tout autre action. Ce qui me permettrait par exemple de définir et de retenir un enchaînement de 49 actions. Tout en ne travaillant que sur des unités de travail facilement mémorisables.

Diviser pour mieux régner

Ces simples constats vont dans le sens d’une simplification des méthodes au sein de la classe: Il suffit de penser à découper les actions d’une méthode au sein d’actions plus petites et des les invoquer dans un ordre logique.
De cette façon, la lecture de la méthode est plus facile puisqu’elle s’apparente une mémorisation d’actions courtes. Les anomalies présentes sont alors plus faciles à détecter. Pour reprendre notre exemple, imaginez la suite suivante:

se lever
dormir
se laver
s'habiller
manger
partir travailler
rentrer chez soi

L’anomalie saute aux yeux, alors que si j’avais donné la séquence des 49 actions, elle serait bien plus difficille à détecter.

La qualité logicielle: un travail de fond

Le nombre de lignes d’une méthode est la métrique de base qui permet de s’attaquer à des problèmes de maintenabilité du code. Il ne faut pas perdre de vue le fait qu’il s’agit de la première métrique, celle qui va aider à poser les jalons de l’amélioration continue de la qualité.

Parmi ces jalons, les plus importants sont:
– La réduction du nombre de lignes de code dans une classe
– La réduction du manque de cohésion d’une classe (trop d’attributs dans une classe et les méthodes de la classe n’accède qu’à peu d’attributs)
– La réduction de la complexité cyclomatique

Leave a Reply

Your email address will not be published. Required fields are marked *