It is often said in some circles that Model states. If we represent everything going on a screen as a container of states, like isLoading, isChecked, it becomes our model. This definition of Model is more closely related to MVI’s Model. So instead of saying Model View Intent, it is more preferable to be called as State View Intention. It is also called the Hannes Model named after Hannes Dorfmann who inspired many people by bringing MVI to the Android world.
There are four basic elements in this State View Intention pattern. Those are State, View, Intention, and User. The addition of User in the pattern itself is what makes it different from other patterns.
The user interacts with the UI like User hits pull to refresh on the screen which can also be called User’s Intention to refresh the screen. This Intent brings about change in State of the screen. This change can occur via any kind of background logic, but the most important thing is that any change in this state has to happen only by firing an Intent. This new State is rendered on View and this newly updated View is shown to the User.
As you can see there is a unidirectional flow of data and none of these components can break this chain and start interacting with each other. This kind of approach restricts any change to the State of the system only via a defined set of actions (intentions). An undefined action by a user cannot cause any undesired change to our System.
Model-View-Intent is a very clean way to deal with application states and UI changes. A unidirectional data flow (cycle), predictable states and immutability are the exciting thing about MVI.
Composing functions leads to clean and reusable code. We can also mix MVI with MVP because MVP helps to separate your concerns. Furthermore, it can’t be highlighted enough about the importance of a Presentation Model. Transforming the Model into a Presentation Model is quite easy with Rx Java (just add a .map()) but improves your code a lot and reduces the complexity of your View layer.
The thing with MVI is like with any other software architecture: MVI gives you an idea, but there is still space for personal preferences and interpretation. One can add as many layers as needed. For example, the model() function could internally be composed by multiple functions (one might call they use cases or interactors, just functional). One could add Action data structures to decouple things between intent() and model() even more. But keep in mind: don’t over-engineer things!