Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Für Fragen von Einsteigern und Programmieranfängern...
Benutzeravatar
stoffel_hessen
Beiträge: 66
Registriert: Sa 18. Jun 2022, 12:27
OS, Lazarus, FPC: Windows 11 (Version 2.2.2, FPC 3.2.2)
CPU-Target: x86 64Bit
Wohnort: Riedstadt

Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von stoffel_hessen »

Hallo abgespaltet vom Tread viewtopic.php?p=129318#p129318
hum4n0id3 hat geschrieben:
Do 28. Jul 2022, 12:47
stoffel_hessen hat geschrieben:
Do 28. Jul 2022, 11:46
Würde ich gerne in Angriff nehmen, allerdings fehlt mir hier der Hintergrund, wie so etwas richtig und gut gelöst wird.
Man muss auch nichts sofort überstürzen, den die Umstellung von Code bringt neuen Aufwand und muss vorbereitet werden. Deswegen ist es eine gute Frage, welche man hier (vielleicht separat im einem extra Thread) erfragen könnte. Mich würde es übringens auch interessieren wie es die Pascal-Profis lösen :)

Ich arbeite hauptsächlich mit PHP, JavaScript und hatte beruflich auch schon mit C# zu tun und ich löse solchen Sachen mit einem Service.
stoffel_hessen hat geschrieben:
Do 28. Jul 2022, 11:46
Als kleines Beispiel, wird aus dem Maschinenname die Loopback-IP-Adresse berechnet (aus xx5325 wird die IP 10.19.215.125).
Und genau das macht dann das Service. Du rufst es auf wenn du es benötigst und hast die Sicherheit das die Daten nicht irgendwo verändert werden. Wenn du dann Fehler feststellst, musst du normalerweise nur das Service untersuchen, ob da nicht der Fehler produziert wird und nicht (im schlimmsten Fall), das gesamte Programm.
und hier die erste Antwort von
af0815 hat geschrieben:
Do 28. Jul 2022, 13:05
stoffel_hessen hat geschrieben:
Do 28. Jul 2022, 11:46
Globale Variablen: Über ein paar Tipps, wie ich dies sinnvoll löse, würde ich mich sehr freuen.
Ich kapsle alles zugehörige in einer Klasse.

Bei mir verwendet: Daher hat die Klasse Maschine alles beinhaltet was sie braucht. Konfiguartionsparameter die allgemeiner sind, sind ebenso in einer Klasse. Das ganze meist in einem Datenmodul.

Generell erzeuge ich zur Laufzeit nur ein Formular (!!) automatisch. Dieses kümmert sich um den Splash, alle Datenmodule, alle Klassen auch um die Initialisierung in der richtigen Reihenfolge. Weil damit wird sichergestellt das alles Resourcen sauber gebunden werden und auch wieder entfernt werden.
Selten verwendet Teile werden sogar erst erzeugt und Initialisiert wenn sie wirklich gebraucht werden.

Sehr starke Verwendung von Frames und der Kapselung von dem Code in den Frames bei optischen Einheiten. Vererbung nur dort wo es sinn macht, die Kommunikation bzw. Datenweitergabe erfolgt über Schnittstellen, Events und Datenmodule. Also sehr modular. Vererbung von Frames ist normal bei mir. Ich habe da eine BasisFrameKlasse die die von mir normalerweise verwendeten Schnittstellen beinhaltet. Zum Beispiel die SQL-Connection. Das Frame selbst hat dezitiert keine Connection, das wird alles vom Hauptformular gemacht. Damit habe ich automatisch auf allen Frames eine Verbindung und wenn ich das Frame in einen anderen Projekt, Maschine, whatever verwende wird es trotzdem richtig and die Datenbank gebunden.

Gewisse Techniken entstehen auch daraus, wie die Arbeitsabläufe in der Firma gehalten werden.
Gruß Christopher

Benutzeravatar
stoffel_hessen
Beiträge: 66
Registriert: Sa 18. Jun 2022, 12:27
OS, Lazarus, FPC: Windows 11 (Version 2.2.2, FPC 3.2.2)
CPU-Target: x86 64Bit
Wohnort: Riedstadt

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von stoffel_hessen »

