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.