¿Cuál es la diferencia entre un observador y un suscriptor?

83

Estoy tratando de descifrar la siguiente función:

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

Obtuve una buena introducción a rxjava de http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/ pero solo mencionó Observer de pasada, diciendo que usará Subscriber la mayor parte del tiempo a los artículos de consumo emitidos desde un Observable.

¿Alguien puede explicarme?

  1. ¿Qué es un observador?
  2. ¿En qué se diferencia un observador de un suscriptor?
  3. ¿Qué hace el fragmento de código anterior?

Javadoc hizo que pareciera un suscriptor. El javadoc para suscriptor dice que implementa observador y suscripción. Estoy muy confundido.

MarcusH
fuente
Es el patrón Observer vs publicar / suscribirse . Son similares, pero tienen diferencias sutiles.
Sean Patrick Floyd
4
@SeanPatrickFloyd: ¿Puedes explicar las diferencias?
user541686
¿Qué es la variable 'detalles'?
Marian Paździoch

Respuestas:

63

EDITADO : con el comentario de @ Alrid

tl; dr

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

Entonces, un suscriptor es una implementación del observador , con semántica adicional en la suscripción (se trata más de cancelar la suscripción). El código en su pregunta solo muestra que pasa la Observerinterfaz, en lugar de la implementación (práctica de programación habitual).

Además, este código devuelve un Subscription, que puede deberse a que el autor de este código pensó que el cliente solo debería tener acceso a Subscriptionmétodos, sin acceso a elementos producidos por lo observable. Eso puede ser un error del programador.

larga historia

Realmente debería leer el contenido de este sitio web (o reservar): http://www.introtorx.com Se trata de Rx.Net, pero los conceptos son los mismos, que fueron creados por Erik Meijer y RxJava ejecutores siguieron ellos ( si es aplicable al lenguaje Java).

Esta página te interesará (es el segundo capítulo): KeyTypes

Aquí leerás en los primeros párrafos:

Hay dos tipos clave que debe comprender al trabajar con Rx y un subconjunto de tipos auxiliares que le ayudarán a aprender Rx de manera más eficaz. IObserver e IObservable forman los bloques de construcción fundamentales para Rx, mientras que las implementaciones de ISubject reducen la curva de aprendizaje para los desarrolladores nuevos en Rx.

...

Básicamente, Rx se basa en los cimientos del patrón Observer. .NET ya expone algunas otras formas de implementar el patrón Observer, como delegados o eventos de multidifusión (que suelen ser delegados de multidifusión).

Incluso si los tipos / API son un poco diferentes, aprenderá mucho con este libro, probablemente mucho más que con algunos blogs.

Lo que no dice este libro ( ... porque está en la implementación de RxJava )

El desarrollador principal de RxJava en este momento introdujo una ligera variación (ver PR # 792 ) que permitió distinguir dos tipos de contratos:

  • notificación -> Observer
  • (des) suscripción -> Subscription

Este cambio permitió expresar / dividir mejor estas preocupaciones de las clases de implementación de la biblioteca RxJava.

Sin embargo, como usuario de la biblioteca, el uso de implementaciones reales de la biblioteca RxJava debería ser lo suficientemente bueno.

Implementar un suscriptor requiere mucho más conocimiento, trabajo y cuidado; de hecho, la semántica de la suscripción es muy importante dependiendo del tipo de fuente observable (¿caliente o fría? ¿Caro de crear?)


Exponer en Subscriberlugar de Observeren casos como el anterior no interferirá con el código en la mayoría de los casos, pero no es el uso previsto para él a menos que se necesite esa semántica de cancelación de suscripción. Pero al final implementar a Subscriber, y puede implicar caer en algunos escollos como:

  1. gastar recursos en funciones que no utilizará
  2. no puede heredar de otra clase
  3. escriba un código de cancelación de suscripción incorrecto
  4. copiar / pegar código un código incorrecto o código correcto escrito para un contexto diferente
Brice
fuente
1
En 2.x, el Observador se usa para suscribirse a un Observable, y el Suscriptor se usa para suscribirse a un Fluido, el Suscriptor ya no implementa Observador, github.com/ReactiveX/RxJava/issues/4515
sarvesh chavan
40

(Editar: esto aparentemente solo es cierto para RxJava 1.)

  1. An Observeres un objeto que puede obtener datos de una fuente de datos (an Observable). La fuente de datos le envía datos llamando al del observador onNext().

  2. A Subscriberes un Observerque también puede darse de baja de esa fuente de datos (a través de la Subscriptioninterfaz).

  3. La getCar()función intenta devolver coches, pero no existe un método directo para hacerlo. Pero hay una función para obtener detalles del automóvil ( getCarDetails()) que llamará a un observador con todos los detalles del automóvil. Entonces llama a esa función y le pasa un observador que, cuando obtiene datos, buscará los datos del automóvil a partir de los detalles y los pasará a su propio observador.

Lawrence Kesteloot
fuente
2
Esto no es cierto a partir de RxJava 2, el suscriptor y el observador son dos interfaces completamente diferentes. Ninguno extiende al otro
FRR
19

En RxJava 2 org.reactivestreams.Subscriber hay una interfaz que cumple con la especificación Reactive Streams .

La principal diferencia Observablees que los nuevos Subscribersoportes contrapresión.

Observerestá suscrito Observabley Subscribersuscrito a Flowable(implementos org.reactivestreams.Publisher).

Ver descripción detallada aquí .

Yaroslav Stavnichiy
fuente
3

También en RxJava2 , si desea darse de baja, debe usar ResourceObserverfor Observabley ResourceSubscriberfor Flowable.

Marque esta pregunta

Beshoy Fayez
fuente