Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Klassendesign und Logik (https://www.delphipraxis.net/199921-klassendesign-und-logik.html)

stOrM 2. Mär 2019 11:59

Klassendesign und Logik
 
Moin,
ich hab mir gerade eine Klasse erstellt, welche Felder einer Tabelle abbilden soll.
Der Grund war, dass ich die eigentliche GUI nur noch zum anzeigen der Daten verwenden will, was mit jedem x-beliebigen Control sein könnte.

Meine Frage wäre jetzt wie bekommt die Klasse mit, dass der Benutzer einen Wert in einem Feld geändert hat, so das wir z.B. ein entsprechendes Update in dieser Klasse, für die Tabelle aufrufen könnten (Ist-Wert entspricht nicht mehr Eingangswert, da müssten ja irgendwie beide Werte vorgehalten werden?)

Sicherlich könnte man da jetzt irgendwas auf die schnelle mit Events zusammenschustern, aber ich würde gern hören, wie Ihr so etwas löst? Vermutlich wesentlich eleganter...

Zacherl 2. Mär 2019 12:12

AW: Klassendesign und Logik
 
Kommt immer ein wenig drauf an. Bewährte Konzepte, welche auch der Trennung von GUI, Business-Logik und Daten dienen sind z.B. MVC oder MVVW. Von der Umsetzung her könnte man unter Delphi z.B. auf DataBindings setzen .. Events sind aber definitiv auch eine legitime Möglichkeit.

Nachtrag:
Oft sind die genannten Konzepte aber etwas starr und zumindest für kleine- bis mittelgroße Projekte mehr Last als von Nutzen. Bezüglich der Wert-Änderung, mache ich das meistens in meiner Model Klasse (deiner Entität, welche die Datenbank-Tabelle abbildet). Dort läuft das bei mir dann über Setter Funktionen der Art:
Delphi-Quellcode:
type
  TModel = class(TObject)
  strict private
    FX: Integer;
  public
    ...
  public
    property X: Integer read FX write SetX;
  end;

...

procedure TModel.SetX(const X: Integer);
begin
  if (FX <> X) then
  begin
    FX := X;
    RaiseUpdateEvent;
  end;
end;

stOrM 2. Mär 2019 12:36

AW: Klassendesign und Logik
 
Zitat:

Zitat von Zacherl (Beitrag 1426793)
Kommt immer ein wenig drauf an. Bewährte Konzepte, welche auch der Trennung von GUI, Business-Logik und Daten dienen sind z.B. MVC oder MVVW. Von der Umsetzung her könnte man unter Delphi z.B. auf DataBindings setzen .. Events sind aber definitiv auch eine legitime Möglichkeit.

Nachtrag:
Oft sind die genannten Konzepte aber etwas starr und zumindest für kleine- bis mittelgroße Projekte mehr Last als von Nutzen. Bezüglich der Wert-Änderung, mache ich das meistens in meiner Model Klasse (deiner Entität, welche die Datenbank-Tabelle abbildet). Dort läuft das bei mir dann über Setter Funktionen der Art:
Delphi-Quellcode:
type
  TModel = class(TObject)
  strict private
    FX: Integer;
  public
    ...
  public
    property X: Integer read FX write SetX;
  end;

...

procedure TModel.SetX(const X: Integer);
begin
  if (FX <> X) then
  begin
    FX := X;
    RaiseUpdateEvent;
  end;
end;


Genau das was ich im Kopf hatte als ich den Eingangspost erstellt hatte.
MVC oder MVVW wäre vermutlich am besten allerdings sehe ich das genau wie Du, für so ein kleines Projekt ziemlicher Overkill, was sicherlich auch wieder Ansichtssache sein kann.

Wie machst Du danach dein Update? Übergibst Du für dein Update SQL nur die Felder die tatsächlich geändert wurden oder machst Du ein Update aller Felder für den entsprechenden Datensatz?

Zacherl 2. Mär 2019 15:49

AW: Klassendesign und Logik
 
Zitat:

Zitat von stOrM (Beitrag 1426795)
Wie machst Du danach dein Update? Übergibst Du für dein Update SQL nur die Felder die tatsächlich geändert wurden oder machst Du ein Update aller Felder für den entsprechenden Datensatz?

Das kommt denke ich ein wenig auf den Anwendungsfall an und vermutlich auch darauf wie viele Felder dein Model hat. Ich arbeite unter Delphi nicht wirklich mit Datenbanken, deshalb kann ich dir da nicht allzu viel zu sagen.

Delphi.Narium 2. Mär 2019 17:32

AW: Klassendesign und Logik
 
Wir nutzen da als "Schnittstelle" je Maske/Formular zwei Methoden:

Eine, um aus dem Objekt die Daten in das Formular zu bekommen und eine, um die Daten aus dem Formular in das Objekt zu bekommen.

Da die Daten datenbankseitig grundsätzlich historisiert/versioniert werden, stellt sich die Frage, ob nur im Formular veränderte Daten übernommen oder alle, nicht.

Jedes Attribut der Klasse hat ein entsprechendes "Gegenstück" im Formular.

Ob man jetzt Plausibilitätsprüfungen in diesen Methoden vornimmt oder in den Settern des Objektes, ist ein bisserl Geschmacksfrage.

Werden Plausibilitätsprüfungen auch benötig, wenn die Daten aus anderen Quellen, als der Maske, übernommen werden, bieten sich die Setter an.

Eventuell erforderliche Typkonvertierungen zwischen Objektattribut und Anzeigecontrol finden in den beiden Methoden statt.

Ghostwalker 3. Mär 2019 06:44

AW: Klassendesign und Logik
 
Wie Zacherl schon sagte, kommt es auf den Umfang der Tabelle (also wieviele Felder) an. Bei kleinen Tabellen, würde ich persönlich gleich alle Felder Updaten.

Bei großen Tabellen, könnte man z.B. in den Settern ein Flag setzten, und beim Update diese Abfragen und so das Statement zusammenbauen.

Schokohase 3. Mär 2019 07:18

AW: Klassendesign und Logik
 
Das hat doch mit dem Umfang der Tabellen nichts zu tun, sondern mit dem Kontext, bzw. wie du Kollisionen entdecken kannst.

Ganz einfaches Beispiel:

Original steht in der DB
Code:
Strasse: Holzweg 3
Ort: Walden
User 1 ändert und speichert
Code:
Strasse(*): Holzpfad 7
Ort: Walden
User 2 ändert und speichert
Code:
Strasse: Holzweg 3
Ort(*): Waldihausen
Heraus kommt jetzt
Code:
Strasse: Holzpfad 7
Ort: Waldihausen
und diese Daten hat kein User jemals so abgesegnet.

ConstantGardener 3. Mär 2019 08:22

AW: Klassendesign und Logik
 
@Schokohase

...na das ist ja dann erst die nächste Baustelle! Der TE hatte noch nichts von MultiUser Umgebung geschrieben, es ging erstmal nur um die Datenhaltung im Objekt usw.

@Storm
Im Prinzip suchst du ja nach einem ORM. Ob du das vom Umfang her benötigst kannst Du nur selbst entscheiden.

Ghostwalker 4. Mär 2019 03:48

AW: Klassendesign und Logik
 
Zitat:

Zitat von Schokohase (Beitrag 1426836)
Das hat doch mit dem Umfang der Tabellen nichts zu tun, sondern mit dem Kontext, bzw. wie du Kollisionen entdecken kannst.

Öhm...dafür gibts sowas wie PrimaryKeys bzw. Unique index, um einen DS eindeutig zu identifizieren. Dein Beispiel läst sich mit einer Plausibilitätsprüfung vermeiden, und hat an und für sich nix mit der DB zu tun. :)