af0815 hat geschrieben:
Do 28. Jul 2022, 13:05
Generell erzeuge ich zur Laufzeit nur ein Formular (!!) automatisch. Dieses kümmert sich um den Splash, alle Datenmodule, alle Klassen auch um die Initialisierung in der richtigen Reihenfolge. Weil damit wird sichergestellt das alles Resourcen sauber gebunden werden und auch wieder entfernt werden.
Selten verwendet Teile werden sogar erst erzeugt und Initialisiert wenn sie wirklich gebraucht werden.

Sehr starke Verwendung von Frames und der Kapselung von dem Code in den Frames bei optischen Einheiten. Vererbung nur dort wo es sinn macht, die Kommunikation bzw. Datenweitergabe erfolgt über Schnittstellen, Events und Datenmodule. Also sehr modular. Vererbung von Frames ist normal bei mir. Ich habe da eine BasisFrameKlasse die die von mir normalerweise verwendeten Schnittstellen beinhaltet. Zum Beispiel die SQL-Connection. Das Frame selbst hat dezitiert keine Connection, das wird alles vom Hauptformular gemacht. Damit habe ich automatisch auf allen Frames eine Verbindung und wenn ich das Frame in einen anderen Projekt, Maschine, whatever verwende wird es trotzdem richtig and die Datenbank gebunden.

Gewisse Techniken entstehen auch daraus, wie die Arbeitsabläufe in der Firma gehalten werden.
Das hier habe ich leider überhaupt nicht verstanden, möglicherweise fehlen mir hier auch Grundlagen.
af0815 hat geschrieben:
Do 28. Jul 2022, 13:05
Generell erzeuge ich zur Laufzeit nur ein Formular (!!) automatisch
Und wenn mehrer Formulare benötigt werden, wie werden diese erzeugt?
af0815 hat geschrieben:
Do 28. Jul 2022, 13:05
Sehr starke Verwendung von Frames und der Kapselung von dem Code in den Frames bei optischen Einheiten.
was bedeutet das, sind Frames = Formulare?

af0815 hat geschrieben:
Do 28. Jul 2022, 13:05
die Kommunikation bzw. Datenweitergabe erfolgt über Schnittstellen, Events und Datenmodule
Wie funktioniert dies?
Gruß Christopher

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von af0815 »

stoffel_hessen hat geschrieben:
Do 28. Jul 2022, 13:27
Wie funktioniert dies?
https://wiki.freepascal.org/Form_Tutorial/de siehe Von Lazarus designtes Formular dynamisch erstellen

Frames:
https://wiki.lazarus.freepascal.org/Frames/de

Dient alles mal zum EInstieg.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
stoffel_hessen
Beiträge: 66
Registriert: Sa 18. Jun 2022, 12:27
OS, Lazarus, FPC: Windows 11 (Version 2.2.2, FPC 3.2.2)
CPU-Target: x86 64Bit
Wohnort: Riedstadt

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von stoffel_hessen »

af0815 hat geschrieben:
Do 28. Jul 2022, 15:12
https://wiki.freepascal.org/Form_Tutorial/de siehe Von Lazarus designtes Formular dynamisch erstellen
Bis auf das Erstellen zur Laufzeit kenne ich das, trotzdem danke.
af0815 hat geschrieben:
Do 28. Jul 2022, 15:12
Frames:
https://wiki.lazarus.freepascal.org/Frames/de

Dient alles mal zum EInstieg.
Das habe ich noch nie verwendet/benötigt.

Wenn ich aus Form1, Form2 mit Form2.ShowModal öffne und dort
Daten eingebe und wieder schließe, wie kann ich auf diese im Form1 zugreifen/übergeben?
Zuletzt geändert von stoffel_hessen am Do 28. Jul 2022, 16:58, insgesamt 1-mal geändert.
Gruß Christopher

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

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von theo »

stoffel_hessen hat geschrieben:
Do 28. Jul 2022, 16:52
Wenn ich aus Form1, Form2 öffne und dort
Daten eingebe, wie kann ich auf diese im Form1 zugreifen/übergeben?
Du musst im "implementation" Teil "uses Unit1" schreiben, dann kannst du von Unit2 auf Unit1 zugreifen.
Im "Interface" Teil gäbe es eine Fehlermeldung "Circular unit reference between Unit2 and Unit1”

Benutzeravatar
stoffel_hessen
Beiträge: 66
Registriert: Sa 18. Jun 2022, 12:27
OS, Lazarus, FPC: Windows 11 (Version 2.2.2, FPC 3.2.2)
CPU-Target: x86 64Bit
Wohnort: Riedstadt

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von stoffel_hessen »

