Accueil
Club Emploi Blogs   TV   Dév. Web PHP XML Python Autres 2D-3D-Jeux Sécurité Windows Linux PC Mac
Accueil Conception Java DotNET Visual Basic  C  C++ Delphi Eclipse MS-Office SQL & SGBD Oracle  4D  Business Intelligence

Cours VB.NET

Date 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

Option Strict=On
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

Option Explicit=On
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.

Dim Taux As Integer= 12

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:

MonAdresse = Nothing

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  'c'est codé en dur!! Que représente 123?
Ecrire:
Const nbMaxLignes As Integer= 123
I=nbMaxLignes 'c'est plus significant

Autre exemple:

Plutôt que:


For i= 0 To 120
Next i

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            'maVariable et v sont la même variable c'est dangereux!!
.. 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:

If x<>0 And y <>0

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)  'on utilise NombreUtilisateur et non 20
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'est mieux

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    'Variable de boucle
'Parcours du tableau à la recherche de..
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:
    
    CalculTotal()
    
  • Camel Case: La première lettre de chaque mot est en majuscule, sauf la première:
    
     iNombrePatient
    
  • UpperCase: Toutes les lettres sont en majuscule:
    
     MACONSTANTE
    

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.

Vos questions techniques : forum d'entraide Accueil - Publiez vos articles, tutoriels, cours et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones. Nous contacter - Copyright 2000..2005 www.developpez.com