Deux personnes regardant du code logiciel sur un écran

Qu’est-ce que la qualité du code ?

Qualité du code et comment l’améliorer

La qualité du code fait référence à la robustesse du code, au-delà du simple fait qu'il s'exécute ou non et qu'il remplit la fonction souhaitée. Un code de haute qualité se distingue par son efficacité, sa maintenabilité, sa lisibilité et sa réutilisation, tandis qu'un code de faible qualité est fragile, difficile à analyser et susceptible d'accumuler une dette technique au fil du temps.

Des normes de codage élevées sont au processus de développement de logiciels ce qu'une bonne mise en place et un « travail propre » sont au fonctionnement d'une cuisine commerciale. Les pratiques qui améliorent la qualité de votre code peuvent offrir de meilleures fonctionnalités à court terme, mais leurs avantages les plus importants sont moins de problèmes, une progression plus rapide et des coûts de maintenance plus faibles sur le long terme.

Les avantages à long terme d'un code de meilleure qualité peuvent parfois être difficiles à communiquer par les programmeurs à des responsables moins versés dans les détails du cycle de développement des logiciels. L’équilibre entre les avantages globaux d’un code optimal et les pressions immédiates liées aux priorités de l’entreprise implique souvent des compromis complexes. Cela dit, une étude de 2022 portant sur 39 bases de code de production propriétaires a notamment affirmé¹ que : 

  • La dette technique liée au code précipité peut faire perdre jusqu’à 42 % du temps des développeurs.

  • Un code de faible qualité entraîne 15 fois plus de défauts qu'un code de haute qualité.

  • La résolution des problèmes liés à un code de faible qualité prend (en moyenne) 124 % de temps de plus que la résolution des problèmes liés à un code de haute qualité.

Un code de meilleure qualité facilite et accélère la compréhension, le remaniement, le débogage et l'ajout de nouvelles fonctionnalités à une base de code. Un code clair, cohérent et bien écrit facilite une meilleure coordination entre les équipes de développement et réduit la complexité et les complications des modifications de code. Elle permet non seulement d'améliorer la qualité des logiciels, mais aussi de renforcer l'expérience des développeurs et l'expérience des utilisateurs.

Le fait qu'un morceau de code se compile et exécute avec succès son objectif au moment de l'exécution ne suffit pas à déterminer sa qualité globale. Écrire du code, ce n’est pas comme jouer un jeu de mots croisés, dans lequel il existe une seule façon de mener à bien votre tâche : il existe souvent d’innombrables solutions à un problème de codage donné. La fonctionnalité représente donc le simple code acceptable. La valeur d'un code de haute qualité se manifeste dans ses effets secondaires sur le contexte qui l'entoure.

Qu’est-ce qui définit une qualité de code élevée ?

Le code de haute qualité est un concept relativement abstrait. La qualité globale d’un morceau de code est définie autant par la manière dont il est créé et interagit avec la base de code plus large qu’il contient que par tout ensemble spécifique d’indicateurs de qualité de code discrets et objectifs (bien qu’il existe de nombreux indicateurs de ce type).

Les caractéristiques courantes d’un code de haute qualité sont les suivantes :

  • Lisibilité : La lisibilité du code est essentielle à la maintenance, au débogage et à la coordination entre les équipes et dans le temps. Un autre membre de l’équipe peut-il facilement comprendre votre code ? Un autre programmeur, qui travaillera dans plusieurs années, pourra-t-il interpréter votre code avec précision sans que vous soyez là pour lui fournir le contexte ?

  • Maintenabilité : La complexité du code est souvent inversement proportionnelle à sa maintenabilité. Votre code est-il facilement testable, permettant à votre équipe de l’évaluer efficacement pour détecter des vulnérabilités de sécurité et des opportunités d’optimisation ? Est-il suffisamment robuste pour permettre l'ajout de nouvelles fonctionnalités sans briser les fonctionnalités de base, ou est-il trop fragile pour être ajusté sans nécessiter une refonte majeure ? Donner la priorité au code maintenable peut entraîner des contraintes supplémentaires en amont, mais permet d’économiser beaucoup de temps et d’énergie à l’avenir.

  • Efficacité : Un code bien écrit peut réduire la latence et la consommation de ressources d’un système. Par exemple, des structures de données soigneusement choisies peuvent minimiser le nombre d'opérations sur le processeur requises pour une fonction donnée. Des stratégies réfléchies de mise en cache des données permettent de réduire les opérations d'entrée/sortie (E/S) coûteuses en éliminant les requêtes redondantes dans les bases de données et les requêtes réseau, tandis que la libération rapide de la mémoire inutilisée évite de surcharger inutilement la mémoire vive.

  • Fiabilité : Moins de défauts et des structures résistantes aux changements de code signifient des pannes et des temps d'arrêt moins fréquents. La fiabilité est essentielle à l'expérience et à la confiance des utilisateurs, ainsi qu'à la santé des systèmes critiques dont dépend votre entreprise.