Und wo schreibe ich die Werte dann hinein, in Variablen oder gibt es hier eine bessere Lösung
Gruß Christopher

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von af0815 »

stoffel_hessen hat geschrieben:
Do 28. Jul 2022, 16:52
Wenn ich aus Form1, Form2 mit Form2.ShowModal öffne und dort
Daten eingebe und wieder schließe, wie kann ich auf diese im Form1 zugreifen/übergeben?
Dann mach mal ein paar Properties und übergebe dort die Daten, nach dem ShowModal frage die Properties ab, bevorst du das Form zerstörst. Man kann dort ganze Strukturen übergeben.

Meine Meinung nach, ist das 'zurückgreifen' von Form2 auf Form1 absolute Quelle von Fehlern. Mach ein klares Interface von Form1 zu Form2 und du kannst Form2 in beliebig vielen Projekten (wieder-) verwenden.

Ähnlich halte ich es mit Frames. Ein dynamisches Frame das alles in sich kapselt. Versorgt wird das Frame über Schnittstellen (eg. Properties) wenn das Frame was unmittelbar zurückmelden müssen, so geht das über die entsprechenden CallBacks (OnXXX - Handler). Damit sind auch die Frames mehrfach verwendbar.

Sowohl Form, als auch Frames lassen sich mit der Technik ausserhalb der eigentlichen App testen und dann in die App einhängen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

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

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von theo »

stoffel_hessen hat geschrieben:
Do 28. Jul 2022, 17:03
Und wo schreibe ich die Werte dann hinein, in Variablen oder gibt es hier eine bessere Lösung
Naja, das kann man schlecht allgemein sagen.
Globale Variablen sind ja nicht verboten, man sollte nur sparsam mit ihnen umgehen.
Man könnte z.B. eine Klasse TMyConfig in einer Unit MyConfig erstellen, wo alle Konfigurationen drin stehen.
Diese könnte dann in einem Initialization (finalization) Abschnitt initialisiert werden. https://wiki.freepascal.org/Initialization

Code: Alles auswählen

Initialization
Globalconfig:=TMyConfig.Create;

finalization
Globalconfig.free;
Diese könnte von jeder Unit verwendet werden (uses MyConfig).
Sie könnte über Methoden wie ReadConfig/WriteConfig verfügen, um die Konfiguration von Datei zu lesen/schreiben. Vielleicht ein IniFile.
Deine 110 Datei Pfade könnte man in eine StringListe oder via CSVDocument einlesen etc.

Das ist nur eine Idee. Ob die zu deinem Design passt, kann man "vom Schiff aus" schlecht sagen.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von Winni »

Hi!

Ergänzend zu Theo ist zu sagen, dass man mit der Anzahl der Units nicht geizen sollte. Das erhält die jeweiligen Units übersichtlich.

Ich lagere z.B. alle globalen Konstanten und Variablen immer in eine Unit XYZconstVar aus. Dort stehen dann auch selbstgeschriebene Helferlein, die man prinzipiell oder für diese spezielle Anwendung braucht. Was z.B. schon inTurbo Pascal fehlte und immer noch keinen Eingang in Lazarus (und Delphi) gefunden hat, ist

Code: Alles auswählen

procedure incF(var f: single; Increment: single =1);
Und die ganze MessageDLG-Arie mit einer einfachen Ja/Nein Abfrage kann man auch in einer einfachen Funktion unterbringen:

Code: Alles auswählen

function YES (MSG : String) : Boolean;
An Konstanten bringt die Unit system zwar Pi mit, aber sonst nix. Deshalb kann man diese geometrischen Kontanten auch hier unterbringen. Wenn man sie braucht,

Code: Alles auswählen

Const
Deg2Rad = pi/180;
Rad2Deg = 180/pi;
Phi= 1.6180;
Weiterhin

Code: Alles auswählen

CSVseparator='|';
SerifFont='Liberation Serif';
SansFont= 'Liberation Sans';
clMellowYellow = $aaffff; 


Und - wie schon erwähnt - gehören hier auch Dateinamen und Pfade hin.

Happy Hacking!

Winni

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
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: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von m.fuchs »

Zum tiefer gehenden Einstieg in sauberen Code empfehle ich gerne dieses Buch:

Clean Code - Refactoring, Patterns, Testen und Techniken für sauberen Code.

