skip to Main Content
Welcome to our digital content blog!. We're excited to have you here and we hope you find the information on our site valuable.
Web

Des règles simples pour écrire du code de qualité

Certaines pratiques et règles simples et faciles à observer permettent de produire du code de bonne qualité. Ces pratiques concernent le nommage, la longueur et la visibilité des artefacts, l’utilisation du constructeur, les commentaires, les tests, le refactoring et bien d’autres aspects. Voyons cela ensemble.

Nommage des variables, classes et méthodes

Il est conseillé d’éviter les abréviations, les noms à une lettre (int a), les noms impossibles à prononcer. Au lieu de mettre un commentaire pour dire à quoi sert une variable, une classe ou une méthode, mieux vaut lui donner un nom auto-descriptif, même si cela revient à utiliser un nom long. Avoir des noms clairs et adaptés au contexte facilite la lecture et la compréhension du code ainsi que sa maintenabilité. Un nom clair se suffit à lui-même et le besoin en commentaire est fortement réduit. Le compilateur se chargera d’optimiser les noms pour vous.

Les commentaires

Les commentaires peuvent être utiles, mais il faut en user avec parcimonie. Avant d’ajouter des commentaires au code, il convient d’essayer au préalable de rendre le code autoporteur. Plusieurs raisons plaident pour une utilisation limitée des commentaires:

  • Si le commentaire décrit le code, alors il est redondant, et donc inutile. C’est le cas des commentaires qui disent à quoi sert une variable, ou qui sont des redites de la logique d’implémentation d’une méthode. Si un nom de variable ou de méthode n’est pas suffisant pour savoir à quoi elle sert, il faut lui trouver un meilleur nom, plutôt que d’ajouter un commentaire.
  • Si le code n’est pas compréhensible, alors il sera difficile de trouver un commentaire clair et succinct pour le décrire. Ou bien alors l’auteur du commentaire est en mesure de rendre le code compréhensible, et dans ce cas, il devrait le faire.
  • Les commentaires sont rarement mis à jour lorsque le code évolue, ce qui aboutit à des commentaires inadaptés, inutiles, ou, au pire, qui induisent en erreur.
  • La lecture des commentaires consomme du temps, sans qu’on ait la garantie que le code fait ce que dit le commentaire.

Il y a cependant des cas où un commentaire est utile. C’est le cas notamment:

  • Lorsqu’on est conscient d’implémenter une logique complexe, que le code seul n’arrive pas à expliquer clairement.
  • Lorsqu’on est conscient d’écrire un code non intuitif, ou qu’on écrit le code de façon inattendue. Le commentaire sert alors à expliquer pourquoi on l’a écrit comme cela.
  • Lorsqu’on est conscient que le code qu’on écrit n’est pas optimal, sans être en mesure de l’améliorer, soit par manque de temps, soit qu’on ne sait pas comment mieux faire. Le commentaire peut expliquer en quoi le code n’est pas optimal.

Une règle simple consiste à toujours se demander: le commentaire n’est-il pas redondant avec le code? ne peut-il pas être remplacé par un code mieux écrit, plus compréhensible? Dans tous les cas, il faut veiller à commenter ce que fait le code (what), pas comment il le fait (how).

Visibilité minimale pour les méthodes et les variables.

Il y a plusieurs niveaux de visibilité pour une variable ou une méthode : public, package-level, protected, private. Il vaut mieux restreindre la visibilité autant que possible, en préférant la visibilité private. En effet, tout ce qui n’est pas private constitue une interface avec le reste du monde, une sorte de contrat. Dès l’instant où le code est publié, on ne contrôle plus qui utilise ni comment sont utilisées nos variables ou méthodes public, protected, package-level. Les modifications sur des méthodes ou des variables qui ne sont pas privées sont susceptibles de provoquer des erreurs pour d’autres développeurs. Des exemples de modifications à risque lorsque la visibilité n’est pas private:

  • Changement de nom d’une variable ou d’une méthode
  • Changement de signature d’une méthode
  • Changement du type d’une variable, ou du type de retour d’une méthode.
  • Restriction ultérieure de visibilité, par exemple passer de protected à private.
  • Changement de la logique d’une méthode.