Dans un article paru dans la Harvard science des données Review en 2023, des chercheurs de l'Université Calvin, du Amherst College et de Columbia ont proposé un cadre des exigences pour un code de qualité : « Les quatre C » ²

  • Exactitude : le code fait ce qu'il est censé faire. Les auteurs ont souligné deux corollaires de cette inclusion évidente : « Tout d’abord, l’exactitude est un indicateur nécessaire mais insuffisant pour un code de qualité. Deuxièmement, les autres objectifs soutiennent et promeuvent la justesse. »

  • Clarté : Toute personne lisant et écrivant le code peut comprendre son objectif et apporter intuitivement les modifications nécessaires.

  • Confinement : évitez la prolifération, la redondance et les dépendances inutiles. Un confinement approprié implique, entre autres, « l’utilisation de fonctions pour contenir le code réutilisable et le maintien du code utilisé dans plusieurs fichiers ou projets au sein d’un module ou d’un package ».

  • Cohérence : Une base de code doit maintenir une cohérence interne au niveau du style, des conventions de dénomination, des commentaires, de l'indentation et d'autres pratiques.

Alors que le développement logiciel moderne continue d’être de plus en plus piloté par des assistants de codage agentique tels qu’ IBM Bob, le confinement et la cohérence sont particulièrement utiles pour maximiser l’efficacité et la précision des outils automatisés. Cela dit, la capacité des plateformes de nouvelle génération comme IBM Bob à identifier les opportunités de refactorisation de l'IA en temps réel peut réduire les efforts nécessaires pour appliquer ce niveau de discipline stylistique.

Bonnes pratiques pour un code de haute qualité

Bien que chaque langage de programmation et chaque cas d'utilisation aient leurs propres nuances et considérations granulaires, il existe quelques bonnes pratiques universelles pour un code de qualité dans n'importe quel scénario.

Une des approches pour conceptualiser un code de haute qualité consiste simplement à penser de lui comme un code qui évite autant de marqueurs de mauvais code que possible, ce que nous allons découvrir plus loin dans cet article.

Pour une approche plus normative, l'article de la Harvard Review des sciences des données (HDSR) précité présente une série de lignes directrices visant à garantir la qualité du code. Bien que ces lignes directrices soient ostensiblement optimisées pour les besoins des data scientist, la plupart sont applicables à toutes les disciplines de codage.

Choisissez de bons noms

De solides conventions de dénomination sont essentielles à la lisibilité et à la cohérence du code. Les auteurs suggèrent les pratiques suivantes :

  • La longueur des noms doit être proportionnelle à leur portée. Plus la distance entre la définition initiale d'un terme et son utilisation est grande, que ce soit en termes de temps, de lignes de code ou de structure organisationnelle, plus il est essentiel que son nom indique clairement son rôle.

  • Conservez un condensé d’abréviations. Les noms de variables courts ou composés d'un seul caractère peuvent aider à désencombrer le code, mais ils peuvent aussi devenir impénétrables pour les personnes qui ne connaissent pas le projet. Le fait de conserver une sorte de « glossaire » atténue ce compromis.

  • Utilisez la majuscule de manière cohérente. Il est également judicieux d'éviter les cas où deux noms sont différenciés uniquement par leur majuscule.

  • Évitez les noms non descriptifs. Ils augmentent considérablement la difficulté d'interprétation des codes.

  • Choisissez des conventions de dénomination de fichiers qui s'imposent naturellement. Par exemple, vous pouvez adopter la norme ISO 8601 pour la date et l'heure, ou remplacer les chiffres par des 0 pour qu'ils aient tous le même nombre de chiffres.

Des conventions de dénomination claires et cohérentes peuvent également aider à simplifier la tâche des assistants de codage basés sur l'IA et à améliorer la précision de leurs résultats. Par exemple, plutôt que de demander à un agent d’inspecter certains types de variables ou de découvrir tous les fichiers d’une certaine période, ce qui pourrait nécessiter que votre agent IA déduise du contexte quelles variables ou fichiers répondent aux critères, vous pouvez explicitement prompt un agent pour découvrir tous les fichiers en commençant par un numéro spécifique, ou toutes les variables avec un nom spécifique.

Suivez systématiquement un guide de style

En plus de codifier des conventions de nommage fortes, un guide de style complet devrait idéalement standardiser les éléments de formatage, y compris l’utilisation des espaces blancs et des indentations, les types de commentaires et de données, ainsi que les « dialectes de codage ». On peut trouver sur GitHub un large éventail de guides de style éprouvés pour différents langages de programmation, tels que ceux inclus dans cette liste sélectionnée.

