Banière du site

[koala01.free.fr]->Tutoriaux->Principes de Programmation ->Pour un code propre

Image d'imprimante   image d'enveloppe

2.1 Plaidoyer pour un code propre

Quel que soit le langage de programmation utilisé il y a très facilement moyen de rendre le code créé parfaitement incompréhensible.

Si l'idée peut parraître tentante, dans le but de se rendre indispensable dans une équipe, ou plus simplement pour «protéger ses sources», il s'agit en réalité d'un très mauvais plan.

En effet, il faut bien être conscient que le code qui vous parraît limpide aujourd'hui, alors que vous savez pertinemment bien ce que vous venez de faire, d'où vous venez et où vous allez, peut vous sembler beaucoup plus nébuleux demain, dans cinq jours... ou dans trois mois...

Peut-être vous dites-vous que, de toutes façons, vous n'aurez pas à relire votre code dans si longtemps?   S'il y a bien une chose que l'expérience m'a apprise, parfois à mes dépends, c'est que m'alheureusement, dans la vie, on ne peut être sûr que d'une seule chose: on ne peut être sûr de rien...  Et même cela, il est permis d'en douter...

Entre madame qui râle parce que vous êtes encore devant l'ordinateur à minuit, le chien à sortir, le gamin qui se casse une jambe et simplement, le manque d'envie ou d'inspiration, ou encore le fait qu'à l'usage vous estimiez utile d'apporter une amélioration ou de résoudre un problème qui n'était pas apparu lors de la conception, il y a mille et une raisons qui font que vous serez souvent amené à décider de continuer votre programmation plus tard...

Et c'est, justement, en prévision de ce «plus tard» qu'il est utile de prévoir de savoir se relire...

Pour se donner un maximum de chances d'arriver à se relire, quelques règles simples suffisent:

fleche haut

2.2 Une ligne, une instruction

La plupart des langages ont une manière particulière de représenter soit la fin d'une instruction, soit le fait qu'un instruction continue sur la ligne suivante, et parfois même les deux.

Si on est en mesure de marquer la fin d'une instruction, cela signifie souvent qu'il est possible de mettre plusieurs instructions sur une même ligne.

Le langage permissif que j'ai mis au point pour ce tutoriel indique la fin d'une instruction par un «pipe»" | ", et autorise, bien évidemment, l'écriture de plusieurs instructions sur une même ligne, ainsi que la continuation d'une instruction sur la ligne suivante…

La seule contrainte étant que le passage à la ligne ne se fasse pas au beau milieu d'un nom de variable ou de valeur…  Ce qui est d'ailleurs le cas de la plupart des langages.

Cela signifie que les quelques instructions suivantes seraient parfaitement autorisées

   variable1 = 3 | variable2 = 52 |variable3 = 21 | variable4 = 
   variable1 *  ( variable2 + ( variable2 * variable3 / 100 ) ) | 

Vous avouerez, que, même si cette suite d'instructions est logique et juste, il devient rapidement difficile de voir exactement ce qui a été entrepris...

Ne trouvez-vous pas que le fait de passer à la ligne pour chaque instruction rendrait les choses beaucoup plus faciles?

Voyez ce que ça donnerait…

   variable1 = 3 | 
   variable2 = 52 |
   variable3 = 21 | 
   variable4 =  variable1 *  ( variable2 +
   ( variable2 * variable3 / 100 )) | 

Cependant, même si ce code est déjà beaucoup plus compréhensible, il est encore l'exemple parfait qui incite à rajouter la règle suivante...

fleche haut

2.3 Utilisez des noms de variables explicites

En effet, avec le code représenté au chapitre précédent, il reste difficile de comprendre, tout à fait hors contexte comme c'est le cas actuellement, le but de ces instructions…

Voyons si, en utilisant des noms de variables explicites, vous serez en mesure de comprendre à quoi servent ces instructions…

Nombre = 3 |
PrixHTVA = 52 |
TauxTVA = 21 |
TotalTTC=Nombre * (PrixHTVA + (PrixHTVA * TauxTVA / 100)) |

Je suis persuadé que, grâce aux noms que j'ai donnés à mes variables, tout le monde a comrpis, bien que les instructions soient hors contexte, qu'il s'agit simplement de calculer le prix total TVA comprise à payer sur base d'un nombre d'articles, d'un prix hors TVA et du taux de TVA…

les langages de troisième génération permettent d'utiliser des noms d'une taille amplement sufisente pour vous permettre de les choisir à votre guise…