Hat jetzt nichts mit Pascal im speziellen zu tun, aber die Techniken kann man auch dort gut verwenden.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

HB9FIH
Beiträge: 11
Registriert: Mi 20. Jul 2022, 10:45
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: 8222 Beringen (CH)
Kontaktdaten:

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von HB9FIH »

Darf ich auch noch meinen Senf ("Würze") dazu geben.
Ich hatte in den 70/80 iger Jahren gelernt zu programmieren.

Ich gehe folgt vor:
1. Papier ... überlegen und ein Nassi - Shneidermann Diagramm erstellen.
2.eigene Regeln - ich erlege mir Regeln (Namen) auf für Variable, Module etc alle Teile in Programmen.
3. füge immer wieder Info in den Source Code ein.
4. ich baue ein Flag ein (das zB als Parameter oder im ini File) gesetzt werden kann. Dann erscheinen immer wieder Meldungen in kritischen Modulen. Das hilft ungemein bei eine Fehlersuche beim Kunden. Auch die einzelnen Fenster enthalten Info zB "KU00 - Bearbeiten der Kundendaten" - wenn man mit einem Kunden am Telefon ist dann ist 100% klar wo der ist. (Ja heute macht man das viel per remote...war halt mal anders aber hat noch Gültigkeit).
5. abfangen von allen möglichen Fehlern (Umwandlung von Daten zB Str to Integer etc, oder Vorhandensein von externen Programen, oder Rückgabewerte von externen Programmen überprüfen. - das Feld ist weit...

Beispiel:
Alle Module zB im Auftrag
beginnen mit AU, die Hauptmodule dann mit eine Zahl AU00 AU01 AU02
Nebenmodule zB Druckmodul (sind dann 3 stellig) AU103 AU003
In anderen Modulen dann zB KU103 (also Druckmodul in Kunden), LO103 (Druckmodul im Lohnwesen).
Ich weiss dass eine nn3 immer ein Druckmodul ist, ein 00 ist immer die hauptsächliche Tabellen Bearbeitung, etc
Oder Variablen:
sProgamm_DIR, sFormular_DIR, s_Daten_DIR - ist sein String s, das andere erklärt sich
dLetztesBeaDatum - Datum letztes Bearbeitungs Datum
Der Vielfalt sind keine Grenzen gesetzt - nur den gleichbleibende Regeln.

Ich kann erkennen, heute nach nurmehr 30 Jahren was ich geschrieben habe. Kann jederzeit ein Modul gezielt erkennen.
(Ja heute muss ich mit denen nix mehr machen, aber ab 2000 gings so weiter und dies ist nun auch 20 Jahre her)
Glaubt mir stochastischer (wilder) Code erfordert früher oder später viel mehr Aufwand. Man vergisst..

Happy coding Erich

Benutzeravatar
stoffel_hessen
Beiträge: 66
Registriert: Sa 18. Jun 2022, 12:27
OS, Lazarus, FPC: Windows 11 (Version 2.2.2, FPC 3.2.2)
CPU-Target: x86 64Bit
Wohnort: Riedstadt

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von stoffel_hessen »

Vielen Dank für eure Informationen und Ratschläge, ich werde bzw. habe davon nun das Eine oder Andere schon umgesetzt.

Ist und bleibt aber trotzdem ein langer Weg.
Habe im Ersten Programm alles von {$MODE Delphi} in {$mode objfpc}{$H+} angeändert und soweit angepasst, was die Applikation wieder läuft.
Auch wurden 2 Units hinzugefügt, eine für die Pfade und eine für die ganzen Const & Variablen, diese aber erst mal ohne lese und schreib Proceduren, der Sinn hierfür Proceduren zu schreiben erschließt sich mir zur Zeit noch nicht.
Gruß Christopher

Benutzeravatar
stoffel_hessen
Beiträge: 66
Registriert: Sa 18. Jun 2022, 12:27
OS, Lazarus, FPC: Windows 11 (Version 2.2.2, FPC 3.2.2)
CPU-Target: x86 64Bit
Wohnort: Riedstadt

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von stoffel_hessen »

Ich zitiere mich mal selbst
stoffel_hessen hat geschrieben:
Fr 29. Jul 2022, 15:55
eine für die ganzen Const & Variablen, diese aber erst mal ohne lese und schreib Proceduren, der Sinn hierfür Proceduren zu schreiben erschließt sich mir zur Zeit noch nicht.
Welchen Vorteil hat es die Daten nicht einfach in eine Variable zu schreiben/lesen, sondern auf diese über Proceduren/Funktionen zurückgreifen und vor allem, wie würdet ihr das lösen?
Über ein kleines Beispiel würde ich mich schon freuen.

Danke
Gruß Christopher

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

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von theo »

stoffel_hessen hat geschrieben:
Fr 29. Jul 2022, 21:12
wie würdet ihr das lösen?
Über ein kleines Beispiel würde ich mich schon freuen.
Wie gesagt, ohne deine Gegebenheiten genauer zu kennen, lässt sich mMn nichts Konkretes sagen.
Mir fehlt schon die Fantasie mir vorzustellen, wie man auf 250 globale Variablen kommt. :wink:
Sind die gar nicht gruppier- bzw. strukturierbar? Es gibt ja auch Records und Arrays/Listen.
Müssen die alle von überall her zugreifbar sein? Warum?

Vielleicht machst du ja auch alles richtig für deinen Fall.
Wie können wir das wissen?

hum4n0id3
Beiträge: 301
Registriert: So 5. Mai 2019, 15:23

Re: Umstellung von Code, wie schreibt man ein Programmcode richtig und gut

Beitrag von hum4n0id3 »

Ist wohl kein Lazarus Weg (eher PHP), aber so würde ich es persönlich lösen.

Code: Alles auswählen

TDeviceIPService = class
  private
    GeraeteArt : string;
    ersteZiffer : string;
    Ziffernrest : string;
    ZiffernInInteger : integer;
    StelleZwei : integer;
    i : integer;
    IPAdresse : string;
    IPAdresseGeraeteklasse : string;
  public
    property IntProp: Integer read FIntProp write FIntProp;
  end;

function DeviceIPService.getIPbyName(Ziffern : string) : string;
var 
begin
  GeraeteArt := copy (Ziffern,1,2);

  if GeraeteArt = 'xx' then IPAdresseGeraeteklasse := '10.19.2';
  if GeraeteArt = 'yy' then IPAdresseGeraeteklasse := '172.24.7.';

  ersteZiffer := copy (Ziffern,3,1);
  Ziffernrest := copy (Ziffern,4,3);
  ZiffernInInteger := strtoint (Ziffernrest);
  if RBxx.Checked
    then      // Loopback Adresse xx
      begin
        StelleZwei := 0;
        for i := 1 to 4 do
        if ZiffernInInteger > 200 then
          begin
            inc(StelleZwei);
            ZiffernInInteger := ZiffernInInteger - 200;
          end;
        IPAdresse := IPAdresseGeraeteklasse + inttostr (StelleZwei) + ersteZiffer + '.' + inttostr (ZiffernInInteger);
      end
    else IPAdresse := IPAdresseGeraeteklasse + inttostr (ZiffernInInteger);   // Loopback Adresse yy
  MaschinennameInIP := IPAdresse;
end;
Den Code habe ich jetzt einfach zusammen geschustert, da ich hier kein Lazarus habe (bin grade zu Gast in Bayern) und dient dem Verständnis.

Es ist eine Klasse mit deiner Funktion aus den anderen Thread. Die legst du in einer Unit ab und kannst sie von überall aufrufen, wo du sie brauchst. Statt also der Globalen Variable, eben

Code: Alles auswählen

ip := DeviceIPService.getIPbyName('xyz');
Das hat (für mich) folgende Vorteile. Ich sehe sofort woher meine GeräteIP kommt. Bei Fehlern muss ich also in dem Service schauen, was dort lost ist und muss nur das Service Debuggen, aber nicht das halbe/ganze Program. Bei großen Projekten mit Globalen Variablen kannst du dir nie sicher sein, wo sie alle verstreut sind und ob nur ausgelesen werden und nicht irgendwo überschrieben werden. Man kann das Service an weitere Begebenheiten anpassen, erweitern und nicht das ganze Programm.

Wie gesagt, das ist die vorgehensweise wie ich in PHP arbeite. Services sind Programmteile die eine bestimmte ServiceLeistung erbringen und dafür kompakt und übersichtlich sind.

Wie in einer Gaststätte. Du setzt dich hin und ein Kellner(Service) kommt mit einer Bestellkarte und der Frage, ob du was trinken möchtest. Der kocht es aber nicht sondern "kellnert" eben nur. Ein Service der Gaststätte.

Antworten