Un guide de style est également une référence inestimable pour un assistant de codage IA, servant de contexte pour des tâches spécifiques ou même faisant partie du prompt système de votre agent IA.

Sélectionner une boîte à outils cohérente et minimale (mais adéquate)

L’utilisation des outils et des bibliothèques est un atout naturel pour la réutilisation et l’efficacité du code, ce qui permet de standardiser les workflows et les sorties entre les différentes équipes et d’accélérer considérablement la création de code. Ils sont particulièrement utiles lorsque le code doit gérer des interactions avec des systèmes tiers complexes ou gérer des problèmes répétitifs « résolus ».

Un recours excessif aux outils peut toutefois engendrer des hausses inutiles et introduire des dépendances externes, réduisant ainsi la robustesse et la maintenabilité du code. Ils ont également tendance à faire abstraction de la logique sous-jacente du code, ce qui diminue sa lisibilité. Les auteurs du rapport sur la santé et la sécurité au travail (HDSR) expriment l'équilibre idéal en termes simples : « Nous voulons que notre boîte à outils soit aussi simple que possible, mais pas plus simple. »

Ne vous répétez pas (DRY)

Si vous vous retrouvez à copier, coller et modifier fréquemment les mêmes blocs de code, il est préférable d’utiliser une fonction qui encapsule le code répété au même endroit. Les paramètres de cette fonction peuvent refléter les éléments qui changent d'une instance à l'autre. Cela nettoie le code et simplifie la maintenance, car cela vous permet d'ajuster toutes les instances de cette fonction en une seule étape et en un seul endroit (au lieu de régler chaque doublon d'un bloc de code individuellement).

Effectuer des vérifications de cohérence

Les vérifications de cohérence sont des validations automatisées qui Verify si les données potentielles ou les états du système respectent des règles et conventions logiques prédéfinies, aidant ainsi à éviter et à prendre en compte les conflits et contradictions imprévus dans le code. Ces tests automatisés sont généralement un composant standard et critique des pipelines CI/CD (intégration continue/déploiement continu).

C'est un exemple typique de l'importance de la testabilité du code. Il est difficile voire impossible de concevoir des tests unitaires qui valident de manière exhaustive chaque fonction si votre code est trop complexe ou contient trop de dépendances fortement couplées.

Appliquer le contrôle des versions

Les systèmes de contrôle de version favorisent la cohérence, le contrôle de la qualité, la coordination et les processus d'avis du code au sein des équipes. Lorsque vous utilisez des environnements de programmation pilotés par l’IA, en particulier ceux qui peuvent ajuster votre base de code de manière autonome, assurez-vous de disposer d’un moyen d’annuler facilement toute modification indésirable ou indésirable. IBM Bob, par exemple, met automatiquement en version vos fichiers d'espace de travail en tant que points de contrôle, ce qui permet de revenir facilement sur les modifications apportées au code, le cas échéant.

Qu’est-ce qui définit un code erroné ?

De manière générale, un mauvais code est difficile à lire et à maintenir, fragile face aux changements et aux nouvelles fonctionnalités, inefficace et peu fiable. Il présente souvent des fonctionnalités inutiles, dans lesquelles différents modules sont étroitement liés les uns aux autres et toute modification de l'un nécessite un travail supplémentaire pour ne pas casser l'autre. Il manque de documentation adéquate et est mal organisé, dépourvu de structure cohérente et logique, une situation souvent qualifiée de « code spaghetti ».

Le mauvais code est souvent dû non seulement à de faibles compétences en matière de codage, mais aussi à de mauvaises incitations et à une mauvaise structure organisationnelle : le fait de donner la priorité au lancement de fonctionnalités au détriment de la qualité du code permet généralement d'accélérer la mise sur le marché, mais d'accroître les complications futures et la dette technique.

Il est important de se rappeler que le mauvais code fonctionne souvent — du moins temporairement. La dette technique ne s’accumulerait pas si ce n’était pas le cas, car il faudrait indéniablement corriger le code défectueux. Refactoring : Improving the Design of Existing Code, le livre fondamental de Martin Fowler et Kent Beck publié pour la première fois en 1999 (et mis à jour plusieurs fois depuis), utilisait donc le terme code smells pour décrire un mauvais code. Il ne s'agit généralement pas de bogues qui n'empêchent pas fondamentalement un programme de fonctionner, mais ils indiquent des faiblesses de conception et des problèmes de qualité du code susceptibles de ralentir le développement ou de provoquer des bogues à l'avenir.

