Zitat von
Optiplex:
Allerdings hätte ich mir gewünscht, dass ein paar Kommentare drinn sind, um sie besser zu verstehen.
Ich sitze in der Türkei bei 35°C am Meer und soll auch noch Kommentare schreiben?
Die Klasse TSubject definiert eine Struktur, die eine Nachricht 'Changed' an andere (per Subscribe angemeldete) Objekte zu verteilen.
Die Klasse TCallbackHelper dient nur dazu, eine Methodenzeiger in einer Liste zu verwalten. Ich hätte auch ein 'Array Of TObserverNotification' verwenden können, dann hätte ich mir diese Hilfsklasse sparen können. Aber ich mag dynamische Arrays (hier) nicht.
Gut gut, die
Unit 'Observer' hat uns also die Grundbausteine für das Pattern bereitgestellt. Wie gehen wir damit um?
Wir haben also unsere Daten-Klassen, die wir um jeweils ein 'Subject' erweitern und dieses Subjekt (Man könnte es auch 'Änderungsnachricht-Verteil-O-Mat' nennen, aber 'Subject' ist irgendwie kürzer. Gut, schwerer zu verstehen, aber kompakt. Geradlinig. Straff. Drahtig. Sch..Schön. Darauf kommt es an.
Äh.. *vomthemaabschweifweilbikinismitinhaltflanieren* Wo war ich? ach ja.
Also, wir erweitern unsere Datenklasse um so ein 'Subject', damit andere Programmteile, die von den Änderungen an dieser Datenklasse informiert werden müssen, dort anmelden können. Dazu implementieren sie so eine Methode vom Typ 'TObserverNotification' und melden sich eben dort an.
Ich habe in der Klasse 'TObserverableObject' die Grundfunktionalität bereitgestellt, die eine Datenklasse, die Änderungen weiterverbreiten kann, so benötigt. Wenn Du deine Datenklassen von diesem Objekt ableitest, haben deine Klassen bereits alles, was ein Observerpattern so braucht. Du musst es nur noch anwenden, d.h. die Visualisierungsklassen bzw. Formulare per Subscribe anmelden und fertig.
Jeder 'Setter' einer Eigenschaft muss zum Schluss nur die 'Changed'-Methode aufrufen (wenn die Property geändert wurde). Mit 'BeginUpdate' kann man die Benachrichtigung puffern, also mehrere Änderungen vornehmen, ohne das jedesmal alle Subscriber benachrichtigt werden. Das würde ja nerven. Wenn ich also viele Eigenschaften eines Objektes ändern will, rufe ich 'BeginUpdate' auf, ändere wie ein Weltmeister und schließe die Änderungen mit 'EndUpdate' ab.
Ich kann das auch sein lassen, dann werden aber bei *jeder* Änderung die Subscriber benachrichtigt.
Die Idee von Guido ist natürlich für einige Objekte vielleicht mit weniger Aufwand zu implementieren, aber wenn in deiner Anwendungen viele Objekte durch die Gegend fliegen, die alle irgendwie dargestellt werden, hättest Du bald Probleme mit den ganzen Messages.
Ich mach das ab und an genauso, wenn ich nur ein oder zwei Klassen habe, die visualisiert werden müssen, aber wenn es mehr werden
...
Das Observer-Pattern bietet dir hier eine orthogonale (also gleichförmige), robuste und einfache Möglichkeit an, dieses Chaos zu vermeiden. Bei der komplexen Softwareentwicklung kommt es
imho in erster Linie darauf an, robust, einfach, verständlich und damit wartbar und erweiterbar zu programmieren und nicht kurz und knapp (a.k.a 'Quick and Dirty').