Il est judicieux de commencer avec la visibilité la plus restrictive possible, et l’augmenter plutard si besoin.

Tester toutes les méthodes publiques

Les méthodes publiques constituent une interface, un contrat avec l’extérieur. Elles sont susceptibles d’être utilisées par d’autres développeurs, parfois de façons totalement imprévues. Il est nécessaire de s’assurer de ne pas rompre ce contrat, ou alors de le faire de façon totalement consciente et assumée. Les tests unitaires donnent l’assurance que toute modification du service rendu par ces méthodes sera repérée.

Utiliser le constructor uniquement pour l’initialisation des variables

Il convient de réserver le constructeur à l’initialisation des variables. Ce qu’il faut éviter de faire dans un constructeur:

  • Mettre une logique métier.
  • Faire des appels de méthodes autres que des méthodes d’initialisation de variables.
  • Faire des requêtes distantes directement à partir du constructeur.

Faire des appels de méthode directement dans le constructeur complique les tests. On perd de la flexibilité dans l’utilisation des objets de la classe concernée car le code contenu dans le constructeur est exécuté à l’instanciation de l’objet. Cela occasionne aussi des appels précoces et souvent inutiles, car celui qui instancie l’objet n’est pas toujours celui qui a besoin des services rendu par cet objet.

Préférer les objets immuables

Les objets immuables ne peuvent pas être modifiés une fois créés. C’est une assurance qu’on peut passer l’objet en paramètre où on le souhaite sans se soucier des effets de bord. Cela facilite grandement l’écriture ainsi que la lecture du code. De même, il faut préférer les attributs immuables autant que possible.

Refactoring régulier pour améliorer la qualité du code.

Le refactoring consiste à réécrire du code existant pour en améliorer certains aspects. Il répond à plusieurs besoins:

  • Maintenir ou améliorer l’architecture et la cohérence globale du code.
  • Adapter l’architecture ou l’implémentation du code pour supporter de nouveaux besoins.
  • Simplifier ou clarifier le code existant.
  • Améliorer le code lorsqu’on découvre de meilleures façons de faire.
  • Tirer profit des nouveautés du langage.

Le refactoring ne doit pas provoquer un changement fonctionnel. Le code fonctionne toujours comme avant, mais s’en trouve amélioré, mieux structuré.

Supprimer le code inutilisé

Conserver du code inutilisé crée de la confusion, une complexité et un effort de lecture inutile. Un bout de code non utilisé nuit à la maintenabilité du code et peut avoir un effet dissuasif sur les améliorations ou les évolutions possibles. On paie inutilement un effort de maintenance. Si on a besoin ultérieurement d’un bout de code qu’on a supprimé, on pourra le retrouver via l’historique du logiciel de gestion du code source. Supprimer du code inutilisé évite à d’autres de devoir se poser la question sur l’utilité de ce bout de code. Cela réduit aussi la taille du code source.

Ne pas mettre du code en commentaire

Mettre en commentaire un bout de code n’a aucune utilité, tout en ayant des effets négatifs: classes et méthodes plus longues, base de code plus volumineux, distraction, effort de lecture plus important. C’est de la pollution. Lorsqu’un bout de code n’est plus nécessaire, il faut le supprimer pour garder une base de code propre. On peut toujours le retrouver dans l’historique du logiciel de gestion du code source.

Éviter les blocs de code imbriqués.

