Das Observer-Muster in Delphi erweitert das grundlegende Observer-Muster. Weitere Informationen zum Observer-Modus finden Sie unter [Gam+, Seiten 293..303]
Definieren Sie eine Eins-zu-Viele-Abhängigkeitsbeziehung zwischen Objekten. Wenn sich der Status eines Objekts ändert, werden alle davon abhängigen Objekte benachrichtigt und automatisch aktualisiert.
Die Aufteilung eines Systems in eine Reihe kooperierender Klassen hat bestimmte Nebenwirkungen: Die Konsistenz zwischen verwandten Objekten muss geschützt werden. Aus Gründen der Dimensionskonsistenz möchten wir Typen nicht eng koppeln, da dies ihre Wiederverwendbarkeit verringert. [Gam+,S.293].
Mit den Ereignissen von Delphi (tatsächlichen Methodenadressen) können Sie eine gute Struktur für die Behandlung dieser Probleme schaffen. Mit Ereignissen können Sie die Kopplung beseitigen und eine bessere Kopplung erreichen. Beispielsweise wird das Ereignis TButton.OnClick ausgelöst, um entsprechende Arbeiten abzuschließen. Die Klasse speichert jedoch keinen Verweis auf den Event-Handler. Im Beobachtermuster wird die Klasse, die das Ereignis auslöst, als Zielobjekt (Subjekt) bezeichnet, und die Klasse, die das Ereignis steuert, wird als Beobachter (Beobachter) bezeichnet.
Die Ereignisse in Delphi können die Kopplung von Klassen besser beseitigen. Wenn Sie mehrere Ereignisse steuern und auf den Beobachtermodus verweisen möchten, können Sie einen Eins-zu-Viele-Benachrichtigungsmechanismus einrichten. Ein Ziel kann eine beliebige Anzahl von Beobachtern haben. Alle Beobachter erhalten Benachrichtigungen, wenn sich der Zustand des Ziels ändert. Nachdem der Beobachter die Benachrichtigung erhalten hat, fragt er sofort das Zielobjekt ab, um die Synchronisierung mit dem Zielobjekt aufrechtzuerhalten.
Diese Interaktion wird auch Publish-Subscribe genannt und das Ziel ist der Herausgeber der Benachrichtigung. Es muss nicht wissen, wer seine Beobachter sind, wenn es eine Benachrichtigung entdeckt. Beliebig viele Beobachter können sich anmelden und Benachrichtigungen erhalten.
Diese Anwendung im Beobachtermodus bietet Ihnen die Vorteile des Delphi-Ereignismechanismus bei der Handhabung der Klassenkopplung. Eins-zu-viele-Strukturen registrieren Beobachter durch Registrieren und Abmelden. Der Eins-zu-Viele-Mechanismus wird tatsächlich auf der Basis von Iteratoren angewendet.
Angenommen, Sie haben eine Tsubject-Klasse, die sinnvolles Verhalten definiert. Schauen wir uns zunächst einen Democode des Beobachtermodus an:
Typ
TSubject = Klasse (TObject)
Privat
FObservers: TList;
öffentlich
procedure RegisterObserver(Observer: TSubjectObserver);
procedure UnregisterObserver(Observer: TSubjectObserver);
Ende;
TSubjectObserver = Klasse (TComponent)
Privat
FEnabled: Boolean;
veröffentlicht
Eigenschaft Aktiviert: Boolean read FEnabled write FEnabled; Standardwert True;
Ende;
Unter den oben genannten Schnittstellen:
? Ein Registrierungsmechanismus zur Registrierung von Beobachtern für Tsubject.
¨ FObservers: TList; speichert registrierte Beobachter.
¨ RegisterObserver(..) wird verwendet, um Beobachter zu registrieren und sie zu Fobservern hinzuzufügen.
¨ UnregisterObserver(..) wird verwendet, um die Registrierung des Beobachters aufzuheben und zugehörige Objekte von Fobservern zu entfernen.
„Der Beobachtermodus muss auch eine neue Klasse TsubjectObserver erstellen.“
¨ Diese Klasse ist der Nachkomme von Tcomponent.
¨ .Eine aktivierte Eigenschaft schaltet die Beobachtung ein oder aus. .
Die tatsächliche Anwendung des folgenden Beobachtermodus:
procedure TSubject.RegisterObserver(Observer: TSubjectObserver);
beginnen
wenn FObservers.IndexOf(Observer) = -1 dann
FObservers.Add(Observer);
Ende;
procedure TSubject.UnregisterObserver(Observer: TSubjectObserver);
beginnen
FObservers.Remove(Observer);
Ende;
Die Implementierung von Shangguan unterstützt den Registrierungsteil von Beobachtern. Wo ist der Eins-zu-Viele-Benachrichtigungsmechanismus? Für tatsächliche Eins-zu-Viele-Benachrichtigungsanwendungen können Sie eine Change-Methode für Tsubject definieren, um seine registrierten Beobachter zu benachrichtigen, und der Beobachter kann ein OnChange-Ereignisattribut definieren, um die Planung zu verwalten. Der Code lautet wie folgt:
Typ
TSubject = Klasse (TObject)
Privat
FObserver: TList;
geschützt
» procedure Change; {Rufen Sie diese Methode auf, um eine Benachrichtigung zu versenden}
öffentlich
procedure RegisterObserver(Observer: TSubjectObserver);
procedure UnregisterObserver(Observer: TSubjectObserver);
Ende;
TSubjectObserver = Klasse (TComponent)
Privat
FEnabled: Boolean;
» FOnChange: TNotifyEvent;
geschützt
» Verfahrensänderung;
veröffentlicht
Eigenschaft Aktiviert: Boolean read FEnabled write FEnabled;
» Eigenschaft OnChange: TNotifyEvent read FOnChange write FOnChange;
Ende;
Durchführung
procedureTSubject.Change;
var
» Obs: TSubjectObserver;
» I: Ganzzahl;
beginnen
» für I := 0 bis FObservers.Count - 1 do
" beginnen
» Obs := FObservers[I];
» wenn Obs.Enabled dann Obs.Change;
" Ende;
Ende;
procedure TSubject.RegisterObserver(Observer: TSubjectObserver);
beginnen
wenn FObservers.IndexOf(Observer) = -1 dann
FObservers.Add(Observer);
Ende;
procedure TSubject.UnregisterObserver(Observer: TSubjectObserver);
beginnen
FObservers.Remove(Observer);
Ende;
procedureTSubjectObserver.Change;
beginnen
» if Assigned(FOnChange) then FOnChange(Self);
Ende;
Im obigen Implementierungscode:
? Die Change-Methode von Tsubject durchläuft alle registrierten Beobachter und ruft die Change-Methode jedes Beobachters auf, eine Implementierung einer Eins-zu-Viele-Benachrichtigung.
? Die Enabled-Eigenschaft des Beobachters bestimmt, ob er Benachrichtigungen erhält oder erhält
? Das OnChange-Ereignis von TsubjectObserver übernimmt tatsächlich die Synchronisierung und andere Vorgänge.
Organisieren
//Viele Auszüge aus „Design Patterns“