AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi OOP, Objekte neu laden, Komponenten aktualisieren
Thema durchsuchen
Ansicht
Themen-Optionen

OOP, Objekte neu laden, Komponenten aktualisieren

Ein Thema von TheMiller · begonnen am 12. Apr 2012 · letzter Beitrag vom 13. Apr 2012
Antwort Antwort
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#1

AW: OOP, Objekte neu laden, Komponenten aktualisieren

  Alt 12. Apr 2012, 15:55
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.
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  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: OOP, Objekte neu laden, Komponenten aktualisieren

  Alt 12. Apr 2012, 16:18
@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...
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (12. Apr 2012 um 16:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#3

AW: OOP, Objekte neu laden, Komponenten aktualisieren

  Alt 12. Apr 2012, 20:51
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
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.656 Beiträge
 
Delphi 12 Athens
 
#4

AW: OOP, Objekte neu laden, Komponenten aktualisieren

  Alt 13. Apr 2012, 07:04
Für mich klingt das alles nach Observer-Pattern.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

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

AW: OOP, Objekte neu laden, Komponenten aktualisieren

  Alt 13. Apr 2012, 12:50
Kann aber auch vielleicht nur Einbildung sein, weil ich gerade nur die Hälfte verstanden habe
Ok, ich versuche es nochmal, wobei ich Dich auch nur halb verstehe.

Du musst unterscheiden, ob Dein Auto aufgelöst, durch ein neues ersetzt oder nur seine Farbe geändert wird.

Wenn ein Control (z.B. ein TPanelAuto) das Kennzeichen Deines Autos und dessen Farbe darstellen soll, würdest Du ihm dafür eine Autoinstanz (Autoobjekt "DataAuto" mit Kennzeichen und Farbwert) zuweisen. Wenn sich das TPanelAuto zeichnet (wann immer das auch ist), liest es aus dem Autoobjekt die benötigten Daten.

Das PanelAuto benutzt dafür die zugewiesene Speicheradresse. Wenn das Autoobjekt inzwischen aufgelöst wurde, bekommt PanelAuto das erst mal nicht mit. Es kann nicht einmal erkennen, ob das "DataAuto" überhaupt noch gültig ist.

Um das zu verwalten könnte man jedes erzeugte DataAuto-Objekt in eine Liste schreiben und beim Zerstören daraus entfernen. PanelAuto könnte nun nachschauen, od sein DataAuto noch in der Gültigkeitsliste enthalten ist.
Wenn nicht, wird der Pointer gleich genilt und ein leeres Panel gezeichnet.

Alternativ kann man Observer-Patterns nutzen. Das PanelAuto meldet sich beim DataAuto an (wird in einer internen Liste von DataAuto eingetragen). Wenn DataAuto aufgelöst wird, informiert es alle registrierten Objekte aus seiner internen Liste über sein Ende. PanelAuto würde dann erfahren, dass sein DataAuto nicht mehr existiert und den Pointer nilen (worauf hin es sich auch neu zeichnet und zwar "leer"). (PanelAuto muss sich natürlich auch wieder bei DataAuto abmelden, falls es früher aufgelöst oder ihm ein anderes DataAuto zugewiesen wird.)

Wird DataAuto nicht aufgelöst, sondern erhält nur eine andere Farbe, müsste eine entsprechende Nachricht verschickt werden, damit sich PanelAuto neu zeichnet.
Das kann ebenfalls über Observer realsiert werden oder einfacher (so habe ich das bisher gelöst) durch ein Invalidate aller erzeugten PanelAuto´s. Die zeichnen sich entsorechend dann neu, sofern sie sich in einem sichtbaren Bereich befinden. Hunderte PanelAuto´s auf geschlossenen Formularen werden natürlich nicht gezeichnet und bremsen das System somit auch nicht aus.

Wird dem PanelAuto ein anderes DataAuto zugewiesen, wird intern ebenfalls Invalidate aufgerufen und das PanelAuto zeichnet sich neu.


So funktioniert das im Grunde sehr gut (siehe mein Turnierprojekt).


Allerdings ist es so nicht möglich, die Daten in einem C/S-Projekt zu nutzen. Der Client kommt ja nicht ohne Weiteres an die Objekte.

Daher würde ich künftig lieber den TPanelAuto nicht ein TDataAuto zuweisen sondern eher eine AutoId. Dann kann es sich von einer zentralen Stelle über GetDataAuto(AutoId) ein DataAuto-Objekt (oder eine Schnittstelle) abrufen, damit arbeiten und dieses wieder verwerfen.
Wird eine ungültige AutoId übergeben, kommt einfach nil zurück und Zugriffe auf ungültige Objekte sind ausgeschlossen. Auch den Observerkram kann man sich (für diesen Bereich) sparen.

Wenn die zentrale Stelle in einem Server liegt, können sich mehrere Clients daraus bedienen (also die gleichen Autos anzeigen).
Die Clients vom Server aus über Änderungen zu informieren sollte nicht weiter schwierig sein. Schwieriger wird es wohl, vom Client Änderungen zum Server zu schicken (z.B. wenn ein Auto gelöscht, hinzugefügt oder verschoben wird) und Zugriffskonflikte zu verhindern.

Auf jeden Fall wird sich eine gute Modularisierung sehr bezahlt machen, da das Projekt dadurch besser wartbar sein wird. Mehr Tipparbeit (z.B. wegen der Objekte-Zentrale oder zu definierenden Schnittstellen) würde ich heute dafür hinnehmen.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (13. Apr 2012 um 13:18 Uhr)
  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 16:50 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-2025 by Thomas Breitkreuz