Thema: Delphi Mein Delphi-Style

Einzelnen Beitrag anzeigen

Dipl Phys Ernst Winter

Registriert seit: 14. Apr 2009
Ort: Jena
103 Beiträge
 
Delphi 3 Professional
 
#1

Mein Delphi-Style

  Alt 17. Mai 2009, 18:41
Dipl. Physiker Ernst Winter: Mein Stil von Delphi Programmen
Der Compiler unterscheidet nicht zwischen Groß- und Kleinbuchstaben, er überliest eingefügte Leerzeichen, Zeilenumbrüche und Leerzeilen, ihm sind vom Benutzer vergebenen Namen gleichgültig. Das ergibt eine große Variabilität für den richtigen, das heißt compilierbaren Code. Alles was damit zusammenhängt bezeichnen wir als den Stil der Delphi-Programmierung. Es gibt für den Stil keine verbindlichen Regeln, jeder sollte seinen Stil nach seinen eigenen Kriterien entwickeln und ihn nicht unmotiviert ändern.

Für mich kann das einzige Kriterium nur die Lesbarkeit des Programmcodes sein!

Das beginnt bei der Vergabe der Namen für die Bezeichner, Verwendung strukturierter Datentypen und endet mit der optischen Trennung von Code und Kommentaren in einem kompakten Quelltext.
Programmcode ist besser zu verstehen, wenn möglicht viel davon gleichzeitig auf dem Bildschirm zu sehen ist. Die Gurus der Strukturierten Programmierung forderten einmal, dass eine Prozedur vollständig auf den Bildschirm passt. Ich schreibe daher möglichst kompakten Code.

Prinzipielles: Schreibweise der Morpheme (Wörter)
Erster Grundsatz: Im ganzen Programm ist nur eine Schreibweise für jedes Wort zu verwenden. Daraus folgt unmittelbar:
Zweiter Grundsatz: Die Schreibweise der von Delphi vergebenen Wörter ist beizubehalten.
Das betrifft zunächst die durchgängige Kleinschreibung aller Schlüsselwörter. Ich verwende ein Programm DelphiText, um diese beiden Grundsätze abzusichern.
Die Schreibweise der von mir vergebenen Namen ist durch kleingeschriebene Präfixe und InfixCaps gekennzeichnet.

Konventionen zur Namensbildung
Allgemein sind wir uns über die Verwendung von ’selbsterklärenden’ Bezeichnern einig. Das Problem ist nur welche wir erklären müssen.

Namen von Variablen
Naturwissenschaftliche Disziplinen leben wesentlich von ihrer Symbolik. Mathematik, Physik, Chemie und Technik könnten wir ohne symbolische Bezeichnung ihrer Größen kaum verstehen. Dabei haben sich in den einzelnen Disziplinen weitgehend einheitliche Symbole eingebürgert. Mitunter werden zur Klassifizierung der Symbole verschiedene Alphabete verwendet, z.B. in der Mathematik griechische Buchstaben für Winkel, deutsche Buchstaben für Vektoren, fette Buchstaben für Matrizen... Programmiersprachen sind jedoch an ein einziges Alphabet gebunden, an Stelle verschiedener Alphabete können Präfixe verwendet werden.
Die Algorithmen der Programme aus Mathematik, Physik oder Technik entnehmen wir entsprechenden Lehrbüchern oder Monographien. In ihnen stehen Symbole und keine selbsterklärenden Bezeichner!
Wir sollten die dort verwendeten Symbole nicht mit der Forderung nach ’Selbserklärung’ verunstalten, das verwischt nur den Zusammenhang zwischen Algorithmus aus dem Buch und unseren Code.
Ein Beispiel:
for intZaehler:= intAnfangZeile to intEndeZeile do arrBildfeld[intZeile, intZaehler]:=... bzw. aus der DP:
for iFor:= ... Welch ein redundanter Schwachsinn! Offenbar an einen geistig Behinderten gerichtet. So etwas habe ich in keinem Mathematikbuch gefunden, selbst wenn es Programme enthält.
Der in der Mathematik übliche Bezeichnungsweise einer Matrix Bik folgend schreibe ich
Delphi-Quellcode:
for i:= ia to ie do
  for k:= ka to ke do B[i, k]:=...
mit Zeilenindex i und Spaltenindex k in den Grenzen ia, ie und ka, ke.
Da ist doch wohl alles erklärt! Der Code wird kompakter, übersichtlicher und besser lesbar.