Schokohase 4. Mär 2019 07:20

AW: Klassendesign und Logik
 
Zitat:

Zitat von Ghostwalker (Beitrag 1426868)
Zitat:

Zitat von Schokohase (Beitrag 1426836)
Das hat doch mit dem Umfang der Tabellen nichts zu tun, sondern mit dem Kontext, bzw. wie du Kollisionen entdecken kannst.

Öhm...dafür gibts sowas wie PrimaryKeys bzw. Unique index, um einen DS eindeutig zu identifizieren. Dein Beispiel läst sich mit einer Plausibilitätsprüfung vermeiden, und hat an und für sich nix mit der DB zu tun. :)

Dann hast du mich nicht verstanden.

Der Datensatz mit der ID 1 wird von zwei Benutzern gleichzeitig so wie beschrieben verändert. Wenn jetzt nur die Änderungen der Benutzer gespeichert werden, dann kommt dieser Unsinn heraus.

stOrM 4. Mär 2019 12:20

AW: Klassendesign und Logik
 
Zitat:

Zitat von Schokohase (Beitrag 1426875)
Zitat:

Zitat von Ghostwalker (Beitrag 1426868)
Zitat:

Zitat von Schokohase (Beitrag 1426836)
Das hat doch mit dem Umfang der Tabellen nichts zu tun, sondern mit dem Kontext, bzw. wie du Kollisionen entdecken kannst.

Öhm...dafür gibts sowas wie PrimaryKeys bzw. Unique index, um einen DS eindeutig zu identifizieren. Dein Beispiel läst sich mit einer Plausibilitätsprüfung vermeiden, und hat an und für sich nix mit der DB zu tun. :)

Dann hast du mich nicht verstanden.

Der Datensatz mit der ID 1 wird von zwei Benutzern gleichzeitig so wie beschrieben verändert. Wenn jetzt nur die Änderungen der Benutzer gespeichert werden, dann kommt dieser Unsinn heraus.

Diesen Fall wird es nicht geben, da der Anwendungsfall so simple sein wird, dass nur eine Person Daten ändert, also muss ich mir darüber keinen Kopf machen. Also keine Multiuserproblematik.
Was die Menge der Felder in den Tabellen angeht, mal so mal so, manche sind von der Menge her sehr klein, manche gehen Richtung 40 Felder und mehr, deshalb kam bei mir die Frage auf, direkt alles updaten oder irgendwo zwischen speichern, welche Felder ein Update benötigen.

MyRealName 4. Mär 2019 18:11

AW: Klassendesign und Logik
 
Wenn es professionell eingesetzt wird, kann man da aufg fertige Lösungen setzen, TMS Aurelius kommt da zum Bsp. in Frage. Auch DevArt hat ein ORM framework.

Zumindest bei TMS weiss ich, dass es genau sowas macht, du hast Klassen, die die Tabellen darstellen und du brauchst dich um die DB Sachen nicht zu kümmern. Du lässt dir erzeugte Objecte oder Object-Listen geben und bearbeitest die und wenn du willst, werden sie dann gespeichert

ConstantGardener 4. Mär 2019 18:12

AW: Klassendesign und Logik
 
Kommt natürlich auch drauf an ob du mit einer Embedded Datenbank oder einem Server im Netzwerk arbeitest. Bei der EmbeddedDB kannst du wahrscheinlich ohne Not alle Felder im Update haben. Beim Server produzierst du viel Traffic und das dauert dann schon etwas länger.

stOrM 4. Mär 2019 20:00

AW: Klassendesign und Logik
 
Zitat:

Zitat von ConstantGardener (Beitrag 1426941)
Kommt natürlich auch drauf an ob du mit einer Embedded Datenbank oder einem Server im Netzwerk arbeitest. Bei der EmbeddedDB kannst du wahrscheinlich ohne Not alle Felder im Update haben. Beim Server produzierst du viel Traffic und das dauert dann schon etwas länger.


SQLite vermutlich... Da es eher in Richtung privates Projekt geht, kommen kommerzielle Komponenten / Frameworks nicht in Frage werde ich aber mal im Hinterkopf behalten für ggf. andere Projekte.

ConstantGardener 4. Mär 2019 20:37

AW: Klassendesign und Logik
 
....schau dir evtl. mal NEXUSDB an. Gibt es über GetIt in der Embedded Version kostenlos. Kompiliert mit in die EXE und hat SQL usw.

Ghostwalker 6. Mär 2019 03:42

AW: Klassendesign und Logik
 
Zitat:

Zitat von Schokohase (Beitrag 1426875)
Zitat:

Zitat von Ghostwalker (Beitrag 1426868)
Zitat:

Zitat von Schokohase (Beitrag 1426836)
Das hat doch mit dem Umfang der Tabellen nichts zu tun, sondern mit dem Kontext, bzw. wie du Kollisionen entdecken kannst.

Öhm...dafür gibts sowas wie PrimaryKeys bzw. Unique index, um einen DS eindeutig zu identifizieren. Dein Beispiel läst sich mit einer Plausibilitätsprüfung vermeiden, und hat an und für sich nix mit der DB zu tun. :)

Dann hast du mich nicht verstanden.

Der Datensatz mit der ID 1 wird von zwei Benutzern gleichzeitig so wie beschrieben verändert. Wenn jetzt nur die Änderungen der Benutzer gespeichert werden, dann kommt dieser Unsinn heraus.


Soweit schon richtig, aber das ist unabhängig davon, ob ich nun im Update den gesamten Datensatz wegspeicher oder nur die geänderten Felder. Wie schon gesagt muß das die Eingabeprüfung abfangen, nicht die DB.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:25 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz