![]() |
Mein Delphi-Style
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:
Delphi-Quellcode:
bzw. aus der DP:
for intZaehler:= intAnfangZeile to intEndeZeile do arrBildfeld[intZeile, intZaehler]:=...
Delphi-Quellcode:
Welch ein redundanter Schwachsinn! Offenbar an einen geistig Behinderten gerichtet. So etwas habe ich in keinem Mathematikbuch gefunden, selbst wenn es Programme enthält.
for iFor:= ...
Der in der Mathematik übliche Bezeichnungsweise einer Matrix Bik folgend schreibe ich
Delphi-Quellcode:
mit Zeilenindex i und Spaltenindex k in den Grenzen ia, ie und ka, ke.
for i:= ia to ie do
for k:= ka to ke do B[i, k]:=... 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
Delphi-Quellcode:
sondern mit einem Typ
pre, pim, zre, zim : extended;
Delphi-Quellcode:
2. Die Punkte zur Beschreibung eines Körpers sind nicht in drei voneinander unabhängigen Arrays
[pre]TKomp= record Re, Im: extended end;
P, z: TKomp;[/pre]
Delphi-Quellcode:
zu speichern, sondern mit einem Feld des Typs
X, Y, Z: array[1..nMax] of extended;
Delphi-Quellcode:
3. Interpolation mit Splinefunktionen: Die Stützstellen und die Koeffizienten der Approximationsfunktionen nicht in unabhängigen Feldern
TPunkt= Record x, y, z: extended end;
TKoerper= array[1..nMax] of TPunkt;
Delphi-Quellcode:
sondern mit den Typen
X, Y: array[0..nMax] of extended; // Stützpunkte
A, B, C, D: array[0..nMax-1] of extended; // Koeffizienten
Delphi-Quellcode:
Kompakter Quelltext
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; 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:
Bei Vergleichen und arithmetischen Operatoren betone ich die Gleichheit der Seiten, indem ich kein oder gegebenenfalls ein Leerzeichen vor und nach dem Operator setze.
const
eps= 1e-8; typ TArr3= array[1..3] of extended; var i, k: integer; begin k:= kMax; In arithmetischen Ausdrücken hebe ich die Termstruktur hervor, indem ich ’+’ und ’–’ mit Leerzeichen umrande (Ausnahme: Indexausdrücke), aber nicht ’*’ und ’/’..
Delphi-Quellcode:
Verwendung von Leerzeilen und Zeilenumbrüchen
y:= a[3]*Power(x, 3) + a[2]*x*x + a[1]*x + a[0];
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:
Nach ’begin’ wird 2 Zeichen weiter eingerückt, mit jedem ’end’ wird 2 Zeichen ausgerückt
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; 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. |
Re: Mein Delphi-Style
Ich hab' nach Jahren auch meinen Stil gefunden. Tatsächlich sind es Kleinigkeiten, die mich bei fremden Code mehr irritieren als man denken sollte.
folgendes:
Delphi-Quellcode:
lese ich deutlich schwerer (ist jetzt ein einfaches Beispiel), als meinen eigenen Stil:
Var
i : Integer; Begin While i >= 0 Do Begin Dec(i); End; End;
Delphi-Quellcode:
Die Großen Buchstaben am Wortanfang von Schlüsselwörtern und die andere Block-Bildung lenken mich ständig vom eigentlichen Inhalt ab. Wenn der fremde Code kompliziert ist, ist meistens mein erster Schritt, die Schreibweise an meinen Stil anzupassen, damit ich ihn schneller/besser verstehe.
var
i : Integer; begin while i >= 0 do begin dec(i); end; end; |
Re: Mein Delphi-Style
Zitat:
Und: Ein hoch auf ihre Mathematikbücher! |
Re: Mein Delphi-Style
Also bei den Blöcken sehe ich das gerade anders herum: Befinden sich begin und end auf selber Ebene ist der Block imho besser erkennbar
|
Re: Mein Delphi-Style
@mkinzler:
Ist er auch! Aber es ist auch nicht die Logik, die mich solche Blöcke schwerer lesen lässt, sondern Jahre der eigenen anderen Schreibweise. |
Re: Mein Delphi-Style
Zitat:
|
Re: Mein Delphi-Style
Zitat:
|
Re: Mein Delphi-Style
Zitat:
|
Re: Mein Delphi-Style
Delphi-Quellcode:
Also über den Code-Stil kann man wohl streiten, obwohl ich es eher so machen würde wie Die Muhkuh ;)
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; Als erstes würde ich diesen Code jedoch ausführlicher kommentieren, gerade wenn es auf irgendwelche Logik u.dgl. ankommt. Das erspart immer noch die meiste Zeit, wenn man sich später wieder in einen Code einarbeiten muss. Ich habe in einigen meiner Projekten einige ziemlich komplexe Methodengefüge, die selbst bei bestem Stil ohne zusätzliche Kommentare nicht auf Anhieb zu verstehen sind... |
Re: Mein Delphi-Style
Ich bin immer für Standards!
Object Pascal Style Guide ![]() s.h auch: GExperts mit Sourcecode Formatter ![]() |
Re: Mein Delphi-Style
Bei sowas brauche ich Leerzeilen, damit ich selber mit klar komme:
Delphi-Quellcode:
Das zieht meinen Code dann immer auseinander. Aber wenn soviel direkt aufeinander sitzt springe ich zwischen den Zeilen und verstehe nicht s mehr ;) (wohl ein persönliches Problem)
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; Operatoren, Zuweisungs/Vergleichszeichen dürfen bei mir meistens auch nicht auf der Variable kleben. Ich übersehe dann beim überfliegen geflissentlich das Symbol. |
Re: Mein Delphi-Style
Bei den JEDIs werden angepasste Standards verwendet, der
![]() Deinen o.g. Code ist meiner Meinung nach nur schwer lesbar und ich würde teils wie die Muhkuh reagieren. |
Re: Mein Delphi-Style
Inwiefern sollte mich dein Delphi-Style interessieren?
|
Re: Mein Delphi-Style
Zitat:
Weder Mukuhhs noch Dein Verständnis für den Code helfen mir, wenn ich Zuhause alleine vorm Rechner sitze. Es ist mir wichtiger, dass ich meinen Code lesen kann. Wenn das etwas ins Forum muss, wird halt umformatiert... Ich gebe hier Beispiele, wie ich Code selber besser lesen kann, keine Regeln für andere Programmierer. Der Thread-Titel heißt ja auch "Mein Delphi-Style"... Falls nicht gemeint war, das man hier seinen Stil posten und kommentieren soll, dann Entschuldigung fürs Off-Topic ;) |
Re: Mein Delphi-Style
Zitat:
|
Re: Mein Delphi-Style
Zitat:
|
Re: Mein Delphi-Style
Wenn das Thema für Dich uninteressant ist, dann gibt es ja keinen Zwang den Thread zu lesen. Ich finde es interessant...
Glaube nicht das er uns bekehren wollte, sondern seine Ansichten mit uns teilen ;) |
Re: Mein Delphi-Style
Bei mir als (einsamer) Hobbyprogrammierer kommt es zum Glück ja mehr darauf an, daß ICH etwas verstehe.
Mag bei der (in Gruppen) arbeitenden Bevölkerungsschicht anders aussehn, dann da müssen ja alle durchsehn. Ansonsten weiß ich, das meine persönlichen Style nicht allen "gefällt", aber ich find es dennoch recht ordentlich. Nja, bei mir hat es sich so über die Jahre entwickelt und ich mag es so. Allerdings sollten wirklich viele mal etwas an ihrem (nicht vorhandenen) Style machen und wenn sie eh es grundlegend ändern, dann wär es schon praktisch sich gleich an solchen allgemeinen "Standards" zu orientieren. Insgesammt wiederspricht also meinem Wohlgefallen einiges: Gut, ich schreib auch oftmal mehreres in einer Zeile, dann aber zumindestens 2 Leerzeichen zwischen de Befehlen, zur Trennung. PS:
Delphi-Quellcode:
da fehlen vor und nach "-" die Leerzeichen ... wenn man sich schon "strikte" Regeln setzt, dann sollte man sie auch "strikt" einhalten :angel2:
Round(sy*(F(x)-yMin))) end end;
ich hab zwar auch so gewisse Regeln, aber in Sonderfällen auch mit optimaleren Ausnahmen. meinen aktuellen Codestyle kann man sich ja vorallem in meinen Programmen hier ansehn und bis jetzt hat sich da noch keiner extrem über was beschwert :angel: Zitat:
nur umformatieren tu ich nicht extra, aber wenn ich fremden Code änder und das für den ersteller des Codes, dann versuch ich zumindestens oftmals mich an dessen Style anzupassen, denn der Code muß dann ja wiederrum in dessen Programm reinpassen. |
Re: Mein Delphi-Style
@himitsu
Ja bei Dir und auch alzaimar ist mir schon positiv aufgefallen, dass die Lösungsvorschläge sich am Code des Fragestellers orientieren (zumindest was ich in meinem Fall an Antworten bekommen hatte). Hier gibt es ja massenhaft Code-Beispiele im Forum. Alles in allem ist der Stil fast aller Poster doch ganz ordentlich. Die Anfänger, die noch gar keinen Stil haben (und Code wie einen Aufsatz schreiben) sieht man dann auch gleich sofort. |
Re: Mein Delphi-Style
Also ich finde, die Standards sind am Besten leserlich, weshalb ich mich weitgehend daran halte. Das heißt also, dass ich Anweisungen auf gleicher Ebene gleich einrücke (außer nach if, for, etc. folgt ein begin, dann ist das untereinander). Wenn ich ein Arument umbrechen muss, rücke ich das so ein, wie das erste Zeichen, das zum Argument gehört). Mich irritieren Großbuchstaben ebenfalls, da sie aber so häufig vorkommen, hab ich mich dran gewöhnt.
Bei Klassennahmen, etc. ist mir vor allem wichtig, dass sie selbsterklärend sind. |
Re: Mein Delphi-Style
Zitat:
Zum Thema : der Borland-Styleguide ist doch wirklich zu gebrauchen. Ich halte mich nur an einer Stelle nicht daran. So wie Satty.
Delphi-Quellcode:
wird so geschrieben :
if xy then
begin ... end;
Delphi-Quellcode:
Und zwar aus zwei Gründen :
if xy then begin
... end; Bei hoher Verschachtelungstiefe fehlt manchmal ein end; oder es ist falsch eingerückt, eines zuviel etc. Interessant ist nun aber nicht, dass zu dem end; irgendwo ein begin steht, das ist ja wohl klar. Interessanter ist, ob das jetzt das for,while,if-end; ist. Das zweite ist das Drucken, bzw. Bildschirmausgabe. Warum soll ich den Code unnötig aufblähen mit überflüssigen Zeilen ? Das gilt auch für eigentlich unnötige Leerzeilen. Der TE-Style ist allerdings auch übertrieben. Eine Variablen-Zuweisung hat nichts in der Zeile zu suchen, in der die Bedingung dafür steht. Wer sich allerdings jetzt zu 100 % an den Borland-Styleguide hät, der machts im Prinzip schon richtig. |
Re: Mein Delphi-Style
Zitat:
@Hansa: Also C-Style |
Re: Mein Delphi-Style
Zitat:
Zitat:
Zitat:
|
Re: Mein Delphi-Style
C-Style ist das ? :gruebel: Der ist dann eben auf meinem Mist gewachsen. :mrgreen: Gründe : siehe oben. Hatte sowieso noch was vergessen. Die Bezeichner. Hier sind ja immer schöne Buttons23 etc. zu begutachten. Die Prefixe klassifizieren ja schon vorab die Variablen. Deshalb gilt (wie gesagt nur bei mir) folgende Nomenklatur : btnWeiter, btnEnde... Dazu braucht man dann auch keinen extra-Kommentar. Um die Beschriftung etwas zu vereinfachen gibt es IDE-Tools wie GExperts oder CnPack. Ohne viel Aufwand kann man dann sinnvolle Namen vergeben (bzw. wird sanft dazu quasi gezwungen). Die Prefixe selber weichen glaube jedenfalls auch etwas von dem Borland-Styleguide ab. Edits haben ed und nicht edt usw. Labels sind die lbl, denn da gibt es ja noch Listboxen, also für die dann lb.
@roter Kasten (Luckie) : nachdem, was ich letztens gesehen habe, ist dieses Buch für die hier gedacht : :cat: . Prozedur maximal 2 Zeilen, oder wie ? Lächerlich. Also jetzt nicht Deine Ausssage, sondern das Buch. :mrgreen: |
Re: Mein Delphi-Style
Nun mein Style ist recht einfach. Jedes Keyword wir immer klein geschrieben. Bezeichner tragen keine Prefixes, der Name sollte auf den Typ schließen lassen. Bezeichner werden in dem UpperCamelCase geschrieben, heißt erster Buchstabe groß, jedes neu Wort groß. Bezeichner von Typen beginnen immer mit T, Interfaces mit I, Pointer mit P, Exception mit E und Resourcestrings mit S.
Delphi-Quellcode:
Wichtig ist auch die Leerzeichensetzung, nach jedem Komma ein Leerzeichen, vor jedem und nach jedem := : ein, zwischen klammern und Bezeichnern keine! Rechenoperatoren immer mit Leerzeichen abtrennen.
procedure TMyObject.MyLittleMethod(Value : Cardinal);
var X, Y, Z : Extended; // Gleiche Typen werden immer hintereinander geschrieben und nicht X : Extended; Y : Extended; Index : Cardinal; SubIndex : Byte; // Variablen, die gleiche Sinne haben, stehen hintereinander. begin { Gedankliche Codesegmente werden so unterteilt. } X := 12; // InlineComments können stehen so wie wollen. Y := 45.8; Z := 7.33; // Wenn kein Platz, dann stehen die Kommentare drüber. for Index := 0 to Value do begin // Irgendwie hab ich mir angewöhnt die Zählervariable immer Index zu nennen. end; end; Dann gibts da noch sowas, dass kann nicht nicht erklären, ich verbinde gerne konstrukte mit einander. So sich andern die Haare streuben finde ich es einfach "schön", eine Art Kunst, es so zu schreiben. Beispiel:
Delphi-Quellcode:
Man könnte fast sagen, ich baue eine Bindung mit meinem Code auf und nur, wenn er auch gut aussieht, ist er ein gute Code.
function BaseCloseHandle(Handle : TBaseHandle) : Boolean; stdcall;
begin if Handles[Handle] = nil then Result := false else begin case Handles[Handle]^.HandleType of // Besonders diese Zeile. bhtObject : Handles[Handle]^.ObjectPointer.Free; bhtWindowsHandle : Windows.CloseHandle(Handles[Handle]^.Handle); bhtCallback : Handles[Handle]^.Callback(); end; FreeMem(Handles[Handle], SizeOf(TBaseHandleData)); Handles[Handle] := nil; Result := true; end; end;
Delphi-Quellcode:
if Count = 0 then Exit;
for Index := 0 to Count - 1 do begin DisplayMode := GetDisplayMode(Index); if ( DisplayMode.Width = Width ) and ( DisplayMode.Height = Height ) and ( DisplayMode.RefreshRate = RefreshRate ) then begin Result := true; Exit; end; end;
Delphi-Quellcode:
EffectHandle := nil;
if FEffect.Bounded then begin IDirectSoundCaptureBuffer8(Effect.BoundedBuffer.Handle).GetObjectInPath( GUID_DSCFX_CLASS_NS, Effect.Description.ID, IID_IDirectSoundCaptureFXNoiseSuppress8, EffectHandle); end else Abort;
Delphi-Quellcode:
Teilweise haue ich auch richtige Hammer raus, die ich aber grade nicht finden kann.
procedure TBaseObject.BeforeDestruction;
var Index : Cardinal; begin BaseDropHandle(SystemHandle); if Length(Dependencies) > 0 then begin for Index := 0 to High(Dependencies) do if Dependencies[Index] <> nil then FreeAndNil(Dependencies[Index]); end; while frefcount > 0 do // Ich weiß nicht wieso, aber das while gehört hir hin. InterLockedDecrement(frefcount); inherited; end; Edit: Gefunden xD :
Delphi-Quellcode:
if AutoOpenFile then try
Stream := TFileStream.Create(FileName); with Stream do case LoadTarget of ltWindow : LoadToWindow(Stream); ltMindmap : LoadToMindmap(Stream); else begin if Stream.Size = 0 then EmptyFile() end end else LoadFail := true; except ShowMessage('Fehler...'); end; |
Re: Mein Delphi-Style
Wenn schon alle ihren Code zur Schau stellen mach ich das jetzt mal auch :mrgreen:
Ich bilde mir ein, relativ nah (bis auf 1-2 Sachen) am Styleguide zu programmieren, aber seht selbst ;) Ich mache gerne sowas:
Delphi-Quellcode:
Also eher nicht kompakt sondern (imho) übersichtlich. Gerne mag ich auch das else if - man könnte auch einfach if schreiben, aber es ist ja doch irgendwie abhängig ...
procedure TFtpBrowser.CreateItemFromFileInfo(const FileInfo: TFileInfo);
var ListItem: TListItem; begin if FileInfo.Filename <> '.' then begin ListItem := FFiles.Items.Add; if FileInfo.FileType = 'Ordner' then if Fileinfo.Filename <> '..' then ListItem.ImageIndex := 0 else ListItem.ImageIndex := 1 else ListItem.ImageIndex := 2; ListItem.Caption := FileInfo.Filename; if FileInfo.Size > 1000000 then ListItem.SubItems.Add(IntToStr (FileInfo.Size DIV 1000000) + ' MB') else if FileInfo.Size > 1000 then ListItem.SubItems.Add(IntToStr (FileInfo.Size DIV 1000) + ' KB') else if FileInfo.Size > 0 then ListItem.SubItems.Add(IntToStr (FileInfo.Size) + ' Byte') else ListItem.SubItems.Add('n/a'); ListItem.SubItems.Add(FileInfo.FileType); ListItem.SubItems.Add(FileInfo.Date); end; end; Noch ein Beispiel:
Delphi-Quellcode:
vor und nach operatoren gehört ein Leerzeichen, vor die Klammer beim Funktionsaufruf aber nicht.
procedure TFtpBrowser.DeleteFile (AFile: String; IsDir: Boolean);
begin if (IsDir and (AFile <> '.') and (AFile <> '..')) then begin try DeleteAll(AFile); FFtp.RemoveDir(FDir.Text + AFile); except TriggerLogEvent('Could not remove directory ' + AFile, etError); end; end else if (not IsDir) then begin try FFtp.Delete (FDir.Text + AFile); except TriggerLogEvent('Could not remove file ' + AFile, etError); end; end; end; Schleifenindizies werden ab i durchnummeriert. |
Re: Mein Delphi-Style
Zitat:
Delphi-Quellcode:
Und RemoveFilesAndDir:
procedure TFtpBrowser.DeleteFile(AFile: String; IsDir: Boolean);
begin if (IsDir and (AFile <> '.') and (AFile <> '..')) then begin try RemoveFilesAndDir(...); except // Fehlerbehandlung end; end else if (not IsDir) then begin try Deletefile(..); except // Fehlerbehandlung end; end; end;
Delphi-Quellcode:
So wird die Methode wesentlich übersichtlicher und man kann mit einem Blick erfassen, was passiert, an Hand der sprechenden Methodennamen.
procedure TFtpBrowser.RemoveFilesAndDir(..);
begin if (not DeleteAll(AFile)) or (not FFtp.RemoveDir(FDir.Text + AFile)) then raise Exception.Create(...); end; Wobei noch zu überlegen wäre, ob man die Fehlerbehandlung nicht auch aus DeleteFile nimmt. Dann kann der Anwender des Codes selber entscheiden, was bei einem Fehler passiert. Ich würde es jedenfalls so machen. TriggerLogEvent wäre dann bei mir in einer eigenen Klasse, die man dem Programmierer mit an die Hand geben kann. @Hansa: So meine ich das. Und wenn ein, zwei zeilen sinnvoll pro Funktion erscheinen, warum nicht. |
Re: Mein Delphi-Style
und ich würde mir den Code so formatieren, ich bevorzuge den Style von Satty allerdings mit 4er Einrückung. Man möge die Übersichtlichkeit im Vergleich zu Muhkuh selber vergleichen :-) Macht sich sehr übersichtlich bei längeren Blöcken. Die Einrückung ist immer wunderbar zu sehen.
Delphi-Quellcode:
if k = kMax then
A[k] := A[k-1] / A[k]; if a = 0 then begin Result := 0 end else begin if a > 0 then Result := 1 else Result := -1; end; if Sender = mnPrintGraphOben then h := ro else h := rm; 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; |
Re: Mein Delphi-Style
die DeleteFile Formatierung finde ich persönlich höchst unübersichtlich. Ein Grundsatz bei uns. Ein "if .. then .. else" entweder komplett ohne ein "begin" und "end", wenn eine einzeilige Anweisungen reicht, oder alle beide Fälle in "begin- end" Blöcke.
In der DeleteFile Formatierung weiter oben würde man überhaupt nicht erkennen, in welchem Fall der Code nämlich einfach nix machen würde. (else Not isDir fehlt) Bei komplizierten Algorithmen kann das schwierig werden. Leerzeilen immer so, wie es am übersichtlichsten aussieht. Dass man den Code auch am "optischen" Eindruck wiedererkennt. so sähe dass bei uns aus..
Delphi-Quellcode:
procedure TFtpBrowser.DeleteFile (AFile: String; IsDir: Boolean);
begin if (IsDir and (AFile <> '.') and (AFile <> '..')) then begin try DeleteAll(AFile); FFtp.RemoveDir(FDir.Text + AFile); except TriggerLogEvent('Could not remove directory ' + AFile, etError); end; end else begin if (not IsDir) then begin try FFtp.Delete (FDir.Text + AFile); except TriggerLogEvent('Could not remove file ' + AFile, etError); end; end; end; end; // DeleteFile edit: bzw sehe ich gerade, dass der Code DeleteFile eine komplett "schiefe" Logik hat, und ich in sauber in einen IsDir und else IsDir unterteilen würde :-) .. (Den Fehler sieht man aber erst, wenn man "ordentlich" formatiert :mrgreen: Eine IsDir Prüfung kann man sich sparen, was vor allen Dingen wichtig ist, wenn es um zeitkritischen Code geht. nämlich so:
Delphi-Quellcode:
procedure TFtpBrowser.DeleteFile (AFile: String; IsDir: Boolean);
begin if (IsDir) then begin if (AFile <> '.') and (AFile <> '..') then begin try DeleteAll(AFile); FFtp.RemoveDir(FDir.Text + AFile); except TriggerLogEvent('Could not remove directory ' + AFile, etError); end; end; end else begin // else IsDir try FFtp.Delete (FDir.Text + AFile); except TriggerLogEvent('Could not remove file ' + AFile, etError); end; end; end; |
Re: Mein Delphi-Style
Zitat:
Delphi-Quellcode:
// Handles[Handle].xyz // hier muß man nicht dereferenieren ... Delphi bemeckert das sogar
Function BaseCloseHandle(Handle: TBaseHandle): Boolean; StdCall; Begin If Handles[Handle] <> nil Then Begin Case Handles[Handle].HandleType of bhtObject: Handles[Handle].ObjectPointer.Free; bhtWindowsHandle: Windows.CloseHandle(Handles[Handle].Handle); bhtCallback: Handles[Handle].Callback; End; FreeMem(Handles[Handle], SizeOf(TBaseHandleData)); Handles[Handle] := nil; Result := True; End Else Result := False; End; // oder Function BaseCloseHandle(Handle: TBaseHandle): Boolean; StdCall; Begin Result := Handles[Handle] <> nil; If Result Then Begin Case Handles[Handle].HandleType of bhtObject: Handles[Handle].ObjectPointer.Free; bhtWindowsHandle: Windows.CloseHandle(Handles[Handle].Handle); bhtCallback: Handles[Handle].Callback; End; FreeMem(Handles[Handle], SizeOf(TBaseHandleData)); Handles[Handle] := nil; End; End; |
Re: Mein Delphi-Style
Gerade Leerzeilen sind ein Zeichen dafür, dass man den Code aufteilen sollte, deswegen meine Aufteilung.
|
Re: Mein Delphi-Style
Zitat:
Also ich füge dich gerne auch einfach mal so ein ... hier mal ne rekursive Funktion:
Delphi-Quellcode:
Naja - jedem das seine ;)
procedure TFtpBrowser.ChangeDir (ADir: String);
begin Working := True; if (ADir = '.') or (ADir = '') then begin TriggerLogEvent('Receiving directory listing', etStatus); FFiles.Clear; CreateDirectoryListing; TriggerLogEvent('Directory listing complete', etStatus); end else if ADir = '..' then begin if FDir.Text <> '/' then begin FDir.Items.Delete(FDir.ItemIndex); FDir.ItemIndex := Pred (FDir.Items.Count); FFtp.ChangeDir(FDir.Text); end; ChangeDir('.'); end else begin if FDir.Items.IndexOf(ADir) > -1 then begin while FDir.ItemIndex <> Pred(FDir.Items.Count) do FDir.Items.Delete(Pred(FDir.Items.Count)); end else if (copy(ADir, 1, 1) = '/') and (copy(FDir.Text, 1, 1) = '/') then Delete(ADir, 1, 1); if (copy(ADir, 1, 1) <> '/') and (copy(FDir.Text, 1, 1) <> '/') then ADir := '/' + ADir; if copy(ADir, length (ADir), 1) <> '/' then ADir := ADir + '/'; FDir.ItemIndex := FDir.Items.Add(FDir.Text + ADir); try FFtp.ChangeDir(FDir.Text); ChangeDir('.'); except TriggerLogEvent('Could not open directory "' + FDir.Text + '"', etError); end; end; Working := False; end; (Mir hat in dem Projekt die Anzahl der Funktionen schon gereicht, jetzt noch Sachen in eigene 3-Zeiler auslagern und ich hätte beim Funktionsbaum nicht mehr durchgeblickt ...) |
Re: Mein Delphi-Style
Die Mathematik ist expliziter Definiert. Bei Formatierungen dürfte sich da eine gewisse Gewohnheit im Team herausbilden und ich sehe eigentlich keinen ernsthaften Grund jede Variante zu Bewerten. Tue ich auch hier nicht, denn der Titel heist ja mein Delphi Style.
Es würde sich bei der Formatierung aber anbieten einen Stil zu wählen, der von den automatischen Formatprogrammen ausgegeben werden kann, damit man auch Fremdcode in eigenen Projekte einpflegen kann ohne alles neu anzufassen. Grüße in die Runde // Martin |
Re: Mein Delphi-Style
Hi,
ich mache es genauso wie Satty, Hansa, Mkinzler und wahrscheinlich viele andere: Borland Styleguide bis auf das begin in der nächsten Zeile. Das Begin am Ende der Zeile ist meiner Meinung nach : - übersichtlicher, man sieht gleich ob das "end" zu einen "if", "for", "while", ... gerade bei längeren Code @Luckie: längerer Code ist zwar "unschön", aber nicht immer lässt sich eine procedure/function auf 2 Zeilen runter brechen - platzsparend Aber im Endeffekt, soll es jeder so machen wie er es am besten findet, wer seinenStil noch nicht gefunden hat sollte sich den Style Guide anschauen. Greetz Data |
Re: Mein Delphi-Style
Zitat:
|
Re: Mein Delphi-Style
Delphi-Quellcode:
außerdem sollte man Funktionen auch nach logischen Gesichtspunkten entwerfen (welche Dinge könnte man wiederverwenden mit welchen Aufrufparametern etc. ), nicht so sehr nach optischen Punkten und Attributen wie "Codezeilen". (es soll ja auch große Monitore mit viel Platz und Übersicht geben :-)
@Luckie: längerer Code ist zwar "unschön", aber nicht immer lässt sich eine procedure/function auf 2 Zeilen runter brechen
Desweiteren ist es manchmal sinnvoll, bei zeitkritischen Stellen einen zusätzlichen Funktionscall zu sparen. |
Re: Mein Delphi-Style
@stoxx: ^^^Absolut richtig ^^
|
Re: Mein Delphi-Style
Zitat:
Gleiches gilt für die Schlüsselwörter FOR und WHILE. Deshalb schreibe ich begin immer in die nächste Zeile. Ich lese die aktuelle Einrückungsspalte gerade runter bzw. scrolle beim lesen entsprechend. Wenn ich nun z.B. eine IF Bedingung finde und ich anhand der Bedingung schon erkenne: Der Fall ist für derzeit uninteressant, dann erkenne ich am begin unter dem IF, ob ich die Spalte runterschauen muss bis zu einem END in der Einrückung oder ich schaue gleich 2 Zeilen tiefer (eine Zeile ist ja der bedingte Code). 2. Platzsparend? Oh, du arbeitest noch 52 MB Platten? Oder warum muss man heute noch Platz sparen? Umweltschutz? Wenn mehr Code ohne Leerzeilen, desto weniger verbraucht die Hintergrundbeleuchtung von deinem Display? Ich bitte dich... Dem Compiler ist es vollkommen egal, also können wir so schreiben, dass es leicht zu lesen und zu verstehen ist. Mit Einrückungen und Leerzeilen wird die Lesbarkeit des Codes erhöht - also für den Menschen. Dem Compiler ist es Wurst - und für mich als Leser sage ich dir: Ich nehme lieber ein paar Leerzeilen in Kauf - für mich musst du kein Platz sparen. Leerzeilen sind auch eine gute Möglichkeit funktionale Codeabschnitte von einander zu trennen. Aber: nie mehr als eine Leerzeile! 3. Allgemein: Leute die den bedingten Code z.B. einer IF, While etc direkt in der selben Zeile hinten dran schreiben, haben noch nie wirklich debuggen müssen. Ich kann beim debuggen niemals sehen ob der Code nach der Bedingung ausgeführt wurde oder nicht. Ich kann diesen schlecht evaluieren, etc. Die Krönung ist dann meist noch den Else Zweig auch noch hinten dran. Dann was vollends nicht mehr, was nun ausgeführt wird. Und nun kommen die Leute, welche behaupten, die Bedingungen sind immer auch zur Debugzeit evaluierbar, weil Optimierungen nutzt man nicht im Debug Kandidaten. Denen nur eins: a) man debuggt Fehler meistens an einem Binary, welches Optimierung an hat. Würde man den Fehler vorher schon finden, bräuchte man ihn nicht debuggen... b) Debuggt mal z.B. Delphi Code in der C++ Personality oder C++ Code, u.a. STL. Dies wird einen schnell dazu bringen das ganze in einzelne Zeilen zu verfrachten. c) Ich muss nicht beim debuggen extra Zeit damit verschwenden die Evaluierung der Bedingung nach zu vollziehen um heraus zu finden, ob die Bedingung nun wahr oder falsch ergibt. Dies sehe ich mit einmal F8 sofort, da die Zeile in die er geht mir anzeigt was er evaluiert hatte. /EDIT: Ziel sollte immer Effizienz sein, mein AG bezahlt mich nicht für's Romane lesen. Und noch weniger gerne bezahlt er mich für's Code formatieren... Und nochmal ein paar ![]() |
Re: Mein Delphi-Style
Zitat:
Delphi-Quellcode:
procedure Test; begin
MyTest; end; Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz