Guter Programmierstil

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Guter Programmierstil

Beitrag von Eclipticon »

Guten Morgen,

ein guter Programmierstil kann bekanntlich eine Menge Fehler und den damit verbundenen Aerger von Vornherein verhindern und noch dazu zur Effizienz beitragen ... ich bin daher neugierig, auf welche "stilistischen" Merkmale ihr bei Eurem Code Wert legt.

Was ich beispielsweise zur Fehlervermeidung ueblicherweise verwende ist

Code: Alles auswählen

var
   i: integer;
   Something: array [0...4] of integer;
begin
   for i := Low(Something) to High(Something) do
   // ...
end;
anstatt in der Schleife fix vorgegebener Grenzen ...

Zuck
Beiträge: 71
Registriert: Fr 22. Jul 2011, 18:30
Wohnort: Los Angeles

Re: Guter Programmierstil

Beitrag von Zuck »

Hi,

naja, also dass man Low(), High() für Array-Schleifen verwenden sollte, sollte für jeden, der schon länger als 2 Wochen programmiert klar sein. Im anderen Fall wenn sich mal die Grenzen des Arrays ändern kann man im gesamten Sourcecode nach Schleifen suchen, die das Array verwenden.

Ansonsten sollte man sich noch an einen Styleguide wie diesen hier halten. Das erleichtert auch enorm die Zusammenarbeit mehrerer Programmierer.

Weiters finde ich, sollte man das Konzept der OOP verstanden haben und auch anwenden können und anwenden. Durch die Kapselung ergibt sich wiederverwendbarer Code. Ich kann mich dran erinnern, dass ich vor etwa 8 Jahren (damals noch in Delphi 3 xD) eine Klasse für die Verwaltung von Anwendungseinstellungen geschrieben habe. Diese verwende ich heute (in leicht angepasster Form) noch immer unter Delphi XE.

wfg Zuck

Displaced
Beiträge: 83
Registriert: So 12. Jul 2009, 10:08

Re: Guter Programmierstil

Beitrag von Displaced »

Code: Alles auswählen

if (Assigned(SomeObject)) then begin
  SomeObject.DoSomething;
  SomeObject.DoSomethingElse;
end;
Ich hatte schon aus diversen Gründen verschiedene nicht Initialisierte Objekte.

Amsonsten fällt mir nichts gerade ein... Außer dass ich ganz gerne sowas wie

Code: Alles auswählen

if (IsInRange(Variable, Min, Max)) then begin
...
end;
Mache, wobei IsInRange ne eigene Funktion ist. Weiß nicht ob es sowas auch intern gibt ^^.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2809
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Guter Programmierstil

Beitrag von m.fuchs »

Displaced hat geschrieben:Amsonsten fällt mir nichts gerade ein... Außer dass ich ganz gerne sowas wie

Code: Alles auswählen

if (IsInRange(Variable, Min, Max)) then begin
...
end;
Mache, wobei IsInRange ne eigene Funktion ist. Weiß nicht ob es sowas auch intern gibt ^^.
Was spricht gegen

Code: Alles auswählen

if (Variable in [Min..Max]) then
?

Es gibt zwar gute Gründe manche Wertprüfungen in eigene Funktionen auszulagern, aber ich glaube das hier ist kein solcher Fall.

mfg
mf
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

BeniBela
Beiträge: 320
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Guter Programmierstil

Beitrag von BeniBela »

m.fuchs hat geschrieben: Was spricht gegen

Code: Alles auswählen

if (Variable in [Min..Max]) then
?
Das funktioniert nicht mit negativen Zahlen, oder Zahlen größer 255

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Guter Programmierstil

Beitrag von MmVisual »

Alles mögliche Abfangen gehört immer zum guten und fehlerfreien Programmierstiel, z.B. bei TQuery

Code: Alles auswählen

Procedure DoSomething
begin
  If not Query.Active Then Exit; // Kann nichts berechnen
  If Query.BOF And Query.EOF Then Exit; // Keine Daten für Berechnung
  : :
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2809
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Guter Programmierstil

Beitrag von m.fuchs »

BeniBela hat geschrieben:
m.fuchs hat geschrieben: Was spricht gegen

Code: Alles auswählen

if (Variable in [Min..Max]) then
?
Das funktioniert nicht mit negativen Zahlen, oder Zahlen größer 255
Hoppla, irgendwie hatte ich im Hinterkopf, dass Sets inzwischen keine Größenbeschränkung mehr haben. Ist aber nicht so. Asche auf mein Haupt.

Dann nehme ich natürlich alles zurück und erkläre hiermit: Das ist genau der Fall, in dem man eine solche Prüfung auslagern sollte.
Und die FPC-Entwickler haben das sogar schon gemacht: http://www.freepascal.org/docs-html/rtl ... range.html

mf
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Re: Guter Programmierstil

Beitrag von Eclipticon »

Hi,
Zuck hat geschrieben:naja, also dass man Low(), High() für Array-Schleifen verwenden sollte, sollte für jeden, der schon länger als 2 Wochen programmiert klar sein. Im anderen Fall wenn sich mal die Grenzen des Arrays ändern kann man im gesamten Sourcecode nach Schleifen suchen, die das Array
ich halte es da mit einer Abwandlung von Murphy's Law: Wenn man etwas falsch machen kann, wird es jemand auch falsch machen. Ich glaub auch nicht, dass jeder fuer Variablen, die mehr als ein Mal im Code vorkommen, eine const verwendet ... auch wenn das total offensichtlich ist.

Eclipticon

Zuck
Beiträge: 71
Registriert: Fr 22. Jul 2011, 18:30
Wohnort: Los Angeles

Re: Guter Programmierstil

Beitrag von Zuck »

Eclipticon hat geschrieben:Hi,
Zuck hat geschrieben:naja, also dass man Low(), High() für Array-Schleifen verwenden sollte, sollte für jeden, der schon länger als 2 Wochen programmiert klar sein. Im anderen Fall wenn sich mal die Grenzen des Arrays ändern kann man im gesamten Sourcecode nach Schleifen suchen, die das Array
ich halte es da mit einer Abwandlung von Murphy's Law: Wenn man etwas falsch machen kann, wird es jemand auch falsch machen. Ich glaub auch nicht, dass jeder fuer Variablen, die mehr als ein Mal im Code vorkommen, eine const verwendet ... auch wenn das total offensichtlich ist.

Eclipticon
Deshalb gibt es IMHO eben Programmierer und "Programmierer" ;-)

Eine Sammlung der häufigsten Anfängerfehler wäre vielleicht mal so ne Sache.

wfg Zuck

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Guter Programmierstil

Beitrag von Scotty »

Das sind aber triviale Dinge, die ihr hier aufzählt. Etwas kontroverser ist vielleicht meine Abneigung gegen exit; (üblich in der LCL). Lieber schreibe ich

Code: Alles auswählen

procedure TSomething.SetFoo(const aValue:byte);
begin
  if aValue<>FValue then
  begin
    FValue:=aValue;
  end;
end;
In diesem Zusammenhang sollte vielleicht die Benennung von Variablen nicht vergessen werden. Interne Variablen fangen mit F an, Typen mit T. Ich hasse deutsche Variablenbezeichner und versuche außerdem den Typen beim Namen mit anzugeben, z.B. lbFoo für Label, cbFoo für CheckBox usw.

Displaced
Beiträge: 83
Registriert: So 12. Jul 2009, 10:08

Re: Guter Programmierstil

Beitrag von Displaced »

Nicht nur Anfängerfehler.. Auch Umsteigerfehler!
Ich zum Beispiel hatte Probleme weil ich folgendes gemacht habe:

Code: Alles auswählen

procedure blah();
var
  kekz: TObject;
begin
  kekz := TObject.Create;
  AndereProzedur(@kekz);
  FreeAndNil(kekz);
end;
Hatte dadurch zufällige abstürze die ich nicht Identifizieren konnte...
Der Grund liegt darin, dass Pascal da nicht aufpasst dass das auch da bleibt wo es soll und somit der Zeiger ungültig werden kann in der inneren Funktion / Prozedur. (Oder so ähnnlich, ich hab das nicht 100%ig verstanden).

Oder was mir auch oft passierte:

Code: Alles auswählen