Les blocs de code imbriqués nuisent à la lisibilité du code et demande un effort élevé pour empiler et dépiler mentalement ces blocs afin de comprendre le flux d’exécution du programme. Il est préférable de limiter le niveau d’imbrication à deux ou trois. La complexité cyclomatique d’une méthode est le nombre de chemins linéairement indépendants qu’il est possible d’emprunter dans cette méthode. Plus il y a d’imbrications, plus la complexité cyclomatique est élevée, ce qui signifie que la méthode est plus difficile à lire, à comprendre et à tester

Ne pas écrire plus de code que ce qu’il en faut

Il est presque toujours inutile d’anticiper des fonctionnalités futures. Il faut écrire le code nécessaire à la fonctionnalité sur laquelle on travaille, et pas une ligne de plus. Ecrire du code en prévision d’une fonctionnalité future à plusieurs inconvénients:

  • On complexifie le code actuel plus que nécessaire.
  • Cela aboutit à un effort inutile si la fonctionnalité anticipée n’est finalement pas implémentée, ou est implémentée différemment de ce qu’on avait anticipé.
  • On crée de la confusion pour les autres développeurs, qui se demanderont pourquoi ce code a été ajouté alors qu’on en a pas besoin.

Longueur des artéfacts (méthode, classe, package)

Plutôt que d’avoir une longue méthode qui fait plusieurs choses à la fois, préférez un enchaînement de méthodes courtes, d’une dizaine de lignes de code, ayant chacune une responsabilité claire. Les méthodes courtes sont plus faciles à lire, à comprendre, à modifier et à tester. De façon similaire, sur le wiki de Ward Cunningham, il est préconisé de limiter le nombre de méthodes dans une classe à une dizaine environ. Cela permet de focaliser la classe sur une responsabilité. On y gagne en lisibilité, clarté, facilité de compréhension. De même, il est préférable de limiter le nombre de classes dans un package. Une dizaine de classes par package est raisonnable.

On peut en déduire la règle de 10:

  • 10 lignes de code par méthode
  • 10 méthodes par classe
  • 10 classes par package

Principe de la responsabilité unique

Le principe de la responsabilité unique prescrit que chaque méthode, chaque classe, doit avoir une et une seule responsabilité, c’est-à-dire ne s’occuper que d’un seul aspect fonctionnel du logiciel. Le code qui obéit à ce principe est facile à comprendre, et surtout à modifier car chaque artefact ayant une seule responsabilité, on sait ou regarder selon le besoin.

Si une méthode implémente à la fois la logique de création, modification et suppression d’une ressource, alors elle fait trois choses à la fois et devrait être séparée en trois méthodes différentes. De même, si une classe est à la fois chargée de créer un employé et de calculer son salaire, alors elle a deux responsabilités et devrait être séparée en deux classes différentes.

Share this Article
Further Reading
Trending Articles

[comments_number]

This Post Has 3 Comments

  1. Nunc pretium, odio nec rhoncus vehicula, ligula tellus tristique tortor, at ultricies dui dui et sem. Phasellus venenatis scelerisque facilisis. Sed et magna id elit dapibus iaculis quis vitae risus. Curabitur condimentum, lorem nec cursus aliquam, ante tellus semper ante, ut aliquam dui sapien vel mi.

    1. Vivamus porta turpis ac urna posuere dignissim dapibus felis facilisis. Suspendisse congue ligula non quam dictum dignissim. Nunc pretium, odio nec rhoncus vehicula, ligula tellus tristique tortor, at ultricies dui dui et sem. Phasellus venenatis scelerisque facilisis. Sed et magna id elit dapibus iaculis quis vitae risus. Curabitur condimentum, lorem nec cursus aliquam, ante tellus semper ante, ut aliquam dui sapien vel mi.

  2. Nunc pretium, odio nec rhoncus vehicula, ligula tellus tristique tortor, at ultricies dui dui et sem. Phasellus venenatis scelerisque facilisis. Sed et magna id elit dapibus iaculis quis vitae risus.

Comments are closed.

Back To Top
Verified by MonsterInsights