Exemple et Conseils


L'objectif de la programmation n'est pas seulement de faire des programmes qui marchent.

En réalité un programme n'est jamais terminé (du moins un programme conséquent tel que vous en rencontrerez en entreprise). Il faut donc pouvoir le modifiez facilement, sachant que le développeur qui sera chargé de la mise à jour de votre programme ne sera pas forcément vous même. Cela a deux conséquences:

  1. Votre code doit être lisible, c'est à dire qu'en le lisant on devine facilement ce qu'il fait.
  2. D'autre part, il doit être facilement modifiable.

Dans cette partie du cours, je vous donne à travers un exemple quelques conseils permettant de rendre un programme plus lisible et plus facile à modifier.

Mise à part la lisibilité et la facilité de modification, il existe d'autres critères importants en programmation que nous n'aborderons pas ici:



Exemple de programme et conseil

Cahier des charges

La réalisation d'un projet informatique démarre en général avec un cahier des charges. C'est en gros une description de ce que devrait faire le logiciel.

Voici, le cahier des charges de notre exemple:

On souhaiterait écrire un programme qui calcule la surface à peindre dans une pièce rectangulaire possédant des portes et des fenêtres.

Pour simplifier, on supposera que les murs ont 2m50 de hauteur et que toutes les fenêtres ont la même dimension (1.4 × 1.2) et de même pour les portes (0.9 × 2.1).

Déclaration des constantes

Introduisons une constante pour chaque donnée fixe du problème:

   const
    LargeurFenetre = 1.4;
    HauteurFenetre = 1.2;
    LargeurPorte = 0.9;
    HauteurPorte = 2.1;
    HauteurMur = 2.5; 

On pourrait se passer de ces déclarations et mettre directement les valeurs 1.4, 1.2, ... etc dans les calculs, mais on obtiendrait ainsi un code moins lisible et plus difficile à mettre à jour.

S'il faut corriger la hauteur des portes par exemple, il suffit de changer la valeur de la constante et cette modification sera automatiquement répercutée dans tout le code (dans tous les calculs où la hauteur des portes intervient).

Essayez de procéder de cette manière dès que vous avez des valeurs fixées. Déclarez des constantes au lieu d'écrire les valeurs dans les instructions.
Conception de l'interface graphique

La surface à peindre dépendra donc de la taille de la pièce ainsi que du nombre de portes et de fenêtres. Ce seront les données du programme. On en déduit l'interface graphique suivante:

Peinture.jpg, 21kB

Les zones de texte sont nommées ZT_Largeur (largeur de la pièce), ZT_Longueur (longueur de la pièce), ZT_NF (nombre de fenêtres), ZT_NP (nombre de portes) et ZT_SP (surface à peindre).

Les noms des zones de texte sont toutes préfixées par ZT_. Cette manière de procéder permet d'éviter des conflit avec des noms de variables. En programmation, un même nom ne peut désigner qu'une seule chose. Vous ne pouvez pas par exemple nommer une zone de texte Largeur et utiliser par ailleur une variable de même nom. Je vous propose de préfixer les noms des zones de texte par ZT_, ceux des zones de liste par ZL_ et ceux des boutons par BT_. Vous pouvez bien sur avoir vos propres conventions. L'essentiel est d'en avoir une.
Lecture et déclaration des données

Associons une variable à chaque donnée: LargeurPiece, LongueurPiece, NFenetre et NPorte. D'où les déclarations:

 Var LargeurPiece, LongueurPiece : Double; 
     NFenetre, NPorte : Integer;
Je n'ai pas besoin de vous expliquez ici la signification de chaque variable, car les noms choisis permettent de deviner la fonction de chacune d'entre elle. Pour obtenir un code lisible, il est recommandé de procéder de cette manière: utilisez des noms de variables parlant. Cette remarque est évidemment également valable pour les noms de constantes et pour de manière générale pour n'importe quel nom utilisé dans un programme.

Nous pouvons à présent écrire les instructions de lecture de données dans la procédure évènementielle du bouton Calculer:

procedure TForm1.BT_CalculClick(Sender: TObject);
begin
  // Lecture des données
  LireNombre (LargeurPiece, ZT_Largeur);
  LireNombre (LongueurPiece, ZT_Longueur);
  LireEntier (NFenetre, ZT_NF);
  LireEntier (NPorte, ZT_NP); 
end;  
Traitement, résultats intermédiaires et finaux

Il nous faut maintenant réfléchir à la manière de calculer la surface à peindre. Pour simplifier le problème, nous allons découper le traitement en plusieurs étapes:

  1. Calcul de la surface des murs.
  2. Calcul de la surface des fenêtres.
  3. Calcul de la surface des portes.
  4. Calcul de la surface à peindre.

Le résultat de chaque étape sera sauvegardé dans une variable: SurfaceDesMurs, SurfaceDesFenetres, SurfaceDesPortes, SurfacePeinture.

Essayez également de procéder de cette manière lorsque vous avez un calcul compliqué. Découpez le calcul en plusieurs parties et sauvegardez le résultat de chacun de ces calculs dans une variable. A la fin écrivez le calcul du résultat final en utilisant les résultats des calculs intermédiaires. Cette manière de programmer simplifie la résolution du problème et rend le programme plus lisible.

Il nous faut d'abord déclarer les nouvelles variables:

 Var LargeurPiece, LongueurPiece : Double; 
     NFenetre, NPorte : Integer;
     SurfaceDesMurs, SurfaceDesPortes, SurfaceDesFenetres,
     SurfacePeinture : double;
Vous pouvez également procéder de cette manière. Il est en général difficile de prévoir dès le début toutes les variables que l'on aura besoin d'utiliser dans un programme. Ajoutez vos déclarations de variable au fur et à mesure des besoins.

Ecrivons à présent les quatre étapes de calcul:

Calcul de la surface des quatre murs:

 SurfaceDesMurs :=  
   2 * (LargeurPiece+LongueurPiece) * HauteurMur; 

Calcul de la surface des fenêtres:

 SurfaceDesFenetres := 
  NFenetre * LargeurFenetre * HauteurFenetre; 

Calcul de la surface des portes:

  SurfaceDesPortes := 
    NPorte * LargeurPorte * HauteurPorte;

Calcul de la surface à peindre:

 SurfacePeinture := 
   SurfaceDesMurs  - SurfaceDesFenetres - SurfaceDesPortes;
Le code de la procédure en entier

Pour conclure, voici le code de la procédure évènementielle du bouton calculer:

procedure TForm1.BT_CalculClick(Sender: TObject);
begin
  //--- Lecture des données
  
  LireNombre (LargeurPiece, ZT_Largeur);
  LireNombre (LongueurPiece, ZT_Longueur);
  LireEntier (NFenetre, ZT_NF);
  LireEntier (NPorte, ZT_NP); 
  
  //--- Traitement des données

  SurfaceDesMurs :=  
   2 * (LargeurPiece+LongueurPiece) * HauteurMur; 

  SurfaceDesFenetres := 
  NFenetre * LargeurFenetre * HauteurFenetre; 

  SurfaceDesPortes := 
    NPorte * LargeurPorte * HauteurPorte;

  SurfacePeinture := 
   SurfaceDesMurs  - SurfaceDesFenetres - SurfaceDesPortes;

  // Affichage des résultats
  
  AfficherNombre (SurfacePeinture,ZT_SP);  
end;  
Le code de cette procédure est bien séparé en trois parties: lecture des données, traitement des données, puis affichage des résultats. Essayez également de procéder de cette manière. Ecrivez votre code en séparant bien la lecture, le traitement et l'affichage.


Synthese

Voici un résumé de tous les conseils vus précédemment: