Part 2: Reactive architectures. MVVM + MVI + RxJava
Previous on Medium,
Part 1 of this series introduces Reactive architecture
with MVI
pattern to make your project able to use whole power of RxJava
instead of wrapping network requests into it.
TL;DR
In this part I introduce MVVM
provided by Google in the way which allows us to keep all advantages ofReactive architecture
with MVI
introduced in previous part. With this solution ViewModel
becomes an Observer
instead of Activity/Fragment(View
), but it keeps the same way of View
sending events.
Switching roles
MVVM
introduced by Google is great to deal with one of well known Lifecycle problems as screen rotation. With just RxJava
you can easily make your own LiveData
with BehaviorSubject which works in exactly the same way. Bigger problem is to create ViewModel
with regular Dependency Injection without connecting it to Application level. This is why a lot of developers stick with Google’s MVVM
.
By introducing MVVM
into project its View
loses any sense of being an Observer
because any data which has to be saved when Activity recreates is now held in ViewModel
. With this small changes ViewModel
becomes Observer
as a holder of data required by View
.
ViewModel
is Observer
now, View
receives required data through LiveData
, and does not receive any event from reactive chains anymore, but it still triggers new events after users actions. Now there is one small problem. What if we need to do something else except setting new List into RecyclerView or change text in TextView? To help with this problem it’s required to introduce third type of event which will be send to View
from ViewModel
through LiveData
if it should do something except change layout. At the same time it is a good idea to rename an old event to make names connected to current patterns:
- xViewModelEvent — event sent from
View
toViewModel
to trigger reactive chain to do required business logic - xUiModel — result of reactive chain with all data required for updating
View
- xViewEvent — event sent from
ViewModel
toView
throughLiveData
to trigger anyView
action different from layout changes (open Dialog, open another Activity etc.)
Practice
This part does not contain so much theory, so it’s time to show how does it look in practice.
ViewModelEvent/UiMode/ViewEvent
Event classes are the same as they were in part 1 of this series: sealed class which extends Base
class to be used in a safe way with Generics and implementations of extended classes which represent all required events or results.
View
This time there is nothing to show in View
. It contains ViewModel
saved in field to start observing LiveData
and send event to trigger reactive chain of business logic.
ViewModel
From this moment ViewModel
is the center of the Universe. Let’s start from Base
of this ultimate Universe.
Here are the key parts of BaseViewModel:
- It requires now 3 instead of 2 generics to describe all required events
- It’s now
Observer
- On initialization it describes where to pass event received in
Subject
and subscribes for results to itself - Subscription is saved in onSubscribe() to be able to dispose it when it is required
- In onClear() dispose() is called to loose all connections to
Observables
- In the same way as before, events are received in event() function which triggers chain of reactive logic in
Subject
- onEvent() is still required to identify received events
With this powerful BaseViewModel
final implementation does not require a lot of extra code to implement everything.
Only a few parts of implementation are interesting for now:
- By extending
BaseViewModel
it describes all required event classes - onEvent() identifies events in the same way as it is without
ViewModel
inMVI
- onNext() sets data/event which has to be setted/called in
View
- If
View
has to do some extra action different from changing layoutViewEvent
has to be passed into viewEventObservable (LiveData
)
Conclusion
This architecture is fair enough to use in most projects if team doesn’t want to do some extra complex separation. It gives you everything for what ViewModel
was created with the power of full RxJava
. However, if team is not scared of challenges and at the same time easy to scale project with faster builds is your goal, you are welcome to read next part of this series about modularizing
projects for Android.