Commentaires sans douleur

" Les débutants ne commentent rien ; les novices commentent l'évident ; les initiés commentent la raison du code; les gurus commentent la raison du code non utilisé."
Richard C Haven

Il y a plusieurs niveaux de commentaires. Je vais illustrer ici ceux que j'utilise basé sur mon expérience de programmeur commercial.

LE PROGRAMME

Ces commentaires sont ceux contenus dans les propriétés du projet. Ne pas les négliger dès que votre programme a des chances de se retrouver sur quelque réseau de distribution car c'est votre carte de visite.
Ils sont visibles dans le dialogue "Properties" quand vous cliquez avec le bouton droit sur votre application et devraient être lisible dans votre dialogue "About"

Dans l'ordre :

Comments : mettez ce qui ne va dans aucune autre section et qui pourrait servir dans votre dialogue "About".
Company name : Inventez-en une (Barn Cat Software, Three Bits Cie...) Même humoristique, ça fait plus sérieux.
File Description : que fait votre application en langage simple.
Legal copyright : soit "Copylefted 2006" (tout le monde copie) soit "Copyright © 2006 <MaCompagnie>. All rights reserved."
Certaines personnes mettent ici toute sortes d'avertissements à propos d'avocats et de poursuites... Les gars, soyons sérieux.
Legal trademark : <MonApplication>© est la propriété exclusive de <MaCompagnie>©. Toute autres marques de commerce sont la propriété de leurs propriétaires respectifs. (Le © est obtenu en tapant ALT 000169)
Product name : <MonApplication>©

MODULE, CLASSE, FORME, USERCONTROL

Le haut de chacun de ceux-ci devrait avoir un bloc de type

 '=====================================================================================
' <MonProgramme>
' frmTips va montrer un commentaire aléatoire lors de son ouverture.
'
' Copyright © 2006 <MaCompagnie>. All rights reserved.
'=====================================================================================

FONCTIONS ET SUBS

Les fonctions et les subs devraient toutes avoir un bloc de commentaire qui permettent à un non-initié de savoir ce que fait cette fonction et sous quelles conditions, les paramètres à passer avec certaines valeurs limites et les valeurs de retour.

Une bloc exemple dont je me sert:

 '===================================================================
' Appelle la routine "Decrypt", changera l'extension de "dmE" (encrypté)
'   à "dmS" (décrypté)
'
' Parameters
'   strFilename     : nom de document existant à décrypter [IN][OUT]
'   nKey            : integer variant de 1 à 9  [IN] Zéro non valide.
'
' Return
'   Boolean         : TRUE si décrypté, FALSE autrement
'                  Un document de longueur zéro causera une erreur fatale de
'                 décryption.
'====================================================================

Vous noterez l'usage de [IN] pour les ByVal et de [IN][OUT] pour les ByRef, ByRef étant utilisé à la fois pour recevoir un argument et pour passer une valeur vers la foncton appelante.

Ce cas simple peut sembler puéril mais voyons celui-ci:

 '=====================================================================================
' Crée une archive de type Zip dans le dossier cible.
' Ces archives doivent être de vrai documents et non des raccourcis.
' Ces archives doivent être en un seul endroit.
' L'utilisateur doit être admin de la machine source.
' Les noms de dossiers doivent être unique à chaque niveau.
' Caractères illégaux: _ . , (accentués) 
' Cette routine prends 2 sec par Megs de données.
'
' Parameters
'   strRoot         : path du root d'archive; peut être en réseau [IN][OUT]
'   blnFlags       : /PIC ;/DOC ;/XML; /OTH    [IN] La présence d'un flag indique VRAI
'
' Return
'   long         : err_NOERROR si succès, sinon err_<cause d'erreur>
'            : Vor liste de constantes
'====================================================================================

Pour résumer:
'===============================================================
' Action: une seule est nécessaire. Sinon faire plusieurs functions.
' Ajouter toutes notes d'utilisation utiles pour quelqu'un qui ferait du copier/coller d'un projet vers un autre.
' Celles-ci seront tout à fait vitales si cette fonction se ramasse dans une librairie de code commune.
'
' Paramêtres:' : mettre non le type mais sa raison d'être ByVal [IN * , ByRef [IN][OUT]
'
' Return value:
' Type : si un BOOLEAN, mettre pourquoi FAUX, pourquoi VRAI.
' : si une valeur d'erreur, mettre la constante NoError et notez ou sont les autres valeurs
' ; Si une vrai valeur de retour mettre la valeur si Succes, et celle si Erreur.
' Calls:
' Quelquefois, pour les fonctions complexes, je mets les nom des fonction appelées.
'
'===============================================================

