¿Cómo puedo implementar el equivalente RxJava de INotifyPropertyChanged para hacer un modelo de datos Observable?

Soy nuevo en Java y nuevo en Rx. Estoy en el fondo. Estoy en las primeras etapas de escribir una aplicación para Android que usará un patrón MVC (Model-View-Controller) y estoy experimentando con varias maneras de hacerlo, en particular RxJava. Mi idea es hacer que mi modelo sea Observable y mi View the Observer . El modelo (o una clase de contenedor) emitiría una nueva copia del modelo cada vez que sus datos cambiaran. En .net estaría pensando en usar INotifyPropertyChanged .

Creo que tengo que implementar una costumbre Observable – pero ¿cómo? Hay mucha documentación sobre cómo convertir colecciones en observables, pero esto no encaja en mi caso de uso, ya que no tengo una colección, solo un elemento, el modelo de datos. ¿Hay alguna forma de hacer esto? Recuerda que estoy desarrollando para Android, así que no puedo usar lambdas ni nada extravagante como eso.

[Actualización] Gracias a la respuesta de André Staltz, creo que estoy fuera de los bloques de salida. He subido con esta clase:

 import rx.Observable; import rx.subjects.BehaviorSubject; public class ObservableModel<TModel> { private TModel modelData; private BehaviorSubject<TModel> modelStream; private boolean disposed = false; public ObservableModel(TModel modelData) { this.modelData = modelData; modelStream = BehaviorSubject.create(modelData); } public TModel getModelData() { if (disposed) { throw new UnsupportedOperationException("The object has been disposed"); } return modelData; } public void setModelData(TModel modelData) { if (disposed) { throw new UnsupportedOperationException("The object has been disposed"); } this.modelData = modelData; modelStream.onNext(this.modelData); } public Observable<TModel> getObservable() { return modelStream; } public void close() { modelStream.onCompleted(); modelStream = null; modelData = null; disposed = true; } } 

No es necesario implementar un Observable personalizado, ya que los Observables son genéricos y están destinados a utilizarse simplemente especificando de qué tipo es el Observable.

Si observa los objetos de su modelo cambiando con el tiempo, realmente tiene una colección de objetos de modelo a lo largo del tiempo: [modelObject1, modelObject2, modelObject3, …]

Una manera sencilla de implementar esto es tener un Observable estático del tipo FooBarModel, es decir, Observable<FooBarModel> :

 public class FooBarModel { public static BehaviorSubject<FooBarModel> fooBarStream; // ... private int fooBarMember1; private int fooBarMember2; } 

En lugar de Observable<FooBarModel> , utilizamos un Subject (elegir PublishSubject o BehaviorSubject, como usted desea), que es similar a un bus de eventos. Cada vez que cambias fooBarMember1 o fooBarMember2 en FooBarModel, emites la instancia de FooBarModel llamando fooBarStream.onNext(this) , y cada suscriptor de FooBarModel.fooBarStream verá la nueva instancia de FooBarModel.

Sin embargo, esto es realmente sólo un sabor de la solución, y hay muchas otras maneras de hacer esto. Si su FooBarModel depende de las actualizaciones de alguna otra entidad "Baz", entonces podría tener más sentido reemplazar el BehaviorSubject por Observable , y en lugar de alimentarse directamente en nuevas instancias, sólo cree el Observable usando algunas funciones de transformación / combinación Como map (), flatMap (), delay (), filter (), etc.) en los Observables de "Baz".


Una buena arquitectura RxJava MVC es tener todos los tres Modelos, Ver y Controlador ser Observables que son circularmente dependientes entre sí.

La Vista observa las actualizaciones del Observable del Modelo y exporta Observables públicos para eventos de clics, eventos de teclado, entradas, etc.

El controlador observa la entrada del usuario de View Observables y procesa esas entradas para exportarlas como observables de "entrada de usuario procesada", en un formato adecuado para el modelo. Por ejemplo, si la vista tiene un observable del contenido textual del campo de la búsqueda, entonces el regulador exporta respectivamente un observable del contenido textual del campo de búsqueda minúscula . Otro ejemplo: el controlador interpreta los eventos de clic desde la vista como solicitudes de base de datos.

El modelo observa la "entrada de usuario procesada" del controlador y exporta los datos observables de aplicación.

En tal escenario, no necesariamente necesitarías sujetos. El beneficio de este enfoque es la separación pura de las preocupaciones: ninguna entidad actualiza ninguna otra entidad imperativamente . Toda la lógica del controlador se especifica completamente sólo en el controlador, en ningún otro lugar. Y también tiene una imagen limpia de las entradas y salidas. Las entidades observan otras entidades y exportan parte de sus datos como Observables. No hay ninguna llamada "controller.updateThisAndThat ()" en la vista.

Pero para empezar, utilice los sujetos ya que son fáciles de razonar acerca de la actualización de los observadores.

  • RxJava comparte las emisiones de un Observable entre múltiples suscriptores
  • RxJava para Android: Exponer Excepción y Reintentar (con retraso)
  • Retrofit no desencadena onError cuando se utiliza ErrorHandler personalizado
  • Rxandroid pide que se ejecute en el hilo ui aunque esté suscrito en AndroidSchedulers.mainThread ()
  • Solo observable con varios suscriptores
  • MVP de Android con RxAndroid + Retrofit
  • Rx Observable emitiendo valores periódicamente
  • ¿Cuál es la diferencia entre EventBus y RxJava?
  • Encadenamiento de llamadas de Retrofit con RxJava y devolución del objeto principal
  • No encontró la clase rx.android.schedulers.AndroidSchedulers
  • Cómo cancelar la solicitud con retofit2 y RxAndroid
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.