Arquitectura limpia: ViewModel con múltiples UseCases en Android

Esta es más una cuestión de Arquitectura que una corrección de errores.

Supongamos que esta aplicación permite a los usuarios marcar una estación de autobuses y / o autobuses como su favorito. Mi pregunta es, ¿debería tener un ViewModel con ambos UseCases o debería build un UseCase que encapsule la lógica actual?

También para la parte de la pregunta, no estoy del todo seguro de la forma en que debo exponer los datos combinados a la capa UI (ver favouritesExposedLiveData )

Gracias de antemano cualquier comentario es bienvenido, aquí está mi ViewModel usted puede suponer que cada UseCase está pasando los datos correctos de la (s) fuente (s) de datos.

 open class FavouritesViewModel @Inject internal constructor( private val getFavouriteStationsUseCase: GetFavouriteStationsUseCase, private val getFavouriteBusesUseCase: GetFavouriteBusesUseCase, private val favouriteMapper: FavouriteMapper, private val busMapper: BusMapper, private val stationMapper: StationMapper) : ViewModel() { private val favouriteBusesLiveData: MutableLiveData<Resource<List<BusView>>> = MutableLiveData() private val favouriteStationsLiveData: MutableLiveData<Resource<List<StationView>>> = MutableLiveData() private lateinit var favouritesMediatorLiveData: MediatorLiveData<List<FavouriteView>> private lateinit var favouritesExposedLiveData: LiveData<Resource<List<FavouriteView>>> init { fetchFavourites() } override fun onCleanetworking() { getFavouriteStationsUseCase.dispose() getFavouriteBusesUseCase.dispose() super.onCleanetworking() } fun getFavourites(): LiveData<Resource<List<FavouriteView>>> { return favouritesExposedLiveData } private fun fetchFavourites() { favouritesMediatorLiveData.addSource(favouriteStationsLiveData, { favouriteStationListResource -> if (favouriteStationListResource?.status == ResourceState.SUCCESS) { favouriteStationListResource.data?.map { favouriteMapper.mapFromView(it) } } }) favouritesMediatorLiveData.addSource(favouriteBusesLiveData, { favouriteBusesListResource -> if (favouriteBusesListResource?.status == ResourceState.SUCCESS) { favouriteBusesListResource.data?.map { favouriteMapper.mapFromView(it) } } }) getFavouriteStationsUseCase.execute(FavouriteStationsSubscriber()) getFavouriteBusesUseCase.execute(FavouriteBusesSubscriber()) } inner class FavouriteStationsSubscriber : DisposableSubscriber<List<Station>>() { override fun onComplete() {} override fun onNext(t: List<Station>) { favouriteStationsLiveData.postValue(Resource(ResourceState.SUCCESS, t.map { stationMapper.mapToView(it) }, null)) } override fun onError(exception: Throwable) { favouriteStationsLiveData.postValue(Resource(ResourceState.ERROR, null, exception.message)) } } inner class FavouriteBusesSubscriber : DisposableSubscriber<List<Bus>>() { override fun onComplete() {} override fun onNext(t: List<Bus>) { favouriteBusesLiveData.postValue(Resource(ResourceState.SUCCESS, t.map { busMapper.mapToView(it) }, null)) } override fun onError(exception: Throwable) { favouriteBusesLiveData.postValue(Resource(ResourceState.ERROR, null, exception.message)) } } } 

Nota: Actualmente, MediatorLiveData ( favouritesMediatorLiveData ) no vincula los datos a favouritesExposedLiveData porque, en este momento, no estoy seguro de que este sea el path correcto;).

    El objective de un ViewModel es que es un model de lo que está usando la vista. Debería estar lo más cerca posible de eso. A less que esté presentando estaciones y buses en la misma list de vistas (parece feo), de lo contrario, son vistas separadas y deberían get models separados.

    Idealmente, un ViewModel solo tendría el estado de vista para su vista. Al utilizar MediatorLiveData, puede agregar todas las fonts de estado en una que represente el estado de la vista a lo largo del time.

    Lo que puede tener es una class de datos que represente su ViewState que construya en su model de vista y que sea su LiveData expuesto

    data class FavouritesViewState(val favoriteStations: List<Station>, val favoritBuses: List<Bus>)

    Sin embargo, usted sabe que depende de ViewModel para build el ViewState final que rompe un poco el principio de responsabilidad única y también lo hace dependiente de un marco de Android.

    Me gustaría abordarlo usando un UseCase compuesto que tenía casos de uso de estación y bus y devuelve los datos compuestos que luego puede exponer fácilmente desde el ViewModel.