Comparison on MVP & MVVM & MVI

Binil Thomas
7 min readSep 16, 2019

--

Organizing, managing and testing your code has been made easier with MVP, MVVM and MVI design patterns. All these three do the same job in general but choosing one to implement in your projects can be a bit bothersome when you do not know the difference between them. So this article compares each of these architectures with each other so you know the difference between them and eventually make you able to decide by yourself which among them is best suited for your needs.

Model-View-Intent (MVI)

MVI pattern is a relatively new pattern compared to the others we discuss here. MVI stands for Model-View-Intent. The unidirectional and cyclical nature of the Cycle.js framework has been believed to inspire this design architecture. MVI can only work with RxJava — a Reactive programming library.

Components of MVI

1. Model

Yes, just like in MVC: Model View Controller, MVP: Model View Presenter, MVVM: Model View ViewMode; the M in MVI stands represents a state, rightfully called a Model. Models in MVI should be immutable to ensure a unidirectional data flow between them and the other layers in the architecture. Alternatively, this is also known as the data/logic layer.

So you can basically summarize the definition of model by saying that model() is a response to the creation of a new state. Example models can include everything from a progress bar to a list of fetched data to an error.

State

State is an immutable data structure. The only way to change the state in project implementing MVI architecture is by creating a new one by triggering intent().

2. View
Interfaces in MVI are represented by Views. Like that in the MVP model. The views are then which are then implemented in one or more Activities or Fragments according to your project and requirements.

3. Intent

Intent is received by the view for every action that the user inputs or the app itself wants to carry out. So you could generally say that before any action is carried there is an intent concerning that action beforehand. The Presenter observes the Intent, and Models translate it into a new state.

For example an intent can be started by the user clicking on a button or as a result of our API call that we want to display on the screen which makes all UI changes as a result of running intent().

4. User

Some may include this as a part of the MVI architecture while others may not. Addition of this component is already different from the other patterns.

How they all function together:

The user interacts with the interface in order to carry out an action which can be called User’s Intention. This Intent brings about change in State of the application. So before any state changes take place, an Intent is generated first. After the required action is carried out by the application with the help of its logic, the new State is rendered on View and this newly updated View is shown to the User. Hence, completing a cycle.

Unidirectional flow

You may have noticed that while an action or change is carried out, there is always a unidirectional flow of data and none of the components can break the flow and start interacting with each other. This helps to prevent any undesired changes to the application or action without an intention created for them. The main idea of the MVI development pattern is that no element of the layout does anything but send or receive data, and elements are divided according to what role they have in this data exchange.

A unidirectional data flow or a cycle, predictable states and immutability are what makes MVI different from the rest of the design patters.

Code

Here is a one line code that summarizes how MVI functions.

intent(user(view(model(intent(user())))))

The result of user() is passed as an input value for intent(). Then the output of intent() is an input for model(). Then a new state which is the only possible result of model(), is passed as an input for view(). Then the whole cycle repeats when output of view() is used to call user(). This concludes our unidirectional cyclic flow of data which is a core concept regarding the MVI design architecture.

What do these design patterns hope to achieve?

The main reasons as to why you would want to implement such design architecture in your project are to make your code more:

· High-quality

· Scalable

· Understandable

· Reliable

Along with abilities such as:

· Separation of Concerns

· Code reusability

· Testability

The ability to expand the project and implement new functions without much hassle and complications like to change the entire project from the very beginning itself or make some major changes that take time can be considered as scaling.

Understanding your code, how each sections of your code connect to the other can be considered as how understandable your project is. All the design patterns achieve this without any doubt.

Different ideas and logics within your project should be separated and be independent upon one another. For example, if you want to change something, you should not have to go to different parts of the code in order to see the changes reflected.

Brief about MVP

It stands for Model View Presenter. This architecture facilitates unit testing, the presenter is easy to write tests, and can also be reused because the presentation can implement multiple interfaces.

When you want to create the best in business interfaces for your applications, you should keep in mind that MVP should only be taken as basic ideas, and not development patterns for your project as there are better options out there for you.

The code is easy to test, and it is even easier to present the elements of the presentation as parameters via the interface, and not functions.

It should be noted that from the point of view of the presenter — nothing has changed.

Brief about MVVMI

Instead of binding the view to the interface, we bind the elements of the view to the parameters of the view model, which is the main idea behind MVVM. Here, ViewModels are simple to write tests, because they do not require writing mock objects because you change your own element and then check how it has changed.

Advantages of using MVI:

· No state problem because there is only one state for our app, which is a single source of truth.

· Unidirectional data flow makes the logic of our app more predictable and easier to understand.

· Immutability, as long as each output is an immutable object

· Debugging: unidirectional data flow also ensures that our app is easy to debug. Every time we pass our data from one component to another, we can log the current value of the outflow. Thus, when we get a bug report, we can see the state our app was in when the error was made, and we can even see the user’s intent under which this state was created.

· Decoupled logic and separation of responsibilities.

· Testability: all we have to do to write the unit test for our app is call a proper business method and check if we’ve got a proper state.

Drawbacks of MVI:

· Things can be a bit bothersome when you have certain actions to be completed. Each small UI change has to start with a user’s intent and then must pass the whole circle. Even with the easiest implementation, you have to create at least an intent and a state object for every action made in our app.

· Complexity: There is a lot of logic inside which must be strictly followed, and there is a high probability that not everybody knows about it. This may cause problems especially when you need to expand your team as it will take more time for newcomers to get used to it.

· Object creation: which is expensive. If too many objects are created, your heap memory can easily reach full capacity and then your garbage collector will be too busy. You should strike a balance between the structure and size of your app.

· SingleLiveEvents are a bit difficult to implement.

So which architecture does it best?

MVVM and MVI can help to improve the scalability of your application but they come with RxJava dependency. It should be remembered that you can select only a part of these elements, and configure them for the final application depending on the tasks.

Using a combination of these architecture patterns so that it fits the unique needs and goals of your mobile application can also be a viable solution if you and your team are up to the task. You don’t have to choose only one and can take several architectures and use elements from them.

I will publish the Git hub link for MVI sample soon, Just working on it.

--

--

Binil Thomas

12+ Years of experience in mobile development enabled me to offer various services to customers, including proof of concept, feasibility studies etc.