La liste de Fowler et Beck sur les odeurs de code dont il faut se méfier comprend des exemples tels que :

  • Fonction longue (méthode longue) : une méthode contenant trop de lignes de code.

  • Classe volumineuse : une classe qui tente d’en faire trop et qui contient trop de variables, manquant de cohésion.

  • Obsession primitive : utiliser des types de données primitifs au lieu de petits objets spécialisés.

  • Nom mystérieux : fonctions ou variables mal nommées, cachant leur intention réelle.

  • Groupes de données : groupes de variables qui apparaissent fréquemment ensemble partout.

  • Éléments paresseux : classes ou fonctions qui font trop peu pour exister.

  • Longue liste de paramètres : Fonctions nécessitant trop d'arguments pour fonctionner correctement.

  • Chirurgie au fusil de chasse : une modification nécessite de modifier de nombreux modules éparpillés simultanément (ce qui est essentiellement le contraire d'une classe importante).

  • Code dupliqué : structures de code identiques ou très similaires réparties à plusieurs endroits.

Vous trouverez ici une liste complète des « odeurs de code », accompagnée d'explications, d'exemples et de citations. Leur présence indique généralement qu'une refactorisation est nécessaire. Une compréhension approfondie, à l'échelle de l'entreprise, de ces questions et des complications qui en découlent est utile pour établir une conception commune des normes de qualité au sein des équipes de développement.

AI Academy

L’essor de l’IA générative pour les entreprises

Découvrez l’essor historique de l’IA générative et ce que cela signifie pour les entreprises.

Mesurer la qualité du code

La mesure de la qualité du code doit toujours comporter une évaluation à la fois qualitative et quantitative. Si les indicateurs tels que la complexité cyclomatique peuvent être utiles, ils peuvent également être trompeuses sans un contexte approprié.

Par exemple, votre équipe pourrait écrire une suite de tests automatisés et votre code pourrait atteindre une couverture de code de 100 % sur une batterie de tests unitaires. Mais si la suite de tests ne dispose pas de certaines des assertions significatives nécessaires pour valider véritablement que votre code fonctionne pleinement comme il se doit, la fausse confiance issue de cette couverture de test pourrait faire plus de mal que de bien.

De même, une structure d'avis robuste devrait inclure à la fois un avis manuel du code et un avis de code IA. Un outil de codage agentiel moderne comme IBM Bob peut effectuer une analyse statique et une refactorisation de code approfondies en temps réel, mais il tire un avantage considérable de règles personnalisées et modes personnalisés qui reflètent les besoins et les intentions spécifiques du développeur. Les humains ne sont pas exhaustifs et l'IA n'est pas infaillible, mais l'étayage de l'un par l'autre est le moyen le plus sûr de confirmer que tous les problèmes potentiels ont été examinés dans le contexte approprié.

N’oubliez jamais que la qualité du code dépend du contexte. Imaginez qu’un programmeur de votre équipe ait écrit un algorithme ou un bloc de code éloquent, efficace et parfaitement articulé, qui remplit parfaitement la fonction prévue. Si le problème aurait pu être résolu efficacement en utilisant une fonction standard de la bibliothèque intégrée avec laquelle tout le monde est déjà familiarisé, ce code éloquent est en fait un problème de qualité parce qu'il ajoute une complexité inutile et une surcharge mentale.

Auteur

Dave Bergmann

Senior Staff Writer, AI Models

IBM Think

Solutions connexes
IBM Bob

Accélérez la livraison de logiciels grâce à Bob, votre partenaire IA pour un développement sécurisé et sensible aux intentions.

Découvrir IBM Bob
Solutions de codage basé sur l’IA

Optimisez les initiatives de développement logiciel à l’aide d’outils fiables pilotés par l’IA qui minimisent le temps consacré à l’écriture de code, au débogage, à la refactorisation ou à la complétion du code et laissent plus de place à l’innovation.

Découvrir les solutions de codage basé sur l’IA
Conseils et services en matière d’IA

Réinventez les workflows et les opérations critiques en ajoutant l’IA pour optimiser les expériences, la prise de décision et la valeur métier en temps réel.

Découvrir les services de conseil en IA
Passez à l’étape suivante

Exploitez l’IA générative et l’automatisation avancée pour créer plus rapidement du code prêt à l’emploi. Les modèles Bob augmentent les compétences des développeurs, en simplifiant et en automatisant vos efforts de développement et de modernisation.

  1. Découvrez IBM Bob
  2. Découvrir les solutions de codage basé sur l’IA
Notes de bas de page

1.« Code red: l'impact commercial de la qualité du code – une étude quantitative de 39 codebases de production propriétaire », Actes de la conférence internationale sur la dette technique (consulté sur l’Association for Computing Machinery Digital Libtary), 16 août 2022

2. « Favoriser de meilleures pratiques de codage pour les data scientists », Harvard Data Science Review, 27 juillet 2023