Einzelnen Beitrag anzeigen

Der_Unwissende

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

Re: Frage zu einer Type-Deklaration in TThread-Unit

  Alt 6. Sep 2006, 15:36
Werde ich dir gerne erklären (ich hoffe dir machen längere Beiträge nichts aus).
An sich ist es die Idee so einfach. Du möchtest ein Ereignis haben. Dies kannst du z.B. mit einer solchen Implementierung (Methodenzeiger) erreichen. Dabei handelt es sich um einen so genannten Callback, da du eine übergebene Funktion aufrufst. Woher die Methode aber kommt, die da aufgerufen wird, dass weißt du / dein Thread gar nicht.
Die Frage ist nun also, sollte der das Wissen? Man versucht diese Frage immer mit nein zu beantworten. Das Prinzip dahinter nennt sich Abstraktion und bietet ein Menge vorteile. Da dein Thread keine Details des Besitzers dieser Callback-Methode hat, kann der Thread auch nicht auf solche zurückgreifen. Klingt noch nicht nach einem Vorteil? Ohne Detailkenntnis können keine Details beim Aufruf des Callbacks vorrausgesetzt werden, der Aufrufer ist also vollkommen austauschbar!
Irgendwie macht es aber keinen Sinn, wenn jmd. erfährt dass irgendein Ereignis eingetreten ist. Sagen wir du hast eine Klasse A, die die Callback-Methode für deinen Thread bereit stellt. Würde hier nur eine Methode aufgerufen werden (ohne Argumente), dann wüßte sie nur, irgendwo ist irgendwas passiert. Das hilft nicht weit. Überwacht sie nur den einen Thread, dann ist ihr sicherlich klar wer der Auslöser war. Der Thread könnte die Änderung ja auch intern speichern und als Property nach aussen führen, aber dann müsste A jetzt Detailwissen über die Properties haben und die neuen Werte abholen (bevor diese sich wieder ändern).
Dadurch, dass du diese als Argument übergibst und der Aufruf der Methode synchron erfolgt (es wird gewartet bis die Methode abgearbeitet ist), stellst du sicher, dass A (oder wer auch immer Besitzer des Callbacks ist) von jeder Änderung erfährt. Die Argumente sollten also immer die Information enthalten, was sich geändert hat (in diesem Fall durch aChangedFile gegeben).
Das mit dem Sender hat eigentlich die gleichen Gründe. Du möchtest alles so abstrakt wie möglich halten. Dass A eine Methode hat, die als Callback verwendet werden kann ist soweit klar. Aber wer sollte A daran hindern dies bei 2 oder mehr Threads zu tun? Sender teilt dann mit, wer das Ereignis ausgelöst hat, damit kannst du dann weiter arbeiten.
Ein etwas dummes Beispiel (da es leichter anders geht) wäre folgendes: Du baust dir eine Gruppe von Buttons, von denen nur einer gedrückt sein darf (also richtig runter). Natürlich würdest du normalerweise TSpeedButton einsetzen und den GroupIndex anpassen, aber die gibt es nicht und du entscheidest dich für Panel.
Ein Panel ist dabei der Träger der Buttons. Dieses Panel spielt keine Rolle, es gruppiert nur die anderen Panel, so dass du leichter über diese iterieren kannst. Wenn also von allen Paneln gesprochen wird, so meine ich alle Panel, die als Button auf diesem Gruppierungselement liegen.
Ja, wenn jetzt ein Panel gedrückt wird, dann muss es unten bleiben. Alle anderen Panel müssen hingegen rausgedrückt werden. Du siehst, dass dies eine sehr allgemeine Formulierung ist. Würdest du für jeden Druck auf ein Panel eine eigene Methode schreiben, könnte das etwas anstrengend (und Fehleranfällig bei Copy&Paste) werden. Viel schöner wäre es, wenn du eine Methode hast, die erstmal alle Panel rausdrückt und dann nur das angeklickte Panel runterdrückt. Mit Sender hast du genau die Möglichkeit. Hier steht dann halt drin, wer das Ereignis auslöste.
Sender wird allgemein immer als TObject übergeben, um auch hier keine Einschränkungen zu machen. Damit kann ein Sender ein vollkommen beliebiges Objekt sein. Wie und wo man das ausnutzt merkt man immer in der Praxis, weitere Beispiele meinerseits wären wohl so schlecht konstruiert wie das ebend.

Ich hoffe, dass dir damit soweit klar ist, warum man diese Argumente übergibt. Dein Empfänger kann so feststellen was passiert ist (Art des Ereignis + Parameter) und wer das Ereignis auslöste.

Trotz alle dem ist es nicht gerade die schönste Lösung. Es gibt im Moment mind. zwei Beiträge, die näher auf das Thema Observer-Pattern eingehen. Ich rate jedem dazu, diesem den Vorzug vor Methodenzeigern zu geben. An sich ist es kein direkter Ausschluss, auch das Observer-Pattern kann mit Methodenzeigern verwendet werden. Genaueres findest du in den Beiträgen.
Die eigentliche Idee beim Observer ist eigentlich nur, dass sich interessenten An- und Abmelden können. Während du mit einem Methodenzeiger häufig nur einem Objekt ermöglichst über ein Ereignis informiert zu werden, ermöglicht ein Observable es mehrere (oder auch keine) Observer zu informieren.
  Mit Zitat antworten Zitat