Ma première rencontre avec un outil automatisé d’aide au développement logiciel remonte à ma troisième année d’école d’ingénieur en option ingénierie du logiciel. L’outil en question, dont j’ai oublié le nom, évaluait la qualité du code par le calcul d’un lot de métriques et leur comparaison avec des seuils prédéfinis. Parmi ces métriques se trouvaient le nombre de lignes de code par fonction, le nombre de lignes de commentaires par ligne de code et la présence de commentaires en cartouche d’une méthode, le nombre d’utilisations d’une fonction ou méthode, etc. Une fonction trop longue – de mémoire, plus d’une centaine de lignes, une fonction non commentée – aussi triviale soit-elle, ou une fonction trop utilisée, déclenchaient des torrents d’insultes de la part de l’outil qui se montrait assez à cheval sur ses principes. Appliqué sans discernement, comme dans les travaux pratiques de ce cours, ce genre d’approche kafkaïenne amène à des sommets de la littérature informatique tels que :
/* Sets the threshold (no shit, it really does) */ public void setThreshold(int threshold) { this.threshold = threshold; }
voire à des abominations du genre :
public void thisMethodIsReallyTooLong() { /* does lots of interesting things, and then, when the metric is about to be exceeded... */ thisMethodIsReallyTooLongPart2(); } public void thisMethodIsReallyTooLongPart2() { /* Now, where were we? */ }
Non seulement la règle a dégradé la lisibilité du code, mais qui pis en fonction de la bonne volonté du compilateur, elle peut même avoir réduit les performances. J’ai appliqué les règles comme on me le demandait et je suis passé à autre chose.
Une fois en situation d’organiser la réalisation de projets pour mes clients, la question des outils s’est posée à nouveau. Editeur de texte, IDE, contrôle de source, générateurs de code, tests unitaires automatisés, intégration continue, déploiement, les outils sont nombreux, résolvent des problèmes très variés et ont des avocats véhéments prompts à l’anathème. En tant que décideur, quels critères appliquer dans ses choix ?
Fidèle à mes principes, je ne m’engage dans la mise en place d’un outil que si il répond à un problème identifié ; je ne pense pas qu’il existe un seul développeur professionnel qui n’ait été confronté à des régressions – « mais je l’avais corrigé ce bug, qui a écrasé mon code ? » – ou à la gestion de versions de ses développements : un système de contrôle de source s’impose donc à tous. A l’inverse, une équipe sortant une version publique tous les ans au plus a-t-elle besoin d’un système d’intégration continue, avec le coût de mis en oeuvre inhérent à ce type d’outil complexe ? Rien n’est moins sûr. Tester voire déployer systématiquement tous les derniers outils à la mode en évaluant mal leur pertinence dans le contexte local est un indicateur certain du mauvais décideur.
Par ailleurs, un outil n’est rien s’il n’est pas pris en main par l’équipe. Naturellement, le décideur aura tendance à se méfier des membres de l’équipe qui auront soutenu vocalement d’autres outils que celui de son choix. Le « fanboy » d’un outil concurrent induit effectivement un risque, mais il est une quantité connue : il sera mécontent que sa préférence ait été mise de côté, mais ayant compris ce que pouvait apporter ce type d’outil, il sera probablement à même d’utiliser correctement le choix du décideur – à moins d’être une tête de cochon n’ayant pas très bien intégré les notions d’équipe et de compromis, auquel cas il serait sans doute mieux tout seul, mais c’est une autre histoire.
La passivité est bien plus pernicieuse, car elle est la marque soit d’un désintérêt total pour la question, soit d’une incompréhension des enjeux, et au pire d’une incapacité à intégrer correctement l’outil dans sa pratique quotidienne.
On l’a vu, appliquer à la serpe des métriques amène à des aberrations ; l’usage correct est donc d’utiliser les seuils comme des avertissements à traiter manuellement avec discernement. Mais encore faut-il comprendre l’avertissement, ne pas simplement le désactiver pour avoir la paix, et le traiter correctement – par exemple analyser une fonction longue pour déterminer si elle n’est pas découpable en unités signifiantes plus petites, mais ne pas la charcuter pour le plaisir. Utiliser des branches pour matérialiser des lignes de développement séparées – la version 1.0 en cours de maintenance, la version 1.1 contenant des évolutions mineures et la version 2.0 qui refond l’architecture du logiciel – est une très bonne chose, encore faut-il les créer à bon escient et savoir effectuer les merge en bout de ligne.
Par conséquent, de même qu’un outil résolvant un problème ne se posant pas est contre-productif, un outil que l’équipe n’est pas assez mature ou organisée pour utiliser correctement est plus dangereux que l’absence d’outil.
Pour paraphraser Jean Bodin, il n’est d’outil que d’homme.
Merci pour toutes ces infos, voici une bonne lecture. J’ai appris différentes choses en vous lisant, merci à vous. Fabienne Huillet http://www.neonmag.fr