Was ist der Unterschied zwischen einem Beobachter und einem Abonnenten?


82

Ich versuche folgende Funktion zu entschlüsseln:

Subscription getCar(id, Observer<Car> observer) {
    return getCarDetails(id, new Observer<CarDetails> {
                             @Override
                             onNext(CarDetails details) {           
                                 observer.onNext(details.getCar());
                             } });
}

Ich habe eine gute Einführung in rxjava von http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/ erhalten, aber Observer wurde nur beiläufig erwähnt, da Sie den größten Teil des Abonnenten verwenden werden Zeit für Verbrauchsgüter, die von einem Observable ausgegeben werden.

Kann mir jemand erklären

  1. Was ist ein Beobachter?
  2. Wie unterscheidet sich ein Beobachter von einem Teilnehmer?
  3. Was macht das obige Code-Snippet?

Javadoc ließ es wie einen Abonnenten erscheinen. Das Javadoc für Abonnenten gibt an, Beobachter und Abonnement zu implementieren. Ich bin sehr verwirrt.


Es ist das Observer- Muster im Vergleich zu Publish / Subscribe . Sie sind ähnlich, haben aber subtile Unterschiede.
Sean Patrick Floyd

4
@ SeanPatrickFloyd: Kannst du die Unterschiede erklären?
user541686

Was ist die Detailvariable?
Marian Paździoch

Antworten:


62

EDITIERT : mit @ Alrids Kommentar

tl; dr

public abstract class Subscriber<T> implements Observer<T>, Subscription

Ein Abonnent ist also eine Implementierung des Observers mit zusätzlicher Semantik für das Abonnement (es geht mehr um das Aufheben des Abonnements). Der Code in Ihrer Frage zeigt nur, dass er die ObserverSchnittstelle anstelle der Implementierung (übliche Programmierpraxis) passiert .

Auch dieser Code gibt a zurück Subscription, was möglicherweise daran liegt, dass der Autor dieses Codes der Meinung war, dass der Client nur Zugriff auf SubscriptionMethoden haben sollte, ohne Zugriff auf Elemente, die vom Observable erzeugt werden. Das kann ein Programmiererfehler sein.

lange Geschichte

Eigentlich sollten Sie den Inhalt dieser Website (oder dieses Buches) lesen: http://www.introtorx.com Es geht um Rx.Net, aber die Konzepte sind dieselben, sie wurden von Erik Meijer erstellt und RxJava-Implementierer folgten ihnen ( falls zutreffend für die Java-Sprache).

Diese Seite wird Sie interessieren (es ist das zweite Kapitel): KeyTypes

Hier lesen Sie in den ersten Absätzen:

Bei der Arbeit mit Rx sind zwei Schlüsseltypen zu verstehen, und eine Untergruppe von Hilfstypen, mit denen Sie Rx effektiver lernen können. Der IObserver und IObservable bilden die Grundbausteine ​​für Rx, während Implementierungen von ISubject die Lernkurve für Entwickler, die Rx noch nicht kennen, verkürzen.

...

Im Wesentlichen basiert Rx auf den Grundlagen des Observer-Musters. .NET bietet bereits einige andere Möglichkeiten zum Implementieren des Observer-Musters an, z. B. Multicast-Delegaten oder Ereignisse (bei denen es sich normalerweise um Multicast-Delegaten handelt).

Auch wenn Typen / APIs etwas anders sind, werden Sie mit diesem Buch viel lernen, wahrscheinlich viel mehr als mit einigen Blogs.

Was dieses Buch nicht sagt ( ... weil es in der RxJava-Implementierung ist )

Der Hauptentwickler von RxJava führte zu diesem Zeitpunkt eine geringfügige Abweichung ein (siehe PR # 792 ), mit der zwei Arten von Verträgen unterschieden werden konnten:

  • Benachrichtigung -> Observer
  • (un) Abonnement -> Subscription

Diese Änderung ermöglichte es, diese Bedenken der implementierenden Klassen der RxJava-Bibliothek besser auszudrücken / aufzuteilen.

Als Bibliotheksbenutzer sollte es jedoch ausreichend sein, tatsächliche Implementierungen der RxJava-Bibliothek zu verwenden.

Die Implementierung eines Abonnenten erfordert viel mehr Wissen, Arbeit und Sorgfalt. In der Tat ist die Abonnementsemantik abhängig von der Art der beobachtbaren Quelle (heiß oder kalt? Teuer zu erstellen?) Sehr wichtig.


Das Belichten Subscriberund nicht Observerin den oben genannten Fällen beeinträchtigt den Code in den meisten Fällen nicht, ist jedoch nicht für die beabsichtigte Verwendung vorgesehen, es sei denn, diese Semantik für das Nichtabonnieren ist erforderlich. Aber am Ende wird die Implementierung von a Subscriberund kann dazu führen, dass einige Fallstricke auftreten, wie z.

  1. Geben Sie Ressourcen für Funktionen aus, die Sie nicht verwenden werden
  2. kann nicht von einer anderen Klasse erben
  3. Schreiben Sie einen falschen Code für die Abmeldung
  4. Kopieren / Einfügen von Code Ein falscher Code oder ein korrekter Code, der für einen anderen Kontext geschrieben wurde

39

(Edit: Dies gilt anscheinend nur für RxJava 1.)

  1. An Observerist ein Objekt, das Daten aus einer Datenquelle (an Observable) abrufen kann . Die Datenquelle überträgt Daten an sie, indem sie den Beobachter anruft onNext().

  2. A Subscriberist ein Observer, der sich auch von dieser Datenquelle abmelden kann (über die SubscriptionSchnittstelle).

  3. Die getCar()Funktion versucht, Autos zurückzugeben, aber es gibt keine direkte Methode, um dies zu tun. Es gibt jedoch eine Funktion zum Abrufen von Fahrzeugdetails ( getCarDetails()), mit der ein Beobachter mit allen Fahrzeugdetails aufgerufen wird. Es ruft diese Funktion auf und übergibt sie an einen Beobachter, der beim Abrufen von Daten die Fahrzeugdaten aus den Details abruft und an seinen eigenen Beobachter weiterleitet.


2
Dies gilt nicht für RxJava 2, Teilnehmer und Beobachter sind zwei völlig unterschiedliche Schnittstellen. Keiner verlängert den anderen
FRR

19

In RxJava 2 org.reactivestreams.Subscriber befindet sich eine Schnittstelle, die der Spezifikation von Reactive Streams entspricht .

Der Hauptunterschied Observablebesteht darin, dass neu Subscriberden Gegendruck unterstützt.

Observerist abonniert Observableund Subscriberist abonniert Flowable(Geräte org.reactivestreams.Publisher).

Siehe detaillierte Beschreibung hier .


3

Auch in RxJava2 sollten Sie ResourceObserverfür Observableund ResourceSubscriberfür verwenden , wenn Sie sich abmelden möchten Flowable.

Überprüfen Sie diese Frage

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.