AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Datenbankanwendung und Klassen - sinnvoll?
Thema durchsuchen
Ansicht
Themen-Optionen

Datenbankanwendung und Klassen - sinnvoll?

Ein Thema von süden · begonnen am 9. Jan 2014 · letzter Beitrag vom 13. Jan 2014
Antwort Antwort
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.869 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: Datenbankanwendung und Klassen - sinnvoll?

  Alt 10. Jan 2014, 10:25
Zitat:
ORM bzw. OPF ??? Das Rad neu erfinden? Gibts doch schon, welche sind gut?
(Reihenfolge ohne Wertung)
hcOPF
dORM
mORMot
tiOPF
TMS Aurelius
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.352 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Datenbankanwendung und Klassen - sinnvoll?

  Alt 10. Jan 2014, 14:23
ich liebäugel schon lange mit Klassen (nicht lachen bitte), und habe ein schlechtes Gewissen, weil ich noch keine selbst gebaut habe.
Du musst Dich nicht schämen, das ist nix schlimmes, aber Du solltest daran arbeiten...

Das Thema interessiert mich auch sehr. Im Grunde geht es um einen Themankomplex:

- Trennung Daten+Geschäftslogik von der GUI
- lose und einfache Verbindung der beiden Schichten
- effektive und einfache Definition der Klassen
- effektive und einfache Einbindung von Datenbanken (ORM)

Ich finde es schade, dass das Thema bisher so vernachlässigt wird.
Es gibt zwar verschiedene Lösungen für einzelne Teilaspekte aber m.E. nichts was alles abdeckt.

Im Grunde geht es daraum:
- Ich will sehr einfach Klassen definieren. Bestenfalls über Metadaten (also Auflistung der gewünschten Probpertys) oder sogar grafisch. Die grundlegenden Eigenschaften und Fähigkeiten sollen automatisch vorhanden sein.
- Ich will den Klassen die Geschäftslogik (Methoden) hinzufügen können.
- Ein Framework soll sich darum kümmern, die Objekte zu erzeugen, zu verwalten und auf Anfrage bereit zu stellen (Kunde(12345)).
- Die Datenspeicherung soll ebenfalls automatisch und möglichst flexibel erfolgen.
- Die GUI soll keinerlei Kenntnis der Daten und Geschäftslogik haben. Sie soll lediglich wissen, welche Daten sie darstellen soll (Namen eines Kunden oder Kennzeichen eines KFZ) und wo sie diese abrufen kann. Die GUI sollte also weitgehend ohne Quelltext auskommen. Wenn ein KFZ-Objekt in seiner Eigenschaft HatTÜV false liefert könnte ein OK-Schalter deaktiviert werden, ohne dass die GUI selbst weiß warum.
Dafür muss die Datenschicht natürlich Schnittstellen bereit stellen, an die die GUI gebunden werden kann.


Grundsätzlich würde ich komßplexere Projekte eher mit Klassen aufbauen, da die Projekte dann aus meiner Sicht flexibler zu warten und besser zu verstehen sind.
Andererseits ist es natürlich auch möglich, die gesamte Funktionalität in Datenbanken zu packen und dann in der GUI nur noch dumme DB-Controls zu verbauen.
Letztlich ist das Geschmacksache und von den eigenen Fähigkeiten abhängig (bzw. davon was man als Entwickler besser kann).

Wichtig ist auf jeden Fall, die Geschäftslogik nicht in der GUI umzusetzen und beides miteinander zu vermischen. Dann hat man schon mal die besten Voraussetzungen für eine vernünftige Projektstruktur.

Ich würde mir wünschen, dass Delphi diesbezüglich besser unterstützen würde.



Hier mal einige Links, die in diese Bereiche gehen:
http://www.delphipraxis.net/164573-d...nd-hoeher.html
http://www.delphipraxis.net/161102-k...onisieren.html
http://www.delphipraxis.net/172249-d...iskussion.html
http://www.delphipraxis.net/165090-g...nkprojekt.html
http://www.delphipraxis.net/164270-k...zu-mormot.html
http://www.delphipraxis.net/176478-m...realitaet.html

Und natürlich:
[Werbeblock]
http://www.delphipraxis.net/173360-s...framework.html
[/Werbeblock]
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Datenbankanwendung und Klassen - sinnvoll?

  Alt 10. Jan 2014, 14:54
Kann sein, daß ich Dich da falsch verstanden habe:
Zitat:
- Die GUI soll keinerlei Kenntnis der Daten und Geschäftslogik haben. Sie soll lediglich wissen, welche Daten sie darstellen soll (Namen eines Kunden oder Kennzeichen eines KFZ) und wo sie diese abrufen kann.
Wenn das (G)UI keine Ahnung von den Daten hat, dann übergibst Du kein KFZ-Kennzeichen, sondern einen 10(?)stelligen alphanumerischen Code.

