Organisation et mise en forme du code source
Indentation et alignement
Chaque niveau d’imbrication est mis en retrait de deux espaces. N’utilisez jamais de tabulations, car leur rendu varie selon l’éditeur. Dans les options d’environnement (menu Tools > Environment Options, onglet General), décochez Use Tab Character et Optional Fill pour éviter d’enregistrer des caractères de tabulation.
Limite de longueur des lignes
Le code ne doit pas dépasser 80 caractères. Si une instruction dépasse cette limite, coupez-la après un opérateur ou une virgule et indentez la suite avec deux espaces supplémentaires.
Structures begin...end
Le mot-clé begin se place systématiquement sur une nouvelle ligne, sauf lorsqu’il fait partie d’une clause else. Le end correspondant est toujours sur une ligne dédiée et aligné avec le begin.
// Incorrect
for i := 1 to 5 do begin Traitement(i); end;
// Correct
for i := 1 to 5 do
begin
Traitement(i);
end;
Exception pour le else :
if condition then
begin
...
end
else begin
ActionAlternative;
end;
Commentaires
Privilégiez les blocs { ... } pour les commentaires standards. L’ancienne syntaxe (* ... *) peut servir à masquer temporairement une portion de code pendant le développement. La notation mono-ligne // est également acceptable si la compatibilité avec Delphi 2 est abandonnée.
Espaces et parenthèses
Aucun espace n’est inséré entre une parenthèse et le caractère adjacent :
Calculer( a, b ); // incorrect
Calculer(a, b); // correct
Les parenthèses superflues sont à éviter :
if (EstValide) then // inutile
if (EstValide) or (EstNeuf) then // nécessaire à cause de la priorité
Mots réservés et types
Les mots réservés du langage s’écrivent entièrement en minuscules. Les types issus de l’API Win32 conservent leur casse d’origine (par exemple HWND). Les noms de variables commencent par une majuscule et alternent minuscules/majuscules ensuite.
var
ChaineLocale: string; // type réservé
Fenetre: HWND; // type API
Compteur: Integer; // type standard
Nombres à virgule flottante
Évitez le type Real (conservé pour compatibilité). Utilisez Double par défaut, car il est optimisé par le processeur et conforme à la norme IEEE. Extended peut être employé lorsque la plage de valeurs est insuffisante, mais il est spécifique à Intel. Si la taille physique de la variable est cruciale (par exemple pour une DLL), préférez Single.
Variants
Les types Variant et OleVariant ne doivent être utilisés que lorsque le type de données n’est connu qu’à l’exécution (COM, bases de données). Pour l’automatisation ActiveX, utilisez OleVariant. Dans les autres contextes, Variant est préférable car il conserve le format natif des chaînes Delphi.
Structures de contrôle
Instruction if
Placez la branche la plus probable dans le then et la moins probable dans le else. Privilégiez une expression case lorsque le nombre de conditions dépasse cinq. L’évaluation logique s’effectue de droite à gauche dans la pile d’appels du compilateur ; si vous connaissez la probabilité d’échec d’une condition, placez-la en premier pour tirer parti de l’évaluation court-circuitée :
if ConditionRapide and ConditionMoyenne and ConditionLourde then ...
// ou, si ConditionLourde échoue souvent :
if ConditionLourde and ConditionRapide and ConditionMoyenne then ...
Instruction case
Les constantes sont ordonnées (numériquement ou alphabétiquement). Si le bloc d’une branche dépasse 4-5 lignes, extrayez-le dans une procédure ou fonction séparée. La clause else ne doit servir qu’au cas par défaut ou à la détection d’erreur.
Boucles while, for et repeat
Évitez d’utiliser Exit pour sortir d’une boucle ; préférez la condition de boucle. Toute initialisation relative à la boucle doit précéder directement l’entrée, sans instruction parasite. Quand le nombre d’itérations est connu, privilégiez for plutôt que while. Les règles de repeat sont analogues à celles de while.
Instruction with
Utilisez with avec parcimonie. Évitez les combinaisons de plusieurs objets ou enregistrements du type with Obj1, Obj2 do, qui rendent le code difficile à lire et à déboguer.
Gestion structurée des exceptions
Toute allocation de ressource doit être protégée par un bloc try...finally, sauf dans les sections d’initialisation/finalisation d’unité ou dans les constructeurs/destructeurs. Par exemple, la séquence suivante n’est pas sûre :
SourceA := TConnecteur.Create;
SourceB := TFlux.Create;
try
// traitement
finally
SourceA.Free;
SourceB.Free;
end;
Version sécurisée :
SourceA := TConnecteur.Create;
try
SourceB := TFlux.Create;
try
// traitement
finally
SourceB.Free;
end;
finally
SourceA.Free;
end;
Réservez try...except aux cas où une action spécifique est nécessaire en cas d’exception. Ne l’employez pas simplement pour afficher un message d’erreur, l’objet Application s’en charge. Évitez le try...except...else, qui intercepte toutes les exceptions, y compris celles que vous n’avez pas prévues.
Conventions de nommage
Procédures et fonctions
Le nom doit décrire l’action ou la valeur retournée. Une procédure qui effectue une tâche commence par un verbe : procedure FormaterDisque;. Les accesseurs utilisent les préfixes Set et Get : procedure SetNomUtilisateur(const Nom: string);, function GetNomUtilisateur: string;.
Paramètres formels
Donnez un nom explicite à chaque paramètre. En cas de risque de conflit avec un champ ou une propriété, préfixez le paramètre par a (exemple : procedure Definir(aNom: string; aAge: Integer);).
Conflits de noms d’unités
Lorsque deux unités exportent un symbole identique, l’appel non qualifié résout vers la dernière unité de la clause uses. Pour lever toute ambiguïté, qualifiez le symbole avec le nom de l’unité : SysUtils.FindClose(Handle); ou Windows.FindClose(Handle);.
Variables
Variables locales
Les boucleurs simples peuvent s’appeler i, j, k ; dans les cas plus complexes, préférez un nom explicite comme IndexUtilisateur. Les booléens doivent être nommés de manière à identifier sans ambiguïté les valeurs True et False.
Variables globales
Elles sont préfixées par la lettre majuscule G, par exemple GCounter, GDatabasePath.
Types
Énumérations
Le nom du type est préfixé par T ; les énumérateurs partagent un préfixe de deux ou trois minuscules pour renforcer la cohérence visuelle.
type
TGenreMusical = (gmRock, gmClassique, gmCountry, gmAlternatif, gmMetal, gmRB);
var
MonGenre: TGenreMusical; // ou GenreFavori1, GenreFavori2...
Tableaux
Le nom du type tableau commence par T. Le type pointeur associé, déclaré juste avant, commnece par P.
type
PListeCycles = ^TListeCycles;
TListeCycles = array[1..100] of Integer;
var
MesCycles: TListeCycles;
Enregistrements
Même règle : nom du type avec T, pointeur avec P.
type
PEmploye = ^TEmploye;
TEmploye = record
Nom: string;
TauxHoraire: Double;
end;