Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi OOP, Objekte neu laden, Komponenten aktualisieren (https://www.delphipraxis.net/167684-oop-objekte-neu-laden-komponenten-aktualisieren.html)

TheMiller 12. Apr 2012 16:51

Delphi-Version: 2009

OOP, Objekte neu laden, Komponenten aktualisieren
 
Hallo,

ich weis, dass es ein richtig schlechter Titel ist, aber mir fällt keine prägnante Beschreibung ein.

Ich programmiere objektorientiert. Angenommen, ich habe das globale Objekt "TFahrzeuge", welches alle Fahrzeuge enthält. Diese Objekte werden auf 3 Forms benutzt zB in einer ListView, Combobox und TreeView.
Nun führt ein Benutzerverhalten (ändern/löschen etc.) dazu, dass die Liste komplett neu geladen wird, in meinem Fall aus der DB.
Das wiederrum führt dazu, dass ich als Programmierer sicherstellen muss, dass alle drei Komponenten gleichzeitig aktualisiert werden. Vergesse ich eine, tritt bei dieser eine AV auf, weil die Speicherbereiche sich geändert haben.

Jetzt könnte man sagen, dass man halt daran denken muss - aber wenn das Projekt wächst, dann wird's unübersichtlich.

Wie machen das andere / Wie löst ihr dieses Problem?

Ich dachte an eine Art "Listener". Jede Komponente, die die Aufgabe hat etwas mit Objekten zu tun, kann sich "registrieren". Wird jetzt das Objekt "TFahrzeuge" geändert - also neu geladen, wird allen Objekten bescheid gegeben und alle Objekte aktualisieren sich. Problem ist aber, dass - je nach Programmgröße und Anzahl der registrierten Objekte - dies unnötig lange dauern kann.

Eine andere Idee wäre es, die Komponenten immer im OnActivate einer Form zu aktualisieren. Aber das könnte den Programmablauf verzögern und das Programm würde immer kurz hängen, wenn man die Forms wechselt.

Ich hoffe, ihr versteht was ich meine und könnt mir ein paar Tipps geben.

Danke im Voraus!

s.h.a.r.k 12. Apr 2012 16:55

AW: OOP, Objekte neu laden, Komponenten aktualisieren
 
Ich handhabe es so, dass die Modelle nach außen hin ein OnChange-Event anbieten. Natürlich musste ich das selbst programmieren, da Delphi von Haus aus nur einen "Listener" registrieren kann -> normale Events. Daher habe ich mir eine Basisklasse bzw. ein entsprechendes Interface geschrieben.

Ändert sich das Objekt bzw. eine Eigenschaft davon, dann propagiere ich das nach "außen" und informiere so die Listener, dass sich die Eigenschaft XYZ geändert hat. Was diese dann machen, ist dem Model selbst egal.

Bummi 12. Apr 2012 16:56

AW: OOP, Objekte neu laden, Komponenten aktualisieren
 
Wenn Du das ganze in Tabellen abfackelst, mit datensensitiven Controls bist Du schon fertig ....

s.h.a.r.k 12. Apr 2012 16:58

AW: OOP, Objekte neu laden, Komponenten aktualisieren
 
Zitat:

Zitat von Bummi (Beitrag 1161590)
Wenn Du das ganze in Tabellen abfackelst, mit datensensitiven Controls bist Du schon fertig ....

Stevie's DSharp schlägt ja auch in die selbe Kerbe.

Bummi 12. Apr 2012 17:00

AW: OOP, Objekte neu laden, Komponenten aktualisieren
 
@s.h.a.r.k

welche Kerbe, für oder gegen "Tabellen" ?

s.h.a.r.k 12. Apr 2012 17:07

AW: OOP, Objekte neu laden, Komponenten aktualisieren
 
Die datensensiblen Controls allgemein -- weder für Tabellen, noch gegen diese. Wobei ich behaupten würde, dass DSharp hier etwas flexibler ist, als wenn ich alles in Tabellen klatschen würde. So verliere ich ja auch gewisse Weise den Nutzen der Objekte, da ich dann ja "nur" Datasets habe. Bin jedenfalls selbst nie so richtig mit diesen Tabellen warm geworden. Bin dann doch ganz gerne der, der es zu Fuss macht, auch wenn es mehr Arbeit ist :stupid:

stahli 12. Apr 2012 17:18

AW: OOP, Objekte neu laden, Komponenten aktualisieren
 
@DJ-SPM

Du gehst genau in die gleiche Richtung, wie ich auch.
In Deinem letzten Thread hatte ich schon auf 2 Themen gelinkt, die auch mit in den Bereich fallen.

Bisher habe ich es so gelöst, dass ich Datenobjekte und eine Eigenschaft an ein sichtbares Control binde (odControls). Wenn das Control sich zeichnet liest es seinen darzustellenden Wert aus der Objekteigenschaft (z.B. Person.FirstName). Das funktioniert mit der erweiterten RTTI ab D2010 einfacher.
Das Framework kümmert sich auch darum, die sichtbaren Controls zu informieren, wenn ein gebundes Datenobjekt aufgelöst wird.
Die Formulare erhalten einen "odFormControler" (der wird einfach auf das Formular gesetzt), der die Verbindung der Datenschuicht und GUI übernimmt.
Insofern ist das alles soweit automatisiert. Man stellt einfach zur Designzeit die gewünschten Eigenschaften ein und das Framework erledigt den Rest.

Das funktioniert so aber nur, wenn alle (Daten-)Objekte die ganze Zeit im Hauptspeicher gehalten werden. Auch müssen sich die Datenklassen untereinander zum großen Teil kennen, und davon will ich künftig gern weg kommen.

Daher plane ich für später eine Lösung in der Art:
- Controls wird eine Id zugewiesen
- die Controls fordern von einem Broker Schnittstellen ab (anhand der Id)
- der Broker erzeugt/verwaltet/zertstört die Objekte und gibt auf Anfrage Schnittstellen heraus
- dabei kann der Broker auf einen ORM zurück greifen - oder auch nicht
- bei Bedarf kann der Zugriff über C/S realisiert werden

Auf jeden Fall würde ich künftig Controls nicht mehr fest an Datenobjekte binden wollen. Besser (übersichtlicher) ist es wohl, nur Id´s zuzuweisen und die Objekte bei jedem Zugriff neu abzufragen. Der Broker wäre dann dafür zuständig, die Objekte in sinnvoller Form zu cachen.


Ich hatte schon länger mal geplant, bzw. mir gewünscht, dass die DP-Profis mal gemeinsam ein entsprechendes Demoprojekt aufbauen, damit man als Einsteiger mal einen Zugang dazu findet. Wer wäre dabei? Man könnte mal ein paar Kriterien zusammenstellen...

TheMiller 12. Apr 2012 21:51

AW: OOP, Objekte neu laden, Komponenten aktualisieren
 
Zitat:

Zitat von stahli (Beitrag 1161601)
Ich hatte schon länger mal geplant, bzw. mir gewünscht, dass die DP-Profis mal gemeinsam ein entsprechendes Demoprojekt aufbauen, damit man als Einsteiger mal einen Zugang dazu findet. Wer wäre dabei? Man könnte mal ein paar Kriterien zusammenstellen...

Ehm ja. Ich wäre eigentlich dabei - hab ja die Frage quasi mal wieder aufgegriffen / ins Rollen gebracht. Auch brauche ich selbst eine Lösung. Zwei Ansätze habe ich ja schon gebracht. Beim Drüberlesen über deinen Beitrag hören sich unsere Vorschläge ein wenig identisch an. Kann aber auch vielleicht nur Einbildung sein, weil ich gerade nur die Hälfte verstanden habe ;)