Übrigens würde ich zumindestens die "Oberflächenlogik" als Teil des UI behandeln. Typische Schreibfehler erkennen, ist oft von der eingesetzten Tastatur(sprache) abhängig. Damit würde ich die "Geschäftslogik" nicht belasten.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.352 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Datenbankanwendung und Klassen - sinnvoll?

  Alt 10. Jan 2014, 15:32
Stimmt beides.


1) Binding

Die GUI-Controls sollen m.E. nicht die gesamte Datenschicht und schon gar nichts von der Businesslogik kennen.

Ein Edit soll nur wissen, dass es die Eigenschaft Name eines Objektes mit der ID 12345 darstellen und ggf. ändern soll.
Oder die Eigenschaft Caption des Objektes mit dem Namen "Form1".
Oder die Eigenschaft "Kennzeichen" eines Objektes mit dem Namen KFZ1.

Das Edit muss dann einen Manager beauftragen, das gewünschte Objekt zu finden und muss dann nachsehen, ob dieses die gewünschte Eigenschaft besitzt. Ggf. muss der Wert der Eigenschaft noch in einen anderen Datentyp umgewandelt werden.

Der Manager seinerseits kann nach bestimmten Regeln in der Datenschicht nach dem Objekt suchen oder z.B. auch per FindComponent innerhalb der GUI. Dem Edit ist es somit egal, ob es an die Datenschicht gebunden ist oder an das Formularcaption.

Im Grunde ist es ähnlich wie ein DBEdit an ein Tabellenfeld zu binden - nur eben viel flexibler.

Die GUI-Schicht selbst kennt dabei weder die Datenschicht noch umgekehrt.


2) GUI-Logik

Die GUI darf und muss natürlich selbst auch Logik erhalten aber das sollte sich wirklich konkret NUR auf die sichtbaren Aspekte beziehen.
Ein MaskEdit ist ein schönes Beispiel. Es akzeptiert selbst schon nicht, wenn ungültige Zeichen z.B. für ein Datum eingegeben werden.
Man könnte ähnliche Prüfungen auch im Formular durchführen, solange man dafür keine Analysen in der Datenschicht benötigt.
Wenn ich z.B. die Kinder für Personen erfasse und die Geburtsdaten prüfe (dass die Kinder nicht vor den Eltern geboren sind usw.) dann muss solch eine Prüfung in der Datenschicht erfolgen. Diese könnte eine Schnittstelle TPerson.KinderSindValide unterstützen.
ButtonOk.Enabled könnte an Person("#Aktuell").KinderSindValide gebunden werden. Dann kann ich die Person nur speichern, wenn die Datenschicht das erlaubt, ohne dass die GUI wissen muss worum es geht.

Auf ungültige Zeichen prüfen kann man natürlich auch schon direkt in der GUI, wobei ich mich frage, ob das immer Vorteile bringt.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Datenbankanwendung und Klassen - sinnvoll?

  Alt 10. Jan 2014, 15:59
Wenn ich z.B. die Kinder für Personen erfasse und die Geburtsdaten prüfe (dass die Kinder nicht vor den Eltern geboren sind usw.) dann muss solch eine Prüfung in der Datenschicht erfolgen. Diese könnte eine Schnittstelle TPerson.KinderSindValide unterstützen.
Interessantes Beispiel.
Wie ist der Ablauf?
  • Abruf des Elterndatensatzes
  • Zuweisung der Info "hatKind(er)"
  • Erfassung der Kinderinformation u.u. mit angepasster Oberfläche

oder vllt. so
  • Erfassung der Personendaten
  • Suche der Eltern
  • Zuweisung der Info "ist Kind"+ID_Eltern)

Wobei meiner Meinung nach die erste Möglichkeit Benutzerorientiert und die zweite Datenbankorientiert ist. Optimal wäre es den Ersten Ablauf zu zeigen und den zweiten in der "Datenwirklichkeit" zu tun.
Und so etwas kannst Du nur erreichen wenn das UI nicht mit der Datenschicht fix verdrahtet ist.

Zitat:
Auf ungültige Zeichen prüfen kann man natürlich auch schon direkt in der GUI, wobei ich mich frage, ob das immer Vorteile bringt
Wie üblich, es kommt darauf an, ist ja hier oft genug diskutiert worden (copy und paste ....)

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.352 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Datenbankanwendung und Klassen - sinnvoll?

  Alt 10. Jan 2014, 16:49
Welcher Weg für das Eltern-Kinder-Beispiel der beste ist muss man im Projektkontext sehen.

Wenn Eltern und Kinder von der selben Klasse TPerson sind ist das schon etwas anderes als wenn man einer Person eine Liste von Autos zuordnet.

Das ist der Knackpunkt:
Zitat:
Und so etwas kannst Du nur erreichen wenn das UI nicht mit der Datenschicht fix verdrahtet ist.
Unter dieser Voraussetzung hat man im Grunde alle Freiheiten.

In der Datenschicht kann ich meine Personen definieren, die eine Liste von anderen Personen erhalten kann (die Kinder) und eine Liste von Autos.

