AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Konzeptfrage: Interface oder Messages
Thema durchsuchen
Ansicht
Themen-Optionen

Konzeptfrage: Interface oder Messages

Ein Thema von Ghostwalker · begonnen am 9. Nov 2016 · letzter Beitrag vom 10. Nov 2016
Antwort Antwort
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#1

AW: Konzeptfrage: Interface oder Messages

  Alt 10. Nov 2016, 09:03
Ich verwirre Dich wohl mehr als geplant.

Ich war zuletzt davon ausgegangen, dass Du dem Formular alle Daten in Form von Objekten bzw. Objektlisten bereitstellt.
Wenn das Formular zur Anzeige der Daten nochmal auf die Datenbank zugreifen muss, sieht das natürlich noch etwas anders aus.
Dann kannst Du keine Objekte zur Benutzung übergeben sondern tatsächlich die Datensatz-Ids.

Grundsätzlich haust Du m.E. die Datenschicht und die Formularschicht zu sehr durcheinander.
Versuche doch mal, das noch konsequenter zu trennen. Dafür gibt es verschiedene Möglichkeiten. Am einfachsten, alles was die Datenmanipulation betrifft in eine eigene Unit auslagern.

Dann könntest Du theoretisch alle Änderungen ohne ein Formular durchführen. Z.B. in einer Methode oder über ein Script.
Dann hast Du eine Datenschicht (und Businesslogik), die für sich funktioniert.

Jetzt muss das Formular sich nur noch an diese Unit wenden und sagen, was es gerade braucht.
Dann kannst Du eine PKW-Liste in Form von kompletten Objekten oder als DataSet übergeben.
Auch kannst Du durch Aufruf bestimmter Methoden Änderungen in der Datenschicht veranlassen.
Ähm...die Trennung ist schon da

Die Listview wendet sich an das Listen-Daten-Objekt um Daten für die Anzeige zu bekomen. Genauso wie sich die Detailview sich an ihr Datensatz-Daten-Objekt wendet um Daten zu bekommen bzw Daten zu
manipulieren (vgl. Schaubild).

1. Kommunikations-Weg ohne Observer bei Änderung eines Datensatzes durch Detailview

User änder Daten in Detailview -> Detailview schickt die Daten an Datensatz-Daten-Objekt(DDO) ->
DDO ändert die Datenbank -> Detailview schickt nachricht an Listview -> Listview fragt Listen-Daten-Objekt (LDO) nach frischen Daten -> LDO aktuallisiert seine Daten von der DB ->Listview zeichnet sich neu.

2. Kommunikations-Weg mit Observer (so wie ich dich Verstanden hab):

a)Registrierung

LDO registriert sich bei DDO als Listener, die Listview registriert sich als Listener bei der LDO
(Den Rückweg lass ich mal der einfachheithalber außer Acht)

b) Der Weg

Wie unter 1. ändert der User die Detailview -> diese sagt dem DDO, das es die Daten ändern soll ->
DDO änder die Daten in der DB -> DDO schickt Nachrichten an seine Listener ->LDO bekommt nachricht und aktuallisiert seine Daten aus der DB->Benachrichtigt seine Listener, das es sich geändert hat->Listview zeichnet sich neu

Der Unterschied zwischen 1 und 2 ist also, das nicht die UI untereinander kommuniziert (wie bei 1), sonder die Datenobjekte untereinander (was nach etwas Überlegung auch mehr Sinn ergibt).
Angehängte Grafiken
Dateityp: jpg Aufbau.jpg (31,4 KB, 14x aufgerufen)
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

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

AW: Konzeptfrage: Interface oder Messages

  Alt 10. Nov 2016, 10:07
Ja genau.

So wird das übersichtlicher.

Die Listbox interessiert sich, wenn sich etwas an der Datenliste ändert.
Also muss sie eine Info aus der Datenschicht bekommen: "Datenliste geändert".

Die DetailView interessiert sich für ein Datenobjekt und muss dazu eine Änderungsmeldung erhalten.
Aber die Listbox muss zusätzlich ihre DetailView kennen um sie zu beauftragen, jetzt ein anderes Datenobjekt anzuzeigen. Wenn jede Listbox genau eine DetailView hat, kann sie direkt die Instanz der View kennen. Ansonsten kann sie mehrere Views in einer Liste verwalten und nacheinander ansprechen oder sie kann einen Rundruf in die Welt senden und alle Views entscheiden selbst, ob sie darauf reagieren.
Diese Nachricht einer Listbox an ihre DetailView(s) ist aber m.E. die einzige notwendige Kommunikation zwischen den Controls.
Alles andere sollte über die Datenschicht kommuniziert werden.

Dazu kann wiederum jedes Datenobjekt alle seine zuständigen Controls kennen und denen eine Änderungsnachricht schicken (Observer) oder die Datenschicht setzt ein Flag DataIsInvalidate und das Formular prüft zyklisch (in einem Timer oder in OnIdle), ob das gesetzt ist und veranlasst seine Controls, sich neu zu zeichnen.
Beides hat Vor- und Nachteile.

Jedenfalls sollte aus der DetailView heraus nach eine Datenänderung nicht noch eine Listbox oder ein anderes Control über die Änderung informiert werden müssen.
Sonst wird vielleicht irgendwann einmal durch einen Job eine automatische Änderung der Daten durchgeführt und Du weißt gar nicht, welche Controls diese Daten anzeigen und welche Du jetzt eigentlich informieren musst weil die Änderung ja jetzt nicht in einer View veranlasst wurde.

