Bei der Implementierung des Observer-Musters sind zwei Hauptansätze zu berücksichtigen: das Push-Modell und das Pull-Modell.
Im "Push" -Modell sendet das Subjekt (dh das Observable) dem Beobachter bei Benachrichtigung alle Daten, die es benötigt. Der Beobachter muss das Thema nicht nach Informationen abfragen. Im "Pull" -Modell benachrichtigt das Subjekt den Beobachter lediglich darüber, dass etwas passiert ist, und der Beobachter fragt das Subjekt anhand der Informationen ab, die es benötigt.
Lassen Sie uns die Vor- und Nachteile beider Ansätze diskutieren:
drücken
Der Hauptvorteil des "Push" -Modells ist die geringere Kopplung zwischen dem Beobachter und dem Subjekt. Der Beobachter muss nichts über das Thema wissen, um es abzufragen. Wenn es nötig wäre, müssten wir eine der folgenden Aktionen ausführen: A - Downcasting auf der Seite des Beobachters durchführen, um klassenspezifische get
Methoden zu diesem Thema aufzurufen . Das ist schlecht. B- die Observable
Schnittstelle klassenspezifischer gestalten, spezifische get
Methoden anbieten , wodurch die Beziehung zwischen Beobachter und Subjekt weniger allgemein und die Dinge kopupelter werden.
Durch die Implementierung des Push-Modells vermeiden wir all dies.
Der Nachteil ist jedoch die geringere Flexibilität: Das Subjekt weiß möglicherweise nicht immer genau, welche Informationen die Beobachter benötigen, um sie an sie zu senden. Dies bedeutet häufig spezifischere Beobachter-Schnittstellen, z. B. solche AgeObserver
, die benachrichtigt werden, wenn das 'Alter' des Betreffs geändert wird, und HeightObserver
die height
bei Benachrichtigung den aktuellen Betreff des Betreffs erhalten.
Dies ist eine Option. Das andere ist das Subjekt, das eine ganze Reihe von Informationen sendet, die in einem Info
Objekt eingekapselt sind, und von den Beobachtern von dort abfragen lässt. Aber auch hier können wir nicht sicher sein, ob wir die richtigen Informationen senden. Entweder dies oder die Beobachter müssen spezifischere Beobachterschnittstellen implementieren, wodurch die Kopplung auf der Beobachterseite verstärkt wird.
ziehen
Ich habe bereits die Nachteile des Pull-Modells festgestellt. Die Beobachter müssten Dinge über das Thema wissen, um die richtigen Informationen abzufragen, was A- zu Downcasting (hässlich) oder B- günstig zu spezifischeren Observable
Schnittstellen führt, die spezifischere Zugriffsmethoden bieten. Bietet zum Beispiel AgeObservable
eine getAge()
Methode an.
Der Vorteil davon ist mehr Flexibilität. Jeder Beobachter kann selbst entscheiden, was abgefragt werden soll, ohne sich darauf verlassen zu müssen, dass das Subjekt die richtigen Informationen sendet.
Sie sollten die Strategie wählen, die für das jeweilige Projekt, an dem Sie arbeiten, besser ist.
In Wirklichkeit haben Sie immer spezifische Observer
und Observable
Schnittstellen, so dass Sie ohnehin eine gewisse Kopplung zwischen den Seiten haben.
Wählen Sie also entweder "Ziehen" oder "Drücken", je nachdem, was am besten zu Ihnen passt.
Brauchen alle AgeObserver
nur age
das Thema? Implementieren Sie das Push-Modell. Weniger Kopplung und einfacher.
Benötigen alle HeightObserver
unterschiedliche Informationen zum Thema - auch bekannt als muss man das Alter abfragen und ein anderes Objekt muss zusätzlich zur Größe das Gewicht abfragen? Implementieren Sie das Pull-Modell. Dies würde Sie zwingen, Accessoren (Getter) zur Observable
Schnittstelle hinzuzufügen (entweder dies oder das eigentliche Objekt als Parameter in seinem expliziten Typ zu übergeben, aber wenn Sie dies über die Schnittstelle tun, können Sie den Beobachtern den Zugriff auf Dinge verweigern, die nicht wichtig sind Sie). Diese Lösung erzeugt eine höhere Kopplung, ist jedoch flexibler.
Wählen Sie, was am besten zu Ihrer Situation passt.
arg
ist ein Parameter oder eine Gruppe von Parametern als zusätzliche Option