Für die kurzlebigen Namen lokaler Variable, deren Gültigkeitsbereich eine Prozedur ist, die oft vollständig auf den Bildschirm passt, verwende ich einem oder maximal zwei Buchstaben. Dabei folge ich der aus FORTRAN stammenden Konvention, dass Namen für Integer-Variable mit den Buchstaben i, j, k, l, m oder n anfangen.
Für den Index der Elemente von Vektoren wird vorzugsweise i verwendet, in Matrizen (immer!) i für den Zeilenindex und k für den Spaltenindex. Namen lokaler Stringvariable beginnen mit dem Buchstaben s.
Damit sind typkennzeichnende Präfixe nach der Ungarischen Notation nahezu überflüssig. Ich halte jedoch für vorteilhaft:
is für boolean, da man eine Boolean-Variable als Bedingung verwenden kann.
p Pointer
T Typ, von Borland eingeführt, eine großgeschriebene Ausnahme.

Ich bilde die Namen von Variablen, deren Gültigkeitsbereiches mehrere Prozeduren umfasst, nach dem Prinzip von Adelstiteln: Je länger eine Variable lebt bzw. je größer ihr Gültigkeitsbereich ist, umso länger und 'selbsterklärender' wird im allgemeinen ihr Name.
In Globale Namen verwende ich InfixCaps, wobei ich einfache Variable kleingeschrieben beginne z. B. iMax und xMax (Anfangsbuchstaben nach der FORTRAN Konvention). Großgeschrieben beginnen Namen von Datenstrukturen (Felder, Records, Files).
Globale Namen von Zahlenstrings bilde ich mit angehängten 'Str' aus ihrer Zahlenvariablen: z.B. XStr für die Stringdarstellung des Werts der Variablen x, beispielsweise gebildet mit Str(x:6:2, XStr).

Namen von Komponenten
Die Namen der Komponenten stehen nicht in den Büchern, sie sollten wir selbsterklärend bilden.
Nach dem Vorschlag von Adrian Vogler (in “Komponenten und Delphi“ Tewi-Verlag 1996) bilde ich den Namen mit einem Präfix für den Typ:
btn Button
lbl Label-Komponente, die vom Programm zur Datenausgabe benutzt werden,
edt Edit-Komponente,
me MaskEdit-Komponente,
mn Menü-Item,
pa Panel,
tab Table, dazu mit
src die zugehörige Datasource,
dahinter steht mit InfixCaps ihre Verwendung.
Beispiele:
Buttons; btnOk, btnAbbruch, btnEnde...
Editierfelder: edtName, meDatum, meX, meX0, meYMin,...
Label: lblName, lblDatum, lblX, lblX0, lblYMin,... zur Anzeige von Werten.
Label, die vom Programm nicht verändert werden, behalten die von Delphi gemachten Vorgaben: Label1...

Verwendung von strukturierten Typen
Pascal wurde von N. Wirth entwickelt, um Studenten die Strukturierung von Daten zu lehren. Ein guter Stil nutzt die entsprechenden Möglichkeiten, um zusammenzuhalte was zusammengehört. Beispiele:
1. Komplexe Zahlen nicht in unabhängigen Variablen
pre, pim, zre, zim : extended; sondern mit einem Typ
Delphi-Quellcode:
[pre]TKomp= record Re, Im: extended end;
P, z: TKomp;[/pre]
2. Die Punkte zur Beschreibung eines Körpers sind nicht in drei voneinander unabhängigen Arrays
X, Y, Z: array[1..nMax] of extended; zu speichern, sondern mit einem Feld des Typs
Delphi-Quellcode:
TPunkt= Record x, y, z: extended end;
TKoerper= array[1..nMax] of TPunkt;
3. Interpolation mit Splinefunktionen: Die Stützstellen und die Koeffizienten der Approximationsfunktionen nicht in unabhängigen Feldern
Delphi-Quellcode:
X, Y: array[0..nMax] of extended;    // Stützpunkte
A, B, C, D: array[0..nMax-1] of extended;   // Koeffizienten
sondern mit den Typen
Delphi-Quellcode:
TPkt= record x, y: extended end;
TKoeff= record a, b, c, d: extended end;
Stp: array[0..nMax] of TPkt;
Koeff: array[0..nMax-1] of TKoeff;
Kompakter Quelltext
Verwendung von Leerzeichen