CLASSE, USERCONTROLs

Les classes et les usercontrols sont un peu spéciaux en ceci qu'ils servent à faire (ou sont déjà) des objets qui exposent des méthodes, des propriétés et des événements.

Pour une classe simple, un nom peut suffire mais pour un objet complexe, il faut commenter le API (Application Programming Interface) au complet avec des exemples. C'est indigeste mais essentiel car c'est le mode d'utilisation de votre oeuvre.

Comme ceci:(Deux méthodes et une 'event' sont illustrées seulement)

' =============================================================
'classe activityMAKE API
'===============================================================
' Property InputMaterial
' 'Set' ou 'Get' le materiel de type 'oMatNonDuplicable'
' Note d'usage:
'    <objectName>.InputMaterial(aMat)
'    Set anotherMat = <objectName>.InputMaterial
' Un materiel 'NULL' créera un materiel par défaut.
' Un materiel avec des champs vide (EMPTY) va créer un materiel
'    incohérent.
' --------------------------------------------------------------
' Property SetCalendar
' Etablira le calendier selon le document XML ou selon défaut.
' La méthode Init de l'object doit avoir mise les valeurs par défaut.
' Note d'usage:
'    <objectName>.SetCalendar(XMLfilename)
'    <objectName>.SetCalendar("")
'    PAS DE METHODE 'Get'
' --------------------------------------------------------------
' Event MaterialReleased
' Renvoie la date et l'heure sous format 'YYYYMMDD;HHMMSS'
'    en String
.....
'===============================================================
'END OF API
'===============================================================

Mettre ce pavé en haut de la classe.

CODE

Tout commenter n'est guère utile.
En règle générale, je mets:

  • la raison d'une étape,
  • le détail d'un algo si ce détail n'est pas évident du premier coup d'oeil,
  • la structure de donnée qui doit être manipulée,
  • la raison d'un maniement d'erreur,
  • toute chose qui risque de ne pas être comprises plus tard ou qui peut sauver du temps et des source d'erreurs à la relecture.

Voici quelques exemples de chaque règle un peu en vrac:

'1 ---------------------------------------------
If j > 0 Then
    ' impossible d'enlever le dernier tab d'un TabStrip.
    tabMaps.Tabs.Remove j
    ' dernier contrôle d'un array ne peut être enlevé
    Unload ucPictureSiz1(j)

'2 ---------------------------------------------
' Note: La méthode .Line ne supporte pas
'   un block "With/End With"

'3 ---------------------------------------------
'Pour un document XML chargé dans une ListView

For j = 0 To nAttCount - 1 Step 1
    '
    Select Case aNode.Attributes.Item(j).baseName
        Case "onmap"
            strwhichmap = aNode.Attributes.Item(j).Text
                                            
        Case "id"
            strID = aNode.Attributes.Item(j).Text
                                            
        Case "name"
            strName = aNode.Attributes.Item(j).Text
                                            
        Case "posx"
            strposX = aNode.Attributes.Item(j).Text
                                            
        Case "posy"
            strposY = aNode.Attributes.Item(j).Text
                                            
        Case "icon"
            strsymbol = aNode.Attributes.Item(j).Text
                                            
        Case Else
            '
    End Select
Next j
' now we can start adding to the lists
'------------------------------------------------------------------------
' lsvPlayers
'  col#     what
'------------------------------------------------------------------------
'   0       playerID
'   1       name
'   2       whichmap    map ID
'   3       posX        upperleft corner X coord of avatar
'   4       posY        upperleft corner X coord of avatar
'   5       symbol      key for custom symbol (unused for now)
'------------------------------------------------------------------------
Set itm = lsvPlayers.ListItems.Add(, strID, strName)
    SubItems(1) = strwhichmap
    SubItems(2) = strposX
    SubItems(3) = strposY
    SubItems(4) = strsymbol

'4 ---------------------------------------------
Input #nfilenum, frm_strLastCampaignDate
' détecter une ancienne version
If Err.Number <> 0 Then' 62 Input past end of file
    ' données n'existent pas: mettre valeur par défaut
    ' format: YYYY;MM;DD as ####;0#;0#
    '   "Janvier 1, 2006" serait "2006;01;01"

'5 ---------------------------------------------
' format: YYYY;MM;DD as ####;0#;0#
'   "Janvier 1, 2006" serait "2006;01;01"

Ce document intitulé « Commentaires sans douleur » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Rejoignez-nous