Einzelnen Beitrag anzeigen

Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#5

Re: Auf Werte der 1. Form zurückgreifen

  Alt 24. Jul 2006, 14:43
Hi,
von dem Tipp mit dem gegenseitigen Einbinden der Units im Uses Teil (ist möglich, einmal unter interface, einmal unter implementation) würde ich dir stets abraten. Zwar wird dieser Weg in Delphi unterstützt, letztlich schaffst du damit aber einen Designfehler der es in sich hat.

Es gibt eigentlich sehr viele Möglichkeiten das zu machen, was du vorhast. Welcher Weg in deinem Fall der Beste ist, hängt aber davon ab was du machen möchtest.
Dein Form dient eigentlich nur einer Anzeige von Daten, wo diese herkommen sollte dem Form letztlich eigentlich immer egal sein. Den Daten ist es letzlichn wiederum egal, was mit ihnen gemacht wird.
Ein wenig anschaulicher wird das ganze anhand eines Beispiels. Nehmen wir mal eine einfache Excel/Calculator Tabelle. Sagen wir du hast 3 Tupel von X und Y Werten. Diese stehen in einer Tabelle:
[x] [y]
1 1
2 2
3 3

Das sind die eigentlichen Daten. Wie das als Tabelle aussieht, kannst du dir ja vorstellen. Jetzt kannst du aus den gleichen Daten auch ein Diagramm machen und du hättest eine Gerade mit der Steigung 1.
Diese beiden Ansichten (Tabelle und Diagramm) verändern die Daten nicht. Die Daten müssen auch diese Ansichten nicht kennen. Statt einem Linien-Diagramm kann ja jetzt auch noch ein Tortendiagramm hinzu kommen.
Auch davon bekommen die Daten nichts mit. Sie speichern nur Werte ab.

Das gleiche kannst du in deinem Programm machen. Du sagst du möchtest auf einen Wert von Form1 zugreifen. Die Frage ist also, muss dieser Wert wirklich im Form stehen? Du könntest auch eine Klasse Class1 schreiben, die all diese Werte speichert. Form1 und Form2 können dann auf Class1 zugreifen. Das klappt ohne Probleme.
Da Form1 und Form2 Class1 sehen, können sie hier leicht lesend und schreibend auf die Werte zugreifen (ähnlich dem Beispiel).

Jetzt kann es noch zu einer Änderung kommen. Für das Beispiel könnten wir sagen, jmd. ändert das erste Tupel in 1 2 um. Nun müssten sich die Tabelle und die Diagramm auch ändern. Immerhin sollen die ja diese Werte anzeigen. Das Problem ist, dass hier mehr als ein Objekt konsistent gehalten werden muss. Die Lösung des Problems besteht im Observer-Pattern.
Die Daten sind dabei das Beobachtete, die Diagramme die Beobachter. Werden die Daten verändert (gut, geschieht wohl in der Tabelle), so müssen alle Beobachter dies mitbekommen. Hierzu kennt das Beobachtete Objekt eine Möglichkeit Beobachter zu registrieren. Diese melden sich also beim Beobachteten Objekt an (abstrakt) und werden beim eintreffen eines Ereignisses benachrichtigt. Wichtig ist hier, dass die Registrierung abstrakt ist. Du kannst z.B. TNotifyEvents verwenden und diese in einer Liste speichern (nicht all zu OO, aber erstmal egal). Ein TNotifyEvent ist ja nur ein Methodenzeiger. Jede Form kann hier eigene Events dieses Typs haben. Im Form wird dann die Adresse der jeweiligen Funktion an das Beobachtete Objekt weitergegeben und dort gespeichert. Ändert sich das beobachtete Objekt, ruft es einfach alle TNotifyEvents in seiner Liste nacheinander auf.

Hoffe ist halbwegs klar. Klingt am Anfang sicherlich etwas kompliziert, aber ich hoffe du erkennst die Vorteile. Nochmal am Beispiel der Tabelle und der Diagramme. Sagen wir mal du erfindest jetzt ein völlig neues Diagramm, dass halt auch y über x aufträgt, aber halt anders als alle anderen. Das stellt hier kein Problem da. Die Daten müssen so dein Diagramm nicht kennen. Für sie registriert sich nur noch jmd, der gerne wüßte wenn sich Daten ändern und die Darstellung dieser Daten ist somit komplett austauschbar.

Gruß Der Unwissende

Wichtig ist, dass du Logik und Darstellung immer trennst. Mag an viele Stellen unnütz erscheinen, aber es ist einfach sauberer. Das ist auch schon die einfachste Trennung, die man vornehmen kann.
In deinem Fall sagst du, du möchtest auf den Wert von etwas in Form1 zurück greifen. Wenn es einen Zustand gibt, den Form1 anzeigt, hindert dich nichts daran, den in einer eigenen Klasse zu halten. Hast du eine dritte Unit, kann die ohne Probleme von beiden Forms gelesen werden (was einer der alternativen Wege darstellt).
Natürlich macht eine Anzeige immer dann Sinn, wenn sie auch den aktuellen Wert anzeigt. Hier hilft das Observer Pattern weiter.
  Mit Zitat antworten Zitat