from https://lambda-it.ch/blog/post/reactive-data-flow-in-angular-2 I’ve always been curious about MVI, ever since I saw the example implementation of . To be honest, I’m still not entirely sure how that one works (I think it’d deserve its own article) — it looks nicer with lambdas, and it is an implementation of a finite-state state machine with strictly defined states, where the unions define the given state, and how they react in that given state. the “Tennis Kata” using RxSealedUnions With that union setup, invalid states are impossible. While this is what MVI hopes to achieve with its immutable view state — to me, and maybe many others, the concept of MVI seems hard to grasp, hard to master, and hard to implement. If you want to learn about MVI, you’ll see intimidating code and intimidating frameworks such as (JS), (JS), (Kotlin), and last but not least (a functional language, unlike C#, C++ or — which are imperative)! Cycle.js Redux Cyklic Elm Architecture written in Elm Java And on top of that, many examples love showing synchronous code where you add a TODO to a memory store with no persistence and no asynchronous operations — well, real life isn’t so easy. Redux But enough talk, I promised MVI, so here we go! Deck of Cards Luckily, (he’s a cool guy, you should follow him) put together a fairly approachable example that is based on MVI architecture (and this is pretty much a follow-up to his ). Zak Taccardi previous post on State Renderers Picture of the Deck of Cards app The source code is available at , and it is written in Kotlin. Zak Taccardi’s Github repository ( ZakTaccardi/deck-of-cards ) However, if you feel uneasy with following Kotlin, then luckily, I took the time and converted the code to Java, which can be found under . my name in a fork ( [zhuinden/deck-of-cards](https://github.com/Zhuinden/deck-of-cards) ) . . . The app itself looks fairly simple — you can tap the card to have the top of the deck dealt, you can ask the app to shuffle the deck. and you can create a new deck (which takes all dealt cards and reshuffles it). The operations themselves are not immediate — it simulates “loading” in-between, as the “network requests” take time. Occasionally, there is also “error” injected with a random chance, to show that sometimes, things don’t work out, and we need to handle error states as well. Overview of components Components and their interactions with one another There are a few important things to note here. : refers to the actions that the user can trigger via the UI. Intentions : subscribes to all exposed requests and operations that trigger a change in state. When a request/operation occurs, these are mapped to a type of — which is used to reduce (evaluate) the new state based on the previous state and the change. Presenter Change : represents a type of change which determines how the State should be changed. Change : represents the state of the application — in this case, the current Deck, if shuffling, is dealing, is building a new deck, or if there is an error. State : delegates the call from the Presenter to the . Ui render(State) StateRenderer : separates the into parts and observes changes in it individually (with a filter, using a ), then calls the which modify the UI when a change occurs in a given property. StateRenderer State distinctUntilChanged() PublishRelay UiActions : represents the actions with which the UI can be manipulated. Essentially the from MVP/MVVM. UiActions View About the Dealer… The last remaining component isn’t strictly part of the architecture, it is an application-specific component: the . Dealer In fact, I didn’t list it above because it behaves a bit… oddly. Instead of using or to connect the “input” requests with the “output” modified deck or operations — a combination of is used with individual subscriptions to s , but as the is a , it stores previous value! flatMap() concatMap() doOnNext() BehaviorRelay deck BehaviorRelay If this were strict MVI, the only would exist inside the , and the dealer would receive the state, and use the deck from there. deck State The anomaly of using with relays most likely stems from that each exposed operation provides multiple events, typically both a change in deck, and a . This could be replaced with a common sealed class, and exposing an that emits multiple events (then calls ). doOnNext() __Operation Observable onComplete() But while the communication with the isn’t entirely stateless, we can still learn a lot from this example. Dealer Intentions All user actions are exposed via s. The presenter listens to them, and maps them to changes, additionally triggering the to do its thing. PublishRelay Dealer Presenter The presenter is subscribed for events from both the (user actions), and the . These are all converted to subclasses of the object, based on which a new state is evaluated from the previous state, and the new state is rendered to the UI. Intentions Dealer Change Change Naming the actions that can change the state is the . In Redux, this is the , in this example, it is the . It represents the ways that the state can change. heart of all MVI solutions Action Change State The state stores the current state (unsurprisingly), but also describes how to evaluate the new state using a . In Redux, this would be called the . Change StateReducer When the object changes, a copy of it is returned, with the given variable modified based on how it is affected by the . Change StateRenderer The presenter tells the Ui to render the state, but this is actually handled by the , which will call the right to determine how to make the Ui show what we want it to show. StateRenderer UiActions UiActions As we can see, the UiActions represent the in MVI, not much more to say about it. View Conclusion The example showed us a glance at MVI. Our most important take-aways are: deck-of-cards Application logic is driven via exposing events, especially for interactions with the UI ( , where the name of the architecture comes from) Intentions Naming the actions that can change the state The state is explicit, and always immutable, and always copied on change In this case, the responsibility of “driving the Ui” is the StateRenderer Apparently, is pretty useful for cutting our stream into multiple streams! :) PublishRelay For more resources, you can check out: (an example without Rx!) KUnidirectional Hannes Dorfmann’s writings on MVI (which is the inspiration behind the MVI variants on Android) this video by the guy behind Cycle.JS this video by the guy behind Redux (which is very similar to MVI) on how he turned Stores into Reducers !) this talk by Jake Wharton on managing state reactively (and properly (maybe also this talk by Christina Lee on ViewDrivers that maybe one day we’ll also understand, along with this proposition behind it) Special thanks again to for writing an example that can be understood once looking through it properly. Zak Taccardi Source code is available in Kotlin by Zak Taccardi or in Java transcripted by me .