Einzelnen Beitrag anzeigen

Benutzerbild von stahli
stahli

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

AW: Databinding - Grundsatzdiskussion

  Alt 7. Jan 2013, 23:44
vorab @Stevie:
Der VTV ist mir irgendwie suspekt. Ich tendiere auch (derzeit noch) mehr zu FMX und dessen Gittern bzw. nur ListBoxen.
Deine Beispiele mit DSharp sagen mir auch nicht so richtig zu und es gab viele Fehlermeldungen unter XE3 (habe alle mal angetestet).
Mein Ansatz bzw. Wunsch wäre eine etwas andere Funktionsweise - daher ...


Noch ein paar Überlegungen zu DataBindings:


Wozu will man Datenbindungen haben?

Ich sehe zwei Gründe:

1) Ich möchte den Datentransfer mit möglichst wenig Quelltext abwickeln. Zum einen wegen Schreibfaulheit und zum anderen wegen einer übersichtlicheren Formularunit. Bestenfalls kann man die Beziehungen zur Designtime und vielleicht sogar graphisch herstellen.

2) Man kann wegen der Verwendung der PropertyNames Zuweisungen zur Laufzeit durchführen. Durch Einbeziehung der RTTI werden die Verbindungen dann zur Laufzeit quasi "interpretiert".

Diese "Interpretation" kostet jedoch ganz schön viel Zeit, so dass dieser Weg für sehr häufige Aktionen (große Datenmengen in Gitter) nicht wirklich sinnvoll ist.

Zudem werden im Hintergrund recht aufwendige und komplexe Funktionen durchgeführt, die eine gewisse Gefahr für die Stabilität eines Projektes darstellen können.

Offenbar wird in den LiveBindings auch nicht vernünftig geprüft, ob verbundene Objekte aktuell noch existieren. Löschen von Controls im Designer führen regelmäßig zu Zugriffsverletzungen.


Alternativen

Die Alternative wären Experten, die nach gewissen Vorgaben "einfachen" Quelltext für mich erzeugen, der dann (z.B. per include) in mein Projekt eingebunden und ganz normal kompiliert wird (ähnlich dem XML-Experten, DataSnap, TMS-DataModeler etc.).
Z.B. könnte so eine Bindung an ein Gitter realisiert werden, das zur Designtime in einem Designer konfiguriert wird (Spaltentypen, Darstellung, gebundene Felder usw.), der dann eine entsprechende Unit erstellt die dann im Projekt genutzt wird. Die Unit könnte dann bei Konfigurationsänderungen überschrieben werden. Man dürfte dann nur nichts händisch darin ändern oder müsste diese handischen Änderungen bei späteren Änderungen durch den Experten wieder neu berücksichtigen.

Das Anliegen, weniger Quelltext schreiben zu wollen, hätte man so auch erfüllt. Es würde relativ einfacher Quelltext vorliegen, der komplett compiliert würde, schnell wäre und im Handling keine Probleme machen würde.

Allerdings könnte man keine Testdaten zur Designtime binden, da der Datentransfer ja vom Hautprogramm realisiert würde.


Komponente

Wenn man den vom Experten erzeugten Quelltext dazu nutzen würde, davon eine eigene Komponente zu erzeugen (z.B. TPersonGrid) könnte das Grid auch zur Designtime dargestellt werden wenn bereits zur Designtime eine Datenmenge zugewiesen wird - wobei man davon nicht sehr viele Vorteile hätte.


Pro und Contra

Um die GUI-Controls untereinander zu verdrahten, wirkt ein Databinding im ersten Moment interessant. Allerdings spart das nicht wirklich viel Arbeit. Wenn ich in einem CheckBox-Click Edit1 und Edit2 auf Enable setze, brauche ich 2 Zeilen Quelltext. Im Fall eines Databindings muss ich 2 Controls bzw. Verbindungen einrichten (Bestenfalls graphisch).
Allerdings scheint in der Delphi-IDE aktuell kein DataBinding wirklich fehlerfrei zu funktionieren.

Einen wirklichen Nutzen sehe ich im Moment auch nicht darin, Datenmengen im ersten Schritt abzurufen, im zweiten Schritt eine Bindung an Controls zu veranlassen (mit Quelltext) und dann Daten wieder zu schreiben.