Optimal wäre es, wenn ich für jede Klasse ein "Bearbeitungsfoirmular zuweise", das projektweit gilt. Wenn ich irgendwo eine Person sehe kann ich das zugewiesene Bearbeitungsformular TFormPerson durch Doppelklick erzeugen und öffnen. Ebenso ein Formular für Auto-Objekte.

Die GUI-Controls werden automatisch an die passenden Objekteigenschaften gebunden, ohne dass man dazu etwas programmieren muss.

Der OKButton.Enabled wird an das FormarObjekt.IsValide im Personenformular oder FormularObjekt.IsValide im Autoformular gebunden. "FormularObjekt" ist das Objekt, für das das Formular geöffnet wurde. Das alles kann ohne Quelltext realisiert werden.

Ob man nun die Kinder in einer Tabelle erfasst oder in einer Listbox sammelt und jeweils wieder über ein eigenes Formular bearbeiten lässt, ist dann eigentlich zweitrangig.


Ein Problem, das ich in meinem Framework auch noch nicht bearbeitet habe ist das Verwerfen von Änderungen.
Wenn ich z.B. ein Kind hinzufüge muss das Kind-Objekt in der Datenschicht erzeugt werden. Wenn ich das Bearbeitungsformular aber schließen und das Kind verwefen will oder muss, muss das Objekt aus der Datenschicht auch wieder entfernt werden.
Gleiches gilt, wenn ich den Namen einer Person ändere und die Änderung wieder verwerfen will (ESC). Es muss dafür so eine Art Transaktion geben, die es ermöglicht, Objekte und Objekteigenschaften vorläufig zu ändern und später die Änderung fest zu machen oder zu verwerfen.

Diese Transaktionsverwaltung sollte nicht einer Datenbank überlassen werden da (zumindest in meinem Framework) die Objekte ja auch ohne Datenbankanbindung erzeugt und persistiert werden können.


Den beste Lösung für das Eltern-Kind-Beispiel müsste man sich noch überlegen. Man sollte sich daran orientieren, was der Anwender am ehesten wünscht.
Egal, ob man die Kinder in einer Tabelle oder in einer Listbox erfassen lässt, die Objekteigenschaften und die Validitätsprüfungen wären jeweis die gleichen.
Im Falle eines Kinder-Bearbeitungsformulars würde der OK-Button im Fehlerfall deaktiviert und ich könnte das Kind nicht schließen, im Falle einer Kinder-Tabelle wäre der entsprechende Datensatz rot markiert und ich könnte meine Person nicht schließen.


Wichtig ist vor allem, dass man im Formular nichts prüft was die Daten betrifft. Solche Zugriffe sollten immer auf definierte Schnittstellen begrenzt und darüber hinaus abstrahiert werden.

Das Formuar sollte auch auf keinen Fall die Klassen TPerson und TAuto kennen. Damit wäre eine lose Bindung schon dahin.


Man könnte die Datenschicht eigentlich fast als Komponente betrachten.
Das Projekt nutzt z.B. eine TEdit anhand derer Schnittstellen, ohne sich über dessen Innenleben Gedanken zu machen.
Das Projekt setzt die Eigenschaft Text eines Edit und liest sie wieder aus. Es kann prüfen, ob das Edit sichtbar und aktiviert ist oder ob es den Fokus hat.
Genau so kann und sollte die Datenschicht betrachtet werden. Es gibt Schnittstellen, an die sich die GUI binden kann - alles andere ist Privatsache. Natürlich ist die Zugriffsmöglichkeit auf die einzelnen Detaildaten komplexer als auf einfache Propertys einer Komponente, weshalb ein Manager für die Vermittlung zwischen GUI und Datenschicht erforderlich ist. Der kennt einige Schnittstellen der GUI (und kann dort über Datenänderungen informieren) und kennt die Struktur der Datenschicht (und kann so die benötigten Objekte verwalten und heraus geben). Die Objekte selbst kennen auch wiederum den Manager und können dort z.B. den Besitzer eines bestimmten Autos erfragen - genau wie die GUI.


Seit der erweiterten RTTI von D2010 lassen sich solche Dinge wunderbar umsetzen (schaffe ich ja sogar ).
M.E. ist das ein völlig neues Arbeiten.


Früher gab es mal ECO und Bold wo m.E. ähnliches versucht wurde. Das wurde dann aber leider nicht richtig ausgebaut.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (10. Jan 2014 um 16:55 Uhr)
  Mit Zitat antworten Zitat
vagtler

Registriert seit: 9. Jul 2010
Ort: Köln
667 Beiträge
 
Delphi 2010 Professional
 
#7

AW: Datenbankanwendung und Klassen - sinnvoll?

  Alt 10. Jan 2014, 19:22
[...] Früher gab es mal ECO und Bold wo m.E. ähnliches versucht wurde. Das wurde dann aber leider nicht richtig ausgebaut.
Leicht OT: An ECO wird wohl noch immer mehr oder weniger aktiv gearbeitet: http://www.new.capableobjects.com/downloads/ - allerdings als reines .NET-Framework.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:21 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 by Thomas Breitkreuz