Un code dont chaque module peut être appréhendé d'un coup d'oeil (une page ou un écran)
Un code qui peut être éxécuté en pas-à-pas.
Un code dont chaque module peut être appréhendé d'un coup d'oeil (une page ou un écran)
Un code qui peut être éxécuté en pas-à-pas.
En general oui, pour quelqu'un qui fonce droit vers le code sans faire un peu d'analyse du probleme a resoudre; et lorsque tu lui expliques que c'est difficile a avaler, il te repondra : "toi, tu fais un code incomprehensible avec des tas de redirections, alors que le mien, tout se trouve dans une meme procedure et c'est facile a suivre !",![]()
Un code lisible. Coder c'est exprimer selon un langage de programmation une succession de tâches.
Un code propre se lit et se comprend en le lisant. Et oui, on n'y pense pas assez, mais nous parlons plusieurs langues étrangères. C'est quand il y a des jargons, du patois, au sein d'un langage que cela devient difficile.
Un morceau de programme est un livre, un formulaire un chapitre, une procédure un paragraphe. Il faut parfois un sommaire, une introduction, un résumé, une conclusion pour comprendre l'ensemble.
J'ai collègue pour qui un code lisible est, en plus, un code correctement indenté, les variables et les propriétés dans l'ordre alphabétique. Les méthodes, les propriétés séparée...
A+
"Winter is coming" (ma nouvelle page d'accueil)
C'est un cas extrême, mais il arrive que ça soit cohérent(en même temps, je fais du COBOL, c'est bavard, sur un langage plus léger ça ferait déjà moins). Genre : remplissage d'un enregistrement. Je fais, en batch, un gros paquet d'assignation de données(plus de 100), qui forment un ensemble cohérent, avec parfois un test technique au milieu(genre on élimine les caractères spéciaux, ou n'importe quoi - pour ça, on peut d'ailleurs faire appel à une fonction dédiée, mais bref).
Comment veux-tu que je découpe le bidule? "premier paquet d'assignation" "deuxième paquet d'assignations".......d'autant que si tu en a 200 lignes, c'est parfaitement lisible, c'est juste très long(mais tu trouves facilement ce que tu cherches, et tu peux bypasser sans souci pour lire la suite). Evidemment, 300 lignes de IF/END-IF imbriqués, je te soutiens, c'est l'horreur. Mais quand tu dois récupérer des données en base, que la base en contient un gros paquet(et c'est cohérent, un client peut avoir plus de 200 données), beeeen, rien que la requête SQL sera très longue. Ajoute le traitement d'erreur et tu as une procédure de 300 lignes. Parfaitement lisible.
Mais après, tu peux faire :
ou tu peux faire
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 IF ENTREE-VALIDE EXEC SQL......(200 lignes) END-EXEC (traitement d'erreur) END-IF
Note : si tu remplaces le SELECT avec toutes les données par un SELECT *, le jour ou la structure de ta base change, tu risques fort le bug. Alors qu'en précisant toutes les données que tu veux, tu n'as que ce que tu veux. Et tu rajoutes la nouvelle donnée quand tu veux.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 IF NOT ENTREE-VALIDE GO TO FIN-LECTURE-SQL END-IF EXEC SQL......(200 lignes) END-EXEC (traitement d'erreur)
Moi, je préfère la seconde solution. Un end-if qui traine, ça n'est jamais bon pour la lisibilité du bousin. Autre exemple sur une procédure toute bête, bien plus courte :
avant :
après :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 IF NOT CONTENTIEUX AND NOT COASSURANCE AND NOT (PRELEVE AND RIB-VALIDE) AND NOT (condition à la noix qui tient sur 3 lignes) PERFORM PROCEDURE-CONDITIONNEE THRU FIN-PROCEDURE-CONDITIONNEE END-IF
Le second code est plus bavard, mais aussi plus lisible, surtout quand les condition commencent à mélanger du NOT, du OR, du AND..... Le pauvre malheureux qui arrive derrière, il est content d'avoir des condition lisibles. Que ces condition soit des conditions de sorties ou d'execution, peu importe. Là, fonctionellement, j'ai des conditions de sortie, multiples et complexes(j'ai fortement simplifié, là). Donc, il peut être propre, dans certains cas(extrêmes), d'utiliser un GO TO. Après, ça dépend aussi du langage, quand on a un moyen plus propre de sortir de la procédure, il faut l'utiliser. Quand on en a pas, eh bien le vieux GO TO est utile. Evidemment, il faut éviter les horreurs du style :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 IF CONTENTIEUX GO TO FIN-CONDITION-PROCEDURE END-IF IF COASSURANCE GO TO FIN-CONDITION-PROCEDURE END-IF AND NOT (PRELEVE AND RIB-VALIDE) GO TO FIN-CONDITION-PROCEDURE END-IF IF (condition à la noix qui tient sur 3 lignes) GO TO FIN-CONDITION-PROCEDURE END-IF PERFORM PROCEDURE-CONDITIONNEE THRU FIN-PROCEDURE-CONDITIONNEE
(ou en plus les points tiennent lieu de END-IF, l'angoisse absolue)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 MOVE ZERO TO P. A31. IF P = NBVC OF DBSEGAB GO TO A32. ADD +1 TO P. IF FIN OF DBSEGAG (P) = SPACE OR ZERO GO TO A31. MOVE FIN OF DBSEGAG (P) TO W-FIN (P) IF W-FINAM (P) NOT > W-DTQUIT MOVE ZERO TO BASE OF DBSEGAG (P). GO TO A31. A32.
Absolument...
Ce n'est franchement pas recommandé, c'est même relativement prohibé, mais il y a des cas où on ne peut s'en passer, au risque de complexifier beaucoup beaucoup plus la lecture.
J'ai eu le cas, dans un très gros logiciel (> 700 000 lignes). 2 routines étaient supérieures à 2000 lignes...
Une construisait un arbre dynamique de widgets dans une IHM, mais avec des propriétés différentes suivant les étages.. Là le gros du code était la création des widgets, mais il n'empêche que la routine fait aux environs de 2500 lignes.
L'autre était une boucle d'affichage en temps réel. MAIS, ce qui la complexifiais, était que chaque paramètre d'affichage était modifiable pendant le déroulement de la boucle , y compris des demandes de calcul, des demandes d'affichage/d'effacement de tel ou tel élément, que certains éléments était affichable pendant une certaine durée, qu'il y avait 3 notions de temps superposées, etc etc... C'était la routine du coeur de l'affichage. J'aurais pu isoler une itération, mais le nombre de paramètres à passer aurait été bien plus grand, rendant la lisibilité bien plus complexe. En pesant le pour et le contre, j'ai finalement décidé de laisser tel quel. Là au moins on pouvait suivre le flux de ce qui se passait et des interactions possibles...
Donc c'est fortement déconseillé, mais ne jamais dire "fontaine je ne boirais pas de ton eau".....
![]()
Un code propre est un code facilement DEBOGABLE. L'humain doit pouvoir comprendre ce qui se passe à chaque étape, estimer ce qu'il doit obtenir après chaque pas et pouvoir le vérifier.
Un exemple tout simple : Il peut paraitre plus élégant d'écrire
x:=fonction1(fonction2(y))
que
z:=fonction2(y);
x:=fonction1(z);
mais la 2e forme permet, en mode pas-à-pas, de tester z avant d'appeler fonction1 et de localiser un bug plus facilement.
Selon mon expérience, le modèle "procedural" permet mieux ce genre de choses que le modèle "objet"
Ah bon ? je croyais que c'est toi le 'debogueur' et pas le soft, et puis les outils actuels permettent de faire le test de z avant appel de fonction1, selon mon experience.
Sinon, +1 pour le code que l'on peut deboguer facilement.
Et selon le mien, c'est la meme chose
Je rajouterais, qu'il ne doit pas générer de memory leaks.
Il existe un livre qui traite (sans doute partiellement) le sujet : http://www.developpez.net/forums/d65...e/#post4271208
Personnellement, je ne regarde pas la lisibilité du code pour dire s'il est propre ou pas.
J'oppose plutôt "propreté" à "bidouille". Et ça donne :
Un code propre, c'est un code où on a utilisé les bons outils et les bons algo pour traiter un problème.
Pour visser une vis, je prends un tournevis.
Pour enfoncer un clou, je prends un marteau.
Le code commence à ne plus être propre lorsque le développeur ne sait se servir que de son tournevis. Et que lorsqu'il doit enfoncer un clou, plutôt que d'apprendre à se servir d'un marteau, il décide que son outil favoris est capable de tout faire et qu'il fera tout avec lui et uniquement lui. Alors il retourne son tournevis et se sert du manche pour tapper sur la tête du clou...
Ca donne alors des bidouilles dans tous les sens et un code bourré de bugs et de verrues... et le tout sera peut-être parfaitement bien présenté et lisible. Dailleurs, plus on fait de bidouilles et plus on a intérêt à ce que le code soit lisible pour pouvoir comprendre ce qu'on a voulu faire avec les bidouilles...
Je suis d'accord pour dire qu'un code sans bidouille aura plus facilement tendance à être plus lisible.
En revanche, une bidouille peut être codée de façon parfaitement lisible et compréhensible. Si tu maitrises ta bidouille, tu pourras écrire 20 lignes de codes parfaitement clair, bien présenté et compréhensible par tous. Ca ne change rien au fait que c'est une bidouille. Et que pour moi, ce n'est pas un code propre !
Je vais prendre un exemple concrêt. Récemment quelque part sur le forum, un internaute donnait une solution pour qu'un script javascript qui s'exécutait dans une page Web hébergée dans un navigateur intégrée dans une appli transmette la valeur de certaines variables javascript à l'application hôte. Autrement dit, comment faire communiquer l'application hôte avec le javascript qui s'exécute dans la page ?
Sa solution était très simple : il "affichait" la valeur de ces variables dans la barre d'état du navigateur. De cette façon, l'appli hôte pouvait recupérer l'événement de modification de la bare d'état, décoder le nouveau libellé pour en extraire la valeur des variables.
On peut certainement faire ça de façon très lisible (dailleurs, j'explique ici ce que j'ai compris du code en 30s). Mais ça reste de la haute bidouille !
Un jour ou l'autre, on voudra afficher la barre d'état, et la
Alors que window.External dans le Javascript est fait pour ça.
Ensuite, je dirais que la lisibilité est de toute façon une notion très subjective qui dépend beaucoup du lecteur et de ses compétences.
Tiens, ça me fait penser à une chose. On veut un code lisible, pour qu'il soit facilement maintenable. La lisibilité a pour but que le code soit compréhensible.
Cependant qu'est-ce qui doit être facilement compréhensible :
1. Ce que le code fait ? (indispensable pour corriger un bug)
2. Ce que le développeur a voulu faire lorsqu'il l'a écrit ? (idem. Sauf que s'il y a un bug, c'est que 1<>2 donc le code ne va pas faire clairement appraitre les deux)
3. Ce que le développeur avait besoin de faire ? (autrement dit quel était le problème qu'il cherchait à résoudre ?) (autrement dit, même si 1=2 (ou une fois que 1=2) est-ce que ça permet de résoudre le bug ?)
En théorie, les trois sont identiques mais dans la pratique...
Avec le cas pratique tellement classique : On vient de découvrir un bug dans l'appli qui doit être corrigé en urgence. Le développeur qui a codé cette partie est en vacances ou a quitter la société. Et c'est quelqu'un qui n'a jamais mis le nez dedans qui doit résoudre le problème.
c'est bien ce qu'on dit depuis le début de cette discussion, non ??
La bonne compréhension passe par le fait que ce soit lisible (et pas "obsufqué"), bien présenté pour que ce soit clair, les blocs bien séparés, des commentaires, si possibles des commentaires (même longs) aux endroits "chauds" ou en tête des fonctions..
Ensuite vient le fait de savoir si c'est bien codé ou non.
MAIS si de toutes façons tu n'arrives pas à lire tu ne le sauras jamais..
Je vais lire ce qui est écrit précédemment mais avant d'être convaincu par certains de vos arguments, je dirai spontanément qu'un code propre est un code compréhensible où il n'y a plus rien à enlever.
Je sais bien que ce sont des conventions mais l'exemple ocaml m'y fait penser : un code avec une syntaxe horrible et/ou pleins de caractères "spéciaux", je trouve ça moche :
;;
$
***a->c
%%
##
Partager