move(array, array2, length);
Wenn man da nicht array[0] drauß macht gibts ebenfalls fehler. (In Delphi nicht)
Zuletzt geändert von Lori am Mo 25. Jul 2011, 15:07, insgesamt 1-mal geändert.
Grund: Highlighter

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Re: Guter Programmierstil

Beitrag von theo »

MmVisual hat geschrieben:Alles mögliche Abfangen gehört immer zum guten und fehlerfreien Programmierstiel, z.B. bei TQuery

Code: Alles auswählen

Procedure DoSomething
begin
  If not Query.Active Then Exit; // Kann nichts berechnen
  If Query.BOF And Query.EOF Then Exit; // Keine Daten für Berechnung
  : :
Naja, kommt drauf an. Wenn diese Bedingungen im Normalfall nicht vorkommen sollten, würde ich das entweder gar nicht abfangen oder dann exceptions raisen oder etwas loggen, damit man auch Wind davon kriegt, dass da was schief läuft.
So allgemein wie du es darstellst, finde ich es nicht unbedingt richtig.

Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Re: Guter Programmierstil

Beitrag von Eclipticon »

theo hat geschrieben:Naja, kommt drauf an. Wenn diese Bedingungen im Normalfall nicht vorkommen sollten, würde ich das entweder gar nicht abfangen oder dann exceptions raisen oder etwas loggen, damit man auch Wind davon kriegt, dass da was schief läuft.
Eine weitere Moeglichkeit, Funktionsparameter zu ueberpruefen, waeren noch Assertions ... ich habe waehrend der Entwicklungszeit immer welche aktiv, generiere aber beim fertigen Programm keinen Code mehr dafuer.

Wie Theo aber schon richtig sagt: Wie man damit umgeht haengt immer davon ab, ob diese Fehlerbedingungen im Normalfall vorkommen koennen ...

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Guter Programmierstil

Beitrag von MmVisual »

Ich habe in meiner App viele Tabellen drin, die in allem möglichen Reitern versteckt sind, die öffne ich nur nach Bedarf, also wenn entweder der User die Tabsheet öffnet oder oben wenn irgend ein Programmteil darauf zugreifen möchte. Letzteres muss dafür sorgen dass die Tabelle schon aktiv ist.

Ich verwende so gut wie kein einziges Try in meinem Programm, sondern lasse es richtig knallen, damit kommt Application.OnException, darin habe ich Routinen die das dann loggen und genau die Aufruf-Hirarchie loggen. So sehe ich auch immer von welcher User-Aktion ausgehend die Exception kam und kann das in meinen 30000 Codezeilen gut nachvollziehen.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Guter Programmierstil

Beitrag von Socke »

MmVisual hat geschrieben:Ich verwende so gut wie kein einziges Try in meinem Programm, sondern lasse es richtig knallen, damit kommt Application.OnException, darin habe ich Routinen die das dann loggen und genau die Aufruf-Hirarchie loggen. So sehe ich auch immer von welcher User-Aktion ausgehend die Exception kam und kann das in meinen 30000 Codezeilen gut nachvollziehen.
Ich halte try..except schon für sinnvoll; dann kann man den Benutzer an der richtigen Stelle auf einen Eingabefehler hinweise oder ähnliches. Was du beschreibst ist aber eher ein Design-Konzept für die ganze Software als ein Programmierstil.

Ich halte ja untypisierte Parameter für ein Unding von Pascal. Ein häufiges Beispiel ist der Datei-/Stream-Zugriff: Wenn ich da eine Zeichenkette speichern möchte übergebe ich nicht die ganze Zeichenkette (String) sondern nur den ersten Buchstaben. Von dem wird dann die Adresse ermittelt und alles bis n Bytes danach geschrieben. Meine Idee wäre dann schon wirklich den Mut zu haben und zu sagen: da hast du ’nen Pointer auf den Speicherbereich den ich speichern möchte und hier die Anzahl ... aber einen Buchstaben zu übergeben, von dem dann auf die Zeichenkette geschlossen wird... da kann ich nur immer mit dem Kopf schütteln.

Ansonsten kann man noch trefflich darüber streiten, was von dem Folgenden denn besser wäre:

Code: Alles auswählen

var
  o: TObject;
//..
if Assigned(o) then begin
// tue was
end;
// oder auch
if o = nil then
begin
// tu was
end;
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Antworten