Abgesehen vom Einrücken werden Leerzeichen zur Verdeutlichung von Aufzählungen und zum Umranden von Operatoren verwendet.
Ich setze ein Leerzeichen nach jedem Komma und Semikolon.
Bei der Umrandung von OPeratoren beachte ich die Gleichwertigkeit der beiden Seiten links und rechts des Operators:
Kann man sie (ohne Syntaxfehler) nicht vertauschen, so betone ich das, indem ich nur ein Leerzeichen hinter dem Operator setze:
Delphi-Quellcode:
  const
     eps= 1e-8;
  typ
     TArr3= array[1..3] of extended;
  var
     i, k: integer;
  begin
     k:= kMax;
Bei Vergleichen und arithmetischen Operatoren betone ich die Gleichheit der Seiten, indem ich kein oder gegebenenfalls ein Leerzeichen vor und nach dem Operator setze.
In arithmetischen Ausdrücken hebe ich die Termstruktur hervor, indem ich ’+’ und ’–’ mit Leerzeichen umrande (Ausnahme: Indexausdrücke), aber nicht ’*’ und ’/’..
  y:= a[3]*Power(x, 3) + a[2]*x*x + a[1]*x + a[0]; Verwendung von Leerzeilen und Zeilenumbrüchen
Ich verwende Leerzeilen nur zur Trennung der Unitabschnitte und der Prozeduren im Implementationsabschnitt. (Da ist einiges von den Delphivorgaben zu löschen).
Kompakter Code trennt eine Anweisung nur, wenn sie nicht auf eine Zeile passt. Wieso sollte sie sich besser lesen lassen, wenn ich sie auf mehrere Zeilen verteile? Die Trennung erfolgt immer vor oder hinter einem Schlüsselwort, wobei ich Trennungen zwischen zwei Schlüsselwörtern vermeide: Beispiele:
Delphi-Quellcode:
  if k=kMax then A[k]:= A[k-1]/A[k]
  if a=0 then Result:= 0 else if a>0 then Result:= 1 else Result:= -1;
  if Sender=mnPrintGraphOben then h:= ro // 'Drucken|Graph oben'
                             else h:= rm; // 'Drucken|Graph unten'
  for k:= 0 to kMax do A[k]:= 0;
  for i:= 1 to iMax do begin temp:= A[i]; A[i]:= B[i]; B[i]:= temp end;
  for i:= 2 to m do begin
    for k:= 1 to i-1 do B[i]:= B[i] - A[r(i,k)]*B[k];
    B[i]:= B[i]/Abs(A[r(i,i)]) end;
  with Image1.Canvas do begin
    MoveTo(DL, D0 - Round(sy*(F(xMin)-yMin)));
    for i:= 0 to 320 do begin
      x:= xMin + i*dx;
      LineTo(DL + 2*i, D0 - Round(sy*(F(x)-yMin))) end end;
Nach ’begin’ wird 2 Zeichen weiter eingerückt, mit jedem ’end’ wird 2 Zeichen ausgerückt
Diese Schreibweise vermeidet die Zeilen auf denen nur ein ’begin’ steht und die völlig unnützen Treppen, deren Zeilen nur ein ’end’ enthalten.
Kommentare
Zu jeder Programmdatei und zu jeder eingefügten selbstständigen Unit gehört ein zusammenfassender Kommentar mit einer kurzen Beschreibung und einer Signatur mit Namen des Entwicklers und dem Datum der Entwicklung.
Ich schreibe diesen Kommentar hinter die Zeile mit der Programm- bzw. Unit deklaration.
Bei den zu einem Formular gehörenden Units können wir auf diesen Kommentar verzichten, da die visuelle Ansicht des Formulares die Aufgabe am besten beschreibt.

Kommentare zum Code dürfen diesen nicht zerreißen. Ich verwende //-Kommentare, die ich rechtsbündig auf dem Bildschirm platziere. Links steht dann entsprechend eingerückt der Code und rechts davon die zugehörigen Kommentare.
Kommentiert wird der Zusammenhang zwischen Code und Anwendung, nicht die Syntax! Wenn da Unklarheiten bestehen, schau ich in die Online-Hilfe.
Eine abschließende Bemerkung
Die Namensbildung und die Verwendung von strukturierten Typen beeinflussen die Lesbarkeit eines Programms mehr als die mehr formellen Aspekte der Verwendung von Leerzeichen und Zeilenumbrüchen.
Autor: DP Ernst Winter
  Mit Zitat antworten Zitat