In Deiner Skizze hast Du jetzt quasi schon einen ORM dargestellt.
Alle Zugriffe der Controls werden über Datenobjekte gemappt. Vorher hattest Du mal erwähnt, dass die Objekte nicht alle Datenbestandteile beinhalten und die GUI deswegen noch Daten aus der Datenbank holen müssen.
In dem Fall wäre Deine Skizze so noch nicht korrekt.

Also Du musst Dir überlegen, ob sämtliche Zugriffe auf die Daten über Objekte erfolgen sollen oder ob sich das Formular auch noch Daten aus der Datenbank holen muss.
Davon ist dann auch nochmal abhängig, wie man das Projekt organisiert.

Wenn Du nicht alles vollständig über Daten-Objekte handelst kann man sich auch überlegen, auf Objekte und Interfaces zu verzichten und die Datenzugriffe über Querys auf die DB zu organisieren.


Wichtigstes Fazit aus meiner Sicht: Kommunikation zwischen Controls nur, soweit sie sich auf die GUI-Logik bezieht (abhängige Controls bei einem Datensatzwechsel informieren).
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (10. Nov 2016 um 10:36 Uhr)
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Konzeptfrage: Interface oder Messages

  Alt 10. Nov 2016, 13:35


Vorher hattest Du mal erwähnt, dass die Objekte nicht alle Datenbestandteile beinhalten und die GUI deswegen noch Daten aus der Datenbank holen müssen.
DAS war das Missverständnis

Was ich meinte war eigentlich nur das in der LDO (und damit auch im Listview) nur die
Daten vorgehalten werden, die zur Anzeige notwendig sind (also z.B. ID und Marke vom PKW),
dafür aber mehrer Sätze, wärend im DDO (und damit in der Detailview) nur ein satz vorgehalten
wird (der der zur Anzeige/Änderung notwendige), dafür aber mit allen feldern des DS (also id,marke,farbe,leistung usw...eines PKW)

Im Moment spiel ich grad ein bischen mit dem Observer-Pattern rum und versucht mich in einem Testprojekt damit. Leider gelingt mir grad die Abstraktion nicht so ganz (in den Basis-Klassen kenn ich ja die konkreten Daten, die bei einer Notification übergeben werden noch garnicht).
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

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

AW: Konzeptfrage: Interface oder Messages

  Alt 10. Nov 2016, 14:04
Nochmal zwei Anmerkungen:

Wenn Du eine PKW-Liste hast:

Zitat:
PKWListe1
PKW1
PKW2
...
PKW10
dann kann Dein Listview ja auf die kompletten PKWs zugreifen und von mir aus in den Items nur das Kennzeichen und die Farbe darstellen.
Dass im PKW-Objekt noch mehr Daten drin stehen ist ja egal.
Du brauchst jedenfalls kein zweites Datenobjekt PkwReduziertFürListendarstellung.

Und wenn jetzt jeder Listeneintrag einen PKW repräsentiert kannst Du bei der Selektierung eines Eintrages einfach das PKW-Objekt an die bekanntgegebene View weiter geben. Das wäre das Einfachste.

Falls die ListenItems auch selbständige Controls sind (quasi viele Panels untereinander in einer Scrollbox) könntest Du jedes Item auch wieder an das PKW-Objekt binden, welches dann wie die Detail-View arbeitet, nur dass es weniger Informationen darstellt und sich in einer Scrollbox befindet, die die PKW-Liste repräsentiert.

Das ListboxItem wäre dann ebenso ein Beobachter des PKW wie das DetailView.
Bei Änderungsmeldungen zeichnen sich beide neu (mit etwas unterschiedlichem Umfang und Style), wobei es dann keine Rolle spielt, in welchem Umfeld sich die Controls befinden.


Die Beobachterliste kann man denkbar einfach realisieren.

Im Datenobjekt einfach:

Delphi-Quellcode:
TPKWData = class...
  fObserverList: TList;
  procedure RegisterObserver(aObserver: TObject);
  procedure UnregisterObserver(aObserver: TObject);
  procedure ObserverInfo;

...

procedure TPKWData.ObserverInfo;
begin
  for I := 0 to fObserverList.Count - 1 do
  begin
    O := TObject(fObserverList[I]);
    if (O is TMyListBox) then
      (O as TMyListBox).RefreshData;
    if (O is TMyListBoxItem) then
      (O as TMyListBoxItem).RefreshData;
    if (O is TMyDetailView) then
      (O as TMyDetailView).RefreshData;
  end;
end;
Wenn man mit Interfaces arbeitet kann man sich das casten an der Stelle ersparen aber wenn man nur wenige Klassen an Beobachtern hat bleibt es auch so ganz übersichtlich. Interfaces bringen ja auch einen Aufwand mit sich.

Wichtig ist natürlich, dass die Beobachtercontrols irgendwie über die Änderungen informiert werden können. Evtl. könnte auch ein Refresh reichen oder man spendiert wie oben eine eigene Methode oder man reagiert auf Messages oder was auch immer.

Wichtig ist m.E. dass die Kommunikation zwischen den Controls möglichst vermieden wird.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (10. Nov 2016 um 14:30 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 18:29 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