In .NET gibt es IObservable- und IObserver- Schnittstellen (auch hier und hier ). Interessanterweise enthält die konkrete Implementierung des IObservers keinen direkten Verweis auf das IObservable. Es weiß nicht, wen es abonniert hat. Es kann nur den Abmelder aufrufen. "Bitte ziehen Sie den Stift, um sich abzumelden."
edit: Der Abmelder implementiert das IDisposable
. Ich denke, dieses Schema wurde angewendet, um das Problem des erloschenen Hörers zu verhindern .
Zwei Dinge sind mir jedoch nicht ganz klar.
- Bietet die innere Unsubscriber-Klasse das Subscribe-and-Forget-Verhalten? Wer (und wann genau) ruft
IDisposable.Dispose()
den Abmelder an? Garbage Collector (GC) ist nicht deterministisch.
[Haftungsausschluss: Insgesamt habe ich mehr Zeit mit C und C ++ verbracht als mit C #.] Was soll passieren, wenn ich einen Beobachter K einem beobachtbaren L1 abonnieren möchte und der Beobachter bereits einen anderen beobachtbaren L2 abonniert hat?
K.Subscribe(L1); K.Subscribe(L2); K.Unsubscribe(); L1.PublishObservation(1003); L2.PublishObservation(1004);
Als ich diesen Testcode anhand des Beispiels von MSDN ausführte, blieb der Beobachter bei L1 abonniert. Dies wäre in der realen Entwicklung eigenartig. Möglicherweise gibt es drei Möglichkeiten, dies zu verbessern:
- Wenn der Beobachter bereits eine Instanz für das Abbestellen hat (dh sie ist bereits abonniert), wird er sich stillschweigend vom ursprünglichen Anbieter abmelden, bevor er eine neue abonniert. Dieser Ansatz verbirgt die Tatsache, dass er nicht mehr beim ursprünglichen Anbieter abonniert ist, was später zu einer Überraschung werden kann.
- Wenn der Beobachter bereits eine Abmeldeinstanz hat, wird eine Ausnahme ausgelöst. Ein gut erzogener Aufrufcode muss den Beobachter explizit abbestellen.
- Observer abonniert mehrere Anbieter. Dies ist die faszinierendste Option. Kann dies jedoch mit IObservable und IObserver implementiert werden? Mal schauen. Der Beobachter kann eine Liste der nicht abonnierten Objekte führen: eines für jede Quelle. Liefert leider
IObserver.OnComplete()
keinen Verweis auf den Anbieter, der ihn gesendet hat. Die IObserver-Implementierung mit mehreren Anbietern kann daher nicht bestimmen, von welchem Anbieter abgemeldet werden soll.
War der IObserver von .NET für das Abonnieren mehrerer IObservables vorgesehen?
Erfordert die Lehrbuchdefinition des Beobachtermusters, dass ein Beobachter mehrere Anbieter abonnieren kann? Oder ist es optional und implementierungsabhängig?