Sinnvoll wäre es, wenn die Controls „wüssten“, WAS sie darstellen sollen und sich das Framework um die Vermittlung kümmert.
Ein Edit soll z.B. die Eigenschaft „FirstName“ des Objektes „Person(1)“ bearbeiten. Das ist eine sinnvolle Definition. Nun muss das Edit bei einen zentralen Manager anfragen und die Person mit der Id 1 abrufen. Dann schaut es nach, ob die Person eine Eigenschaft „FirstName“ hat und bindet sich daran. Fertig. Das macht schon Sinn.
Weise ich
* einer ListBox -> „“PersonList“ + „FirstName“ oder
* einem Grid -> „PersonList“ + „FirstName, LastName, Birthday“ (so in´s unreine)
zu, dann müssen die Controls die Liste ebenfalls von einem Manager abrufen (wobei die Zeilendaten erst bereitgestellt werden sollten, wenn die jeweilige Zeile dargestellt wird).
Wo der Manager die Daten her bekommt (ob von einem Server, einem DataSet, einer Objektliste oder was auch immer) wäre dann egal.


Voraussetzung

Voraussetzung ist, dass die Controls auf die Zusammenarbeit mit dem Framework (Manager) abgestimmt werden. Entsprechend muss auch die Datenschicht den Manager kennen und ihn mindestens über Änderungen informieren.


Machbarkeit

Eine Realisierung bis hierher halte ich ohne große Schwierigkeiten für realisierbar. Unter der VCL habe ich mit meinen „odControls“ in der Weise bereits meine „Turniersoftware“ realisert.
Die Datenschicht ist über Objekte realisiert und die GUI wird in der beschriebenen Weise an die Datenschicht gebunden.
In der damaligen Version mussten die Objekte jedoch in der Hauptanwendung vorliegen. Es war nicht möglich, die Daten aus einer Datenbank oder von einem Server abzurufen.
Daher habe ich inzwischen bereits Ansätze einer Client/Server-Version angetestet.


Problem

Das größte Problem, welches ich derzeit sehe ist die Frage der Validierung.
Wenn Änderungen nicht sofort in der Datenschicht gespeichert werden sollen, muss deren Gültigkeit geprüft werden. Das kann sehr einfach erfolgen (z.B. ob ein Text kein ‚%‘ enthält) oder sehr komplex (ob einer einzutragende Person noch nicht im System mit 1MIo Datensätzen existiert).
Die erste Prüfung kann ggf. ein Edit selbst vornehmen, die zweite Prüfung müsste in der Datenschicht veranlasst werden.
In jedem Fall müssten die Controls aber die „fehlerhaften Daten“ erst mal anzeigen während sie im Formular eingegeben werden. Es darf also in dem Fall keine strikte Bindung in die Datenschicht erfolgen da ja sonst dort die falschen Daten gespeichert würden oder die GUI-Controls die Originaldaten aus der Datenschicht anzeigen würden (die Falscheingabe würde sofort überschrieben).
Also müsste ein temporärer Datenbestand (z.B. ein TPerson) erzeugt werden, das der aktuellen Datenbearbeitung dient.
Nach der Validierung können die Daten dann an die Datenschicht übertragen oder verworfen werden.
Im Firemonkey kann man auf Fehler schön hinweisen, indem die Controls rot umrahmt werden.

Das Handling einer solchen Validierung ist m.E. das größte (eigentlich einzige) Problem eines entsprechenden Frameworks.


Fazit

Die Controls sollten (ähnlich den früheren DB-Control) spezialisierte Controls sein, die zu einem DataBinding-Framework passen.
Die Controls sollten sich „gezielt“ Daten von einem Manager abrufen und ggf. untergeordnete Controls dynamisch erzeugen und binden.
Eine Bindung von GUI-Controls untereinander darf als Nebenprodukt möglich sein, aber als Ziel darf das keine Rolle spielen.
Die Controls sollten also nicht passiv auf das warten, was da kommt, sondern sich aktiv (über einen Manager“ ihre Daten abrufen.

Im Kern wird bei dem Konzept die RTTI für reine Datenübertragung genauso genutzt wie bei den LiveBindings, aber die Art der Datenbeschaffung unterscheidet sich.


Meinungen

?


PS: In folgendem Video habe ich noch ein paar Überlegungen dazu angestellt.
- Es ist zugegebener Maßen etwas wirr bzw. unstrukturiert, aber das Thema ist ja auch vielschichtig.
- Mit dem Video werde ich keine Preise gewinnen aber als Diskussionsgrundlage und zur Verdeutlichung meiner Vostellungen taugt es hoffentlich.
- Leider ist ist das Video deutlich länger geworden (45 min) als ursprünglich geplant.
- Ich zeige meine bisherigen Ansätze und erkläre auch (mit meinen Mitteln) wie ein DataBinding grundsätzlich funktioniert.
- Es wird hoffentlich deutlich, welchen anderen Ansatz ich von einem DataBinding erwarten würde.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat