Cours VB.NETDate de mise à jour : 05/12/2010
XVI-E. Faire du bon 'code'
XVI-E-1. Bonnes variables
XVI-E-1-a. Utilisez Option Strict=On et Option Explicit=On
XVI-E-1-b. Donnez à chaque variable un seul rôle
XVI-E-1-c. Évitez les variables avec des significations non évidentes
XVI-E-1-d. Initialisez les variables dès leur déclaration
XVI-E-1-e. Utilisez le principe de proximité
XVI-E-1-f. Travaillez sur des variables qui restent actives le moins de temps possible
XVI-E-1-g. Si vous codez la valeur d'une variable en 'dur', utilisez plutôt des constantes
XVI-E-1-h. Groupez les instructions liées
XVI-E-1-i. Réduisez la portée des variables (problème des variables globales)
XVI-E-1-j. Les Booléens sont des Booléens
XVI-E-1-k. Utiliser les variables Date pour stocker les dates
XVI-E-2. Règles de bonne programmation
XVI-E-2-a. Séparer l'interface utilisateur et l'applicatif
XVI-E-2-b. Utiliser le typage fort
XVI-E-2-c. Forcer la déclaration des variables et les conversions explicites
XVI-E-2-d. Utiliser des constantes ou des énumérations
XVI-E-2-e. Vérifier la validité des données que reçoit une Sub une Function ou une Classe
XVI-E-2-f. Se méfier du passage de paramètres 'par valeur' ou par 'référence'
XVI-E-2-g. Structurez le code, évitez les Goto
XVI-E-2-h. Ne faire aucune confiance à l'utilisateur du logiciel
XVI-E-2-i. Rendre le code lisible par tous
XVI-E-3. Rendre le code lisible : commentaires, noms de variables
XVI-E-3-a. Ajoutez des commentaires
XVI-E-3-b. Choisissez les noms de procédures et de variables avec soin
XVI-E-3-c. Éclaircir, aérer le code
XVI-E. Faire du bon 'code'
XVI-E-1. Bonnes variables
XVI-E-1-a. Utilisez Option Strict=On et Option Explicit=On
Travailler avec
Vous serez obligé de faire du 'cast' à longueur de temps (conversion d'une variable d'un type vers un autre), mais au moins le code sera rigoureux.
Les conversions seront évidentes, explicites:
Dim I As Integer
Dim J As Long
J= CType (I, Long)
|
et avec
Vous serez obligé de déclarer les variables avant de les utiliser. C'est indispensable.
Voir chapitre 1-7 pour le détail.
XVI-E-1-b. Donnez à chaque variable un seul rôle
A l'époque ou il y avait très peu de mémoire, un octet était un octet, aussi on utilisait parfois une même variable pour différentes choses:
Dim total As Integer
total= nbArticle* 3
Affiche (total)
total= nbFacture* 2
Affiche (total)
|
Ici total contient le total des articles puis le total des factures!!
Il vaut mieux créer 2 variables et écrire:
Dim totalArticle As Integer
totalArticle= nbArticle* 3
Affiche (totalArticle)
Dim totalFacture As Integer
totalFacture= nbFacture* 2
Affiche (totalFacture)
|
Dans le même ordre d'idée, éviter les variables nommées 'temp'(temporaire) qui serviront à plusieurs reprises pour des résultats temporaires successifs.
XVI-E-1-c. Évitez les variables avec des significations non évidentes
Eviter les significations cachées.
Exemple à ne pas faire:
- nbFichier contient le nombre de fichier sauf s'il prend la valeur -1 , dans ce cas cela indique qu'il y a eu une erreur de lecture!!
- clientId contient le numéro du client sauf s'il est supérieur à 100000 dans ce cas soustraire 10000 cela donne le numéro de la facture.
Dans le premier exemple, la solution est d'utiliser en plus de nbFichier une variable isReadOk indiquant si la lecture s'est bien déroulée.
XVI-E-1-d. Initialisez les variables dès leur déclaration
Cela évite de l'oublier. Les erreurs d'initialisation sont très fréquentes.
Un truc: si vous initialisez ou réinitialisez une variable avec NoThing, elle prend la valeur obtenu après déclaration pour ce type. Pour une structure, c'est valable pour chaque variable.
Exemple:
Soit une structure Adresse
Public Structure Adresse
Dim Numero As Integer
Dim Id As Integer
Dim Rue As String
Dim Ville As String
End Structure
|
Je déclare une variable Adresse
Dim MonAdresse As Adresse
|
J'initialise:
MonAdresse. Numero = 12
MonAdresse. Id = 15
MonAdresse. Ville = " lyon "
|
Maintenant si je fais:
Cela entraîne:
MonAdresse. Numero = 0
MonAdresse. Id = 0
MonAdresse. Ville = Nothing
|
XVI-E-1-e. Utilisez le principe de proximité
Déclarer, initialiser une variable le plus prêt possible de sa première utilisation, puis grouper les instructions dans lesquelles la variable est utilisée:
Mauvais exemple: (chaque variable est repérée par une couleur)
Dim Prixtotal As Integer
Dim Taux As Integer
Dim Prix As Integer
Dim Quantité As Integer
Dim Ristourne As Integer
Taux= 12
Ristourne= 0
Prix= 0
Prixtotal= Quantité* Prix
Ristourne= Taux* Quantité
|
Prixtotal n'est pas initialisé, on utilise les variables loin de leur déclaration...
Code dur à lire, source d'erreur.
Bonne manière de faire:
Dim Taux As Integer= 12
Dim Prix As Integer= 0
Dim Quantité As Integer= 2
Dim Prixtotal As Integer= 0
Prixtotal= Quantité* Prix
Dim Ristourne As Integer= 0
Ristourne= Taux* Quantité
|
XVI-E-1-f. Travaillez sur des variables qui restent actives le moins de temps possible
Les instructions utilisant une même variables doivent être si possible regroupées.
Exemple: regardons la variable Acte:
Mauvaise méthode: il y a plusieurs lignes entre 2 lignes contenant la même variable, le cheminement est difficile à suivre!!
Dim Acte As Integer
Dim Bib As Integer
Dim C As Integer
C= 2
Call Calcul ()
Call Affiche ()
Acte= Acte+ 1
Call CalculTaux ()
Call AfficheResultat (Acte)
|
Bonne méthode: le cheminement est clair, les lignes utilisant la variable Acte sont regroupées,la lecture est facile est facile à suivre.
Dim Acte As Integer
Acte= Acte+ 1
Call AfficheResultat (Acte)
Dim Bib As Integer
Dim C As Integer
C= 2
Call Calcul ()
Call Affiche ()
Call CalculTaux ()
|
XVI-E-1-g. Si vous codez la valeur d'une variable en 'dur', utilisez plutôt des constantes
Une valeur codé en dur est une valeur imposée par le programmeur et écrite sous forme d'un littéral:
I= 123
Ecrire :
Const nbMaxLignes As Integer= 123
I= nbMaxLignes
|
Autre exemple:
Plutôt que:
Ecrire:
Const MAXELEMENT As Integer = 120
For i= 0 To MAXELEMENT
Next i
|
Cela a tous les avantages: Quand on regarde le code, MAXELEMENT est plus explicite que 120.
De plus si on change la valeur de MAXELEMENT , la modification est prise en compte partout dans le code et les boucles fonctionnent toutes bien.
On peut utiliser des '0' (pour démarrer les boucle: For i= 0 to..) ou des '1' pour incrémenter des compteurs (i=i+1) mais on évitera les autres littéraux.
Utilisez aussi les énumérations.
XVI-E-1-h. Groupez les instructions liées
Regroupez les instructions faisant référence aux mêmes choses:
Mauvaise méthode: c'est un peu fouillis
CalculNewTotal ()
CalculOldTotal ()
AfficheNewTotal ()
AfficheOldTotal ()
ImprimeNewTotal ()
ImprimeOldTotal ()
|
Bonne méthode:
CalculNewTotal ()
AfficheNewTotal ()
ImprimeNewTotal ()
CalculOldTotal ()
AfficheOldTotal ()
ImprimeOldTotal ()
|
XVI-E-1-i. Réduisez la portée des variables (problème des variables globales)
Une variable 'globales' est une variable visible dans la totalité du programme.
Exemple: créons une variable globale nommé Index
Module MonModule
Public Index As Integer
. .
End Module
|
A l'inverse une variable 'locale' est visible uniquement dans une procédure ou une Classe:
Class Form1
Private Dim Index As Integer
. .
End Class
|
Avantages et inconvénients des 2 manières de faire:
Utilisation de variables globales:
Exemple:
Public maVariable As Integer
Sub Mescalculs ()
. . maVariable= 12
End Sub
|
Toutes les procédures ont accès à la variable globale.
Les variables globales sont commodes, d'accès facile, il n'y a peu de paramètres à passer quand on appelle une fonction. Mais on prend des risques: n'importe quelle procédure peut modifier la variable globale.
Utilisation de variables locales:
La variable a une portée limitée, pour qu'une procédure l'utilise, il faut lui fournir en paramètre:
Exemple:
Sub Main ()
Dim maVariable As Integer
Call MesCalculs (maVariable)
End Sub
Sub Mescalculs (V As Integer)
. . V= 12
End Sub
|
La variable locale aide à la maniabilité, vous restez maître de ce à quoi chaque procédure a accès.
Chaque procédure est autonome. Cela conserve donc une bonne modularité et un bon masquage des informations.
Autre danger des variables globales que l'on utilise comme paramètre:
Si on a des variables globales et en plus on utilise ces variables comme paramètres d'une procédure, la même variable peut être modifiée en utilisant 2 noms différents:
Public maVariable As Integer
Call Mescalculs (maVariable)
Sub Mescalculs (By Ref v As Integer)
. . maVariable= 12
. . v= 15
End Sub
|
Utiliser le maximum de variables locales.
(Il sera toujours possible d'augmenter la portée de la variable si nécessaire, plutôt que de la diminuer)
Eviter donc les variables globales qui sont visibles dans la totalité du programme.
Procédures d'accès aux variables:
Si vous tenez quand même à utiliser des variables globales utilisez des 'procédures d'accès à ces variables'.
Le programme n'ira pas modifier directement la valeur de la variable globale mais passera par une Sub ou une Classe qui ira modifier la variable.
Exemple avec un Sub:
Public maVariable As Integer
|
Au lieu d'écrire maVariable=12 ce qui modifie directement l'accès à la variable globale, créer une Sub modifiant cette variable:
Sub SetVariable ( Valeur As Integer)
maVariable= Valeur
End Sub
|
Cela a l'avantage de pouvoir ajouter un contrôle des données, on peut ajouter par exemple des conditions, interdire des valeurs..
Pour modifier la variable globale on écrira SetVariable(12)
De manière plus générale plutôt que de créer un tableau de variables globales du genre:
Public Variables (100) As Variable
|
et d'écrire Variables(50)=485
créer une procédure SetVariable() une procédure LetVariable() une procédure VariableCount()..
En programmation objet, on crée une classe contenant les données (tableau, collection) mais 'Privé', on crée aussi des membres de cette classe qui permettent de lire (les accesseurs)ou de modifier(les mutateurs) les données.
XVI-E-1-j. Les Booléens sont des Booléens
Utiliser une variable Integer pour stocker un Flag dont la valeur ne peut être que 'vrai' ou 'faux' et donner la valeur 0 ou -1 est à proscrire.
Faire:
Dim Flag As Boolean
Flag= True
|
(Utiliser uniquement True et False)
Eviter aussi d'abréger à la mode Booléens ce qui n'en est pas.
Dim x,y As Integer
If x And y then (pour tester si x et y sont = 0) est à éviter.
|
Faire plutôt:
XVI-E-1-k. Utiliser les variables Date pour stocker les dates
Ne pas utiliser de type Double.
Dim LaDate As Date
LaDate= Now
|
XVI-E-2. Règles de bonne programmation
Pour faire un code solide, éviter les bugs, avoir une maintenance facile, il faut suivre quelques règles.
Relire les chapitres :
sur les bonnes procédures.
sur les bonnes Classes
sur le bon code: bonnes variables
sur les bons commentaires le code lisible
Voici un résumé des points forts.
XVI-E-2-a. Séparer l'interface utilisateur et l'applicatif
Exemple: un formulaire affiche les enregistrements d'une base de données:
Créer:
- Les fenêtres dont le code gère uniquement l'affichage. C'est l'interface utilisateur ou IHM (Interface Homme Machine)
- une Classe gérant uniquement l'accès au base de données.
Cela facilite la maintenance: si on désire modifier l'interface, on touche au fenêtre et pas du tout à la Classe base de données.
Architecture à 3 niveaux.
Elle peut être nécessaire dans certains programmes, les 3 niveaux sont:
- Application ,interface.
- Logique.
- Données.
Exemple: Un formulaire affiche certains enregistrements d'une base de données.
- L'interface affiche les enregistrements.
- Les classes ou modules 'logiques' déterminent les bons enregistrements.
- Les classes ou modules données vont chercher les données dans la base de données.
Si au lieu de travailler sur une base Access, je travaille sur une base SQLServer, il suffit de réécrire la troisième couche.
Utiliser des design pattern: ce sont des 'patrons', des modèles en programmation objet.
XVI-E-2-b. Utiliser le typage fort
Cela consiste à spécifier le type de données pour toute variable, en plus il faut utiliser des variables le plus typées possible.
Éviter le type 'Object'.
Le code en sera plus rapide, le compilateur interceptera des erreurs (cela évitera des erreurs à la compilation).
XVI-E-2-c. Forcer la déclaration des variables et les conversions explicites
Option Explicit étant par défaut à On, toute variable utilisée doit être déclarée. Conserver cette option. Cela évite les erreurs liées aux variables mal orthographiées.
Si Option Strict est sur On, seules les conversions de type effectuées explicitement sur les variables seront autorisées. Le mettre sur On.
Voir Strict et Option Explicite.
XVI-E-2-d. Utiliser des constantes ou des énumérations
L'usage de constantes facilite les modifications.
Exemple : un programme gère des utilisateurs;:
Faire:
Créer une constante contenant le nombre maximum d'utilisateurs.
Const NombreUtilisateur= 20
Dim VariableUtilisateur (NombreUtilisateur)
For i= 0 To NombreUtilisateur- 1
Next i
|
Plutôt que:
Dim VariableUtilisateur (20)
For i= 0 To 19
Next i
|
Si ultérieurement on veut augmenter le nombre d'utilisateurs possibles à 50, il suffit de changer une seule ligne:
Const NombreUtilisateur= 50
|
Utiliser les constantes VB, c'est plus lisible:
Form1.BorderStyle=2 est à éviter
Form1. BorderStyle = vbSizable c
|
XVI-E-2-e. Vérifier la validité des données que reçoit une Sub une Function ou une Classe
Vous pouvez être optimiste et ne pas tester les paramètres reçus par votre Sub. Les paramètres envoyés seront toujours probablement bons!! Bof un jour vous ferez une erreur, ou un autre n'aura pas compris le type de paramètre à envoyer et cela plantera!!
Donc, il faut vérifier la validité des paramètres.
On peut le faire au fur et à mesure de leur utilisation dans le code, il est préférable de faire toutes les vérifications en début de Sub.
Vérifier aussi ce que retourne la procédure.
XVI-E-2-f. Se méfier du passage de paramètres 'par valeur' ou par 'référence'
Par défaut les paramètres sont envoyés 'par valeur' vers une procédure. Aussi, si la variable contenant le paramètre est modifiée, cela ne modifie pas la valeur de la variable de la procédure appelante.
Si on a peur de se tromper utilisons 'ByVal' et 'ByRef' dans l'en-tête de la Sub ou de la Fonction.
XVI-E-2-g. Structurez le code, évitez les Goto
Faire de bonnes Sub ou de bonnes classes.
Découper les problèmes en sous-ensemble plus simples et ne faisant chacun qu'une tâche.
Structurer le code en evitant les GoTo.
XVI-E-2-h. Ne faire aucune confiance à l'utilisateur du logiciel
Si vous demandez à l'utilisateur de saisir un entier entre 1 et 7.
Vérifier:
qu'il a tapé quelque chose!!
Qu'il a tapé une valeur numérique.
Que c'est un entier.
Que c'est supérieur à 0 et inférieur à 8.
Accorder les moindres privilèges:
Ne permettre de saisir que ce qui est valide.
XVI-E-2-i. Rendre le code lisible par tous
S'il est lisible par tous, il sera lisible et comprehensible par vous même dans un an.
S'il est lisible par tous, il sera déboguable plus facilement.
Pour améliorer la lisibilité:
-Bien choisir le nom des variables.
-Mettre des commentaires.
-Ecrire les algorithmes compréhensibles par tous.
XVI-E-3. Rendre le code lisible : commentaires, noms de variables
Pour faire un code lisible:
- Mettre des commentaires.
- Choisir de bons noms de variable.
- Aérer le code.
XVI-E-3-a. Ajoutez des commentaires
Pour vous; pour les autres.
Au début de chaque routine, Sub, Function, Classe , noter en commentaire ce qu'elle fait et quelles sont les caractéristiques des paramètres:
- Le résumé descriptif de la routine, la Sub ou Function.
- Une description de chaque paramètre.
- La valeur retournée s'il y en a une.
- Une description de toutes les exceptions..
- Un exemple d'utilisation
- Une explication sur le fonctionnement de la routine.
Ne pas ajouter de commentaire en fin de ligne (une partie ne sera pas visible) mais plutôt avant la ligne de code. Seule exception ou on utilise la fin de ligne: les commentaires après les déclarations de variable.
Dim i As Integer
For i= 0 To 100
. . .
|
Paradoxalement, trop de commentaires tue le code autant que le manque de commentaires. Pour éviter de tomber dans le tout ou rien, fixons nous quelques règles:
- Commentez le début de chaque Sub, Fonction, Classe
- Commentez toutes les déclarations de variables
- Commentez toutes les branches conditionnelles
- Commentez toutes les boucles
Commentaire en Xml
On peut ajouter des commentaires en xml dans VB2005.
Exemple:
Pour une Sub: Sur une ligne blanche au dessus de la Sub Calcul, tapez "'''" (3 "'").
ou
Pour une variable: Curseur sur la variable, bouton droit puis 'Insérer un commentaire' dans le menu.
Un bloc Xml "Summary" se crée automatiquement; pour l'exemple de la Sub, ajouter 'Fonction Calculant le total'
Quand ensuite on tape le nom de la Sub , le commentaire s'affiche.
De plus Visual Basic génère automatiquement un fichier de documentation XML lorsque vous créez le projet. Ce fichier apparaît dans le répertoire de sortie de l'application sous le nom AssemblyName.xml.
XVI-E-3-b. Choisissez les noms de procédures et de variables avec soin
On concatène plusieurs mots pour former un nom de fonction, de variable de Classe..
Il y a 3 manières d'utiliser les lettres capitales dans ces mots (on appelle cela la capitalisation!)
- Pascal Case: La première lettre de chaque mot est en majuscule:
- Camel Case: La première lettre de chaque mot est en majuscule, sauf la première:
- UpperCase: Toutes les lettres sont en majuscule:
De plus le nom doit être explicite.
Microsoft propose quelque règles:
- Sub , Fonctions
Utilisez la 'case Pascal' pour les noms de routine (la première lettre de chaque mot est une majuscule).
Exemple: CalculTotal()
Évitez d'employer des noms difficiles pouvant être interprétés de manière subjective, notamment Analyse() pour une routine par exemple.
Utilisez les verbe/nom pour une routine : CalculTotal().
- Variables
Pour les noms de variables, utilisez la 'case Camel' selon laquelle la première lettre des mots est une majuscule, sauf pour le premier mot.
Exemple: iNombrePatient
noter ici que la première lettre indique le type de la variable (Integer), elle peut aussi indiquer la portée(gTotal pour une variable globale).
Évitez d'employer des noms difficiles pouvant être interprétés de manière subjective, 'YYB8' ou 'flag' pour une variable.
Ajoutez des méthodes de calcul ( Min, Max, Total) à la fin d'un nom de variable, si nécessaire.
Les noms de variable booléenne doivent contenir Is qui implique les valeurs True/False, par exemple IsFileFound
Évitez d'utiliser des termes tels que 'Flag' lorsque vous nommez des variables d'état (elles sont différentes des variables booléennes car elles acceptent plus de deux valeurs). Plutôt que documentFlag, utilisez un nom plus descriptif tel que documentFormatType.
Même pour une variable à courte durée de vie utilisez un nom significatif. Utilisez des noms de variable d'une seule lettre, par exemple i ou j, pour les index de petite boucle uniquement.
- Paramètre
Pour les noms de paramètres, utilisez la 'case Camel' selon laquelle la première lettre des mots est une majuscule, sauf pour le premier mot.
Exemple: typeName
- Constantes
Utiliser les majuscules pour les constantes: MYCONSTANTE
N'utilisez pas des nombres ou des chaînes littérales telles que For i = 1 To 7. Utilisez plutôt des constantes par exemple For i = 1 To DAYSINWEEK, pour simplifier la maintenance et la compréhension.
- Objet, Classe
Pour les noms de Classe, utiliser le case Pascal:
Exemple Class MaClasse
Idem pour les évènement, espace de nom, méthodes:
Exemple: System.Drawing, ValueChange..
Dans les objets, il ne faut pas inclure des noms de classe dans les noms de propriétés Patient.PatientNom est inutile, utiliser plutôt Patient.Nom.
Les interfaces commencent par un I
Exemple: IDisposable
Pour les variables privées ou protégées d'une classe utilisez le case Camel:
Exemple: lastValue (variable protégée)
En plus pour les variables privées d'une classe mettre un "_" avant:
Exemple: _privateField
Pour une variable Public d'une classe:
Exemple TotalAge
- Tables
Pour les tables, utilisez le singulier. Par exemple, utilisez table 'Patient' plutôt que 'Patients'.
N'incorporez pas le type de données dans le nom d'une colonne.
- Divers
Minimisez l'utilisation d'abréviations,
Lorsque vous nommez des fonctions, insérez une description de la valeur retournée, notamment GetCurrentWindowDirectory().
Évitez de réutiliser des noms identiques pour divers éléments.
Évitez l'utilisation d'homonymes et des mots qui entraînent souvent des fautes d'orthographe.
Évitez d'utiliser des signes typographiques pour identifier des types de données, notamment $ pour les chaînes ou % pour les entiers.
Un nom doit indiquer la signification plutôt que la méthode.
XVI-E-3-c. Éclaircir, aérer le code
Eviter plusieurs instructions par ligne.
Ajouter quelques lignes blanches.
Décaler à droite le code contenu dans une boucle ou une section If.. End If:
Une mise en retrait simplifie la lecture du code, par exemple :
If . . . Then
If . . . Then
. . .
Else
. . .
End If
Else
. . .
End If
|
Les sources présentés sur cette page sont libres de droits,
et vous pouvez les utiliser à votre convenance. Par contre cette page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © .
Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu :
textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
Cette page est déposée à la SACD.
|