Les seules limites à respecter pour le choix des noms sont:

fleche haut

2.4 Scindez les blocs trop complexes

Pour le code actuel, l'utilité de cette règle peut parraître minime, cependant, quand on a affaire à un bloc trop complexe, on a vite fait de se perdre dans la logique suivie…

Mon langage imaginaire permet, bien évidemment, de créer des tests basés sur les opérateurs, aussi bien logiques que mathématiques, dont le résultat sera vrai ou faux…

Les blocs qui prennent en charge les tests sont mis obligatoirement entre parenthèses.

Les parenthèses peuvent en outre servir à modifier l'ordre habituel des priorités

Comme tous les langages de troisième génération, on a la possiblité de définir un bloc d'instructions à effectuer si le résultat du test est juste et une autre bloc d'instructions si le résultat du test est faux.

Ces blocs d'instructions à effectuer seront mis entre accolades " { } "

Examinons un code sorti tout droit d'une de mes applications, simplement adapté à mon langage imaginaire et au but de ce chapitre:

si(actuel[0]=trouve[id] et actuel[0]≠1 et actuel[0]≠4 et 
actuel[0]≠5 et actuel[0]≠6  et actuel[0]≠7)
{
//les instructions précises n'ont ici aucun inérêt, c'est la raison 
//pour laquelle elles portent des noms simples
instruction1 |
instruction2 |
instruction3 |
}
sinon
{
instruction4 |
instruction5 |
}
instruction6 |
instruction7 |
instruction8 |

Le test sortira «vrai» si l'ensemble des six conditions du test sont vérifiées…

Le bloc des conditions n'a été scindé que pour permettre un affichage correct…

Comme vous pouvez le constater, il est facile de « perdre le fil » des différentes conditions, bien que le seul opérateur logique qui les relie entre elles soit un ET logique…

Imaginez alors si, en plus de mettre des conditions, on les relie entre elles avec toute la gamme d'opérateurs logiques (ET, OU, ET PAS, OU PAS, OU EXClusif, PAS) et si, pour corser encore un peu le tout, on influe sur la priorité de ces opérateurs logiques avec des parenthèses…

Voyons maintenant ce que cela donnerait en scindant ce groupe de conditions complexes:

si(actuel[0]=trouve[id] et 
actuel[0]≠1 et 
actuel[0]≠4 et 
actuel[0]≠5 et 
actuel[0]≠6  et 
actuel[0]≠7)
{
//les instructions précises n'ont ici aucun inérêt, c'est la raison 
//pour laquelle elles portent des noms simples
instruction1 |
instruction2 |
instruction3 |
}
sinon
{
instruction4 |
instruction5 |
}
instruction6 |
instruction7 |
instruction8 |

Avouez que c'est déjà beaucoup mieux… Au moins, on est en mesure de déterminer précisément quelles conditions sont vérifiées…

Ce code recèle pourtant encore un gros problème dont je suis sûr que vous aurez identifié vous même…

Il est excessivement difficile de repérer où se termine la liste des conditions à vérifier, ainsi que l'endroit où commencent les blocs d'instructions…

Cela m'emmene donc naturellement à la règle suivante.

fleche haut

2.5 Indentez votre code

La *plupart* des langages de troisième génération (car je sais de tête qu'il y a au moins une exception, même si je ne suis plus en mesure de la nommer) ne s'intéressent pas au nombre d'espaces dans le code, du moment où il y en ait au moins un.

Si donc, vous remplacez un espace par dix espaces, ou par trois tabulations, les langages ne s'inquiéteront aucunement…

Par contre, cela vous permet de représenter visuellement les instructions et/ou les conditions qui font partie d'un même bloc…

Encore faut il que ce ne soit pas fait n'importe quand, n'importe comment…

L'idéal, c'est de:

Le code que je vous présentais juste avant deviendrait donc:

si
(
    actuel[0]=trouve[id] et
    actuel[0]≠1 et
    actuel[0]≠4 et 
    actuel[0]≠5 et 
    actuel[0]≠6  et
    actuel[0]≠7
)
{
//les instructions précises n'ont ici aucun inérêt, c'est la raison 
//pour laquelle elles portent des noms simples
    instruction1 |
    instruction2 |
    instruction3 |
}
sinon
{
    instruction4 |
    instruciton5 |
}
instruction6 |
instruction7 |
instruction8 |

Il devient enfin facile de se repérer dans le code…

Nous voyons en effet tout de suite qu'il y a six conditions vérifiées dans le test, que, si le résultat global est «vrai», on effectuera les instructions 1, 2 et 3, alors qu'on effectuera les instruction 4 et 5 si le résultat du test donne «faux», et que nous effectuerons de toute manière les instructions 6, 7 et 8 après.

Le dernier problème auquel nous sommes maintanant confronté est celui de «fixer dans le temps» une idée de la logique que l'on a utilisée…

En effet, la logique suivie lors de la programmation sera très souvent fonction de «l'humeur du moment», car il ne faut pas oublier qu'il n'existe jamais qu'une seule manière d'arriver à un résultat…

Il n'existe d'ailleurs pas de «mauvaise manière» de l'obtenir, mais bien des manières «différentes» et «plus ou moins efficaces» d'y arriver…

Ce sera le but de la dernière règle.

fleche haut

2.6 Commentez votre code

Tous les langages permettent de mettre des commentaires, parfois sur une ligne, parfois sur plusieurs, parfois même après une ou plusieurs instructions, pour autant que ce soit à la fin de la ligne (qu'il n'y ait pas d'autre instruction après le commentaire)

Comme les commentaires ne sont purement et simplement pas intégrés dans l'exécutable pour les langages compilés, ni pris en compte pour les langages interprétés, il serait idiot de ne pas s'en servir…

A vrai dire, c'est même une chose dont l'abus ne nuise nullement, bien qu'il soit utile de veiller à les utiliser à bon escient…

Certaines personnes n'hésitent pas à préconiser que les commentaires devraient représenter un tiers des lignes du programme

Je me contenterai pour ma part de vous conseiller d'en mettre suffisemment pour vous permettre de savoir retrouver facilement le but qui était recherché par un bloc d'instruction, ainsi qu'une description sommaire de la logique que vous avez suivie pour y arriver…

Soyez toute fois logique dans l'utilisation des commentaires: commenter une ligne du genre

variable = variable +1 // incrémente variable

n'a pas énormément d'intérêt…Ne serait-ce parce qu'il ne faut pas sortir de polytechnique pour savoir que si on donne à une variable sa valeur +1, sa valeur aura augmenté de 1…

Un commentaire efficace concernant cette incrémentation serait sans doute d'en préciser la raison…

En outre, j'aurais personnellement tendance à *conseiller* de mettre le commentaire AVANT l'instruction ou le bloc d'instructions auquel il se rapporte… mais ça, ça reste du domaine des goûts et des couleurs…

La raison de ce conseil est toute simple: comme tout un chacun, je lis géralement le texte de haut en bas… je préfère donc savoir ce qui m'attend dans ce que je n'ai pas encore lu plutôt que d'avoir (enfin) une information sur quelque chose que je n'aurais pas compris …

fleche haut

2.7 La précision finale…

Tout au long de cette page, j'ai parlé de «règles»…

Il va de soi qu'il s'agit surtout de conseils que je vous incite grandement à suivre…

Si vous décidez de ne pas les suivre, libre à vous, cela m'indifère, tant que vous ne me demanderez pas de jeter un oeil à votre code…

Sachez cependant que la première chose que je fais quand je m'attaque à un code qui m'est inconnu, et c'est d'ailleurs le cas de nombreuses personnes, est toujours de rendre le code aussi conforme que possible avec ces conseils…

image d'imprimante   image de mail   fleche haut

Evaluation donnée par les visiteurs
Cette page a été évaluée 19 fois et a obtenu une moyenne de très bien expliquée
Mon appréciation sur la compréhensibilitéde cette page est:
  • incompréhensible
  • mal expliquée
  • compréhensible, sans plus
  • bien expliquée
  • très bien expliquée

fleche haut

[koala01.free.fr]->Tutoriaux->Principes de Programmation ->Pour un code propre

Copyright (©) 2005 (Philippe Dunski)

Ce cours est libre, vous pouvez le redistribuer et/ou le modifier selon les termes de la Licence Publique Générale GNU publiée par la Free Software Foundation (version 2 ou bien toute autre version ultérieure choisie par vous).

Ce cours est distribué car potentiellement utile, mais SANS AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties de commercialisation ou d'adaptation dans un but spécifique. Reportez-vous à la Licence Publique Générale GNU pour plus de détails.

Cependant, l'auteur apprécierait grandement que vous lui fassiez part de toute modification apportée à son contnu

Vous pouvez le contacter par mail à l'adresse koala01@free.fr

Vous pouvez trouver une adaptation française de la licence GNU/GPL à l'URL http://www.linux-france.org/article/these/gpl.html