Meine Idee wäre folgende (unrein, ungetestet)

Objekte: TFahrzeuge, TAuto, TFahrrad, TPersonen, THalter, TFahrer
Komponenten: chkboxFahrzeugtyp, cbAutos, cbFahrraeder, cbHalter, cbFahrer
User-Möglichkeiten: Fahrzeug hinzufügen (LKW), Auto/Fahrrad hinzufügen, Personen (Vor/Nachname) hinzufügen
Objektverwaltung: TFahrzeug und TPersonen sind global und von TObjectList abgeleitet.

Problem: Wird ein neues Auto hinzugefügt, wird auch das globale Auto-Objekt neu geladen => neue Speicheradressen

Nun muss jede Komponente bescheid gesagt bekommen, dass deren Inhalt veraltet ist und sich eben verändert hat. Meine erste(!) Idee wäre nun diese, dass jede Komponente einem "Verwalter" (Broker) sagt: Ich möchte wissen, wenn sich was ändert. Dies könnte in einem Array gespeichert werden oder so. Bei einer Änderung beliefert der Verwalter die Komponenten, die für "TAuto" zuständig ist, mit allen neuen Daten.

Das hätte sogar den Vorteil, dass man das in eine Unit auslagern kann und demnach alle Ladevorgänge an einem Ort hat. Quasi eine weitere Ebene zwischen Objekten und GUI. Ich nehme dabei an, dass sowieso eine Unit nur für Objekte exisitert.

Ich hoffe, das war jetzt nicht zu umständlich?

Wobei ich auch sagen muss, dass diese Variante ziemliche Tipparbeit sein könnte. Aber das könnte man ja alles selbst in eine tolle Klasse verpacken, die Methoden wie "addListener(obj: TObject)" bereitstellt. So kann eine Komponente mit einem Objekt für den Listener "verlinkt" werden. Einmalig. Den Rest übernimmt die Klasse. Also nur einmal Tipparbeit und alle Projekte dürften davon profitieren (mit minimaler Anpassung). VSS: Das ausgedachte System würde funktionieren ;)

Grüße

DeddyH 13. Apr 2012 08:04

AW: OOP, Objekte neu laden, Komponenten aktualisieren
 
Für mich klingt das alles nach Observer-Pattern.

Stevie 13. Apr 2012 09:30

AW: OOP, Objekte neu laden, Komponenten aktualisieren
 
Zitat:

Zitat von s.h.a.r.k (Beitrag 1161593)
Zitat:

Zitat von Bummi (Beitrag 1161590)
Wenn Du das ganze in Tabellen abfackelst, mit datensensitiven Controls bist Du schon fertig ....

Stevie's DSharp schlägt ja auch in die selbe Kerbe.

Problem ist leider, dass ihm das mit Delphi 2009 nicht helfen wird :(
Ansonsten dürfte das beschriebene ohne Probleme möglich sein. Fahrzeugliste (welche in diesem Fall von IObservableCollection sein sollte) an die verschiedenen Controls binden, Properties des in der Liste angewählten Objekts an andere Controls binden, fertig ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:53 Uhr.
Seite 1 von 2  1 2   

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