¿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.
- Retrofit no puede crear adaptador de llamada
- RxJava: ¿Cómo reanudar el trabajo de un observable si se produce un cambio de configuración?
- Cómo manejar el error auth0 403 sin agregar código específico en todas partes (Retrofit / okhttp / RxAndroid)
- ¿Qué está causando HTTP FALLA: java.net.SocketException: Socket cerrado?
- RxJava2 función de rebote no funciona correctamente en RecyclerView - Android
[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; } }
- Dar un RxJava Observable algo a emitir de otro método
- Limitar el rendimiento con RxJava
- Arquitectura de la aplicación de Android: RxJava
- Cómo anular los Observables compartidos, infinitos con un retraso después de que el último suscriptor no se haya suscrito
- RxJava - cómo invocar abonado en eventos de 4 clics en Android
- Usando observeOn () el hilo de interfaz de usuario de Android bloquea mi prueba de emulador
- Combinación de llamadas API con RX Java
- No se puede convertir el objeto Subclase en cuerpo de solicitud json en Retrofit 2.0 con GsonConverterFactory
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.
- Android build tools 1.1.0, carpeta de prueba de unidad?
- Cómo enumerar pares de valores clave de un paquete