Decoding Android Architectures: MVVM, MVC, MVP, MVI

Find the best way to build Android apps using MVVM, MVC, MVP, and MVI architectures.

Shirsh Shukla
9 min readNov 24, 2023

Hey, welcome back! in this article we’re talking about picking the best design pattern for your Android app — whether it’s MVVM, MVI, MVC, MVP, or something else. It might seem a bit tricky, but don’t worry! By the end of this, I’ll help you figure out which one suits your app best. Let’s dive in!

Now, let’s talk about the common ground. In all these patterns, the “M” stands for Model, representing your app’s data source, like local databases or remote APIs. The “V” stands for View, representing the UI layer, which includes fragments, activities, and composables in Android. So, the shared concept is having separate layers for data models and the UI.

What makes them unique is what comes after the “MV.” We’ll explore these differences, and I’ll guide you through each one. So, stick around for all the details!

M.V.V.M (Model-View-ViewModel)

MVVM Components:

  • ViewModel (VM): This is like the brains of our app. It holds the business logic, especially in MVVM. You can also add a domain layer to make your logic more reusable. This domain layer helps organize and separate your business logic.
  • View: This is what users interact with.
  • Model: This represents your data and business logic.

ViewModel Job:

  • The ViewModel main job is to interact with the data layer. It takes data from places like a database or a remote API, processes it, and changes it into a form that the UI can use.

UI State in MVVM:

  • In MVVM, the ViewModel provides the UI State for the View to observe. Each individual value that can change over time is kept separate. For instance, if you have a loading indicator, it’s just a single Boolean value, not mixed with other states.

Advantages and Disadvantages:

  • Advantage: MVVM makes it easy to handle something called “process death” in Android. This is when the system decides to close your app in the background. MVVM allows you to save and restore the state easily using a tool called a “saved State handle.”
  • Disadvantage: The downside is that dealing with all these separate states can make your ViewModel look crowded. For every state, you might end up with two separate pieces of code — one for the private mutable State and one for the public immutable State.

Example: If your ViewModel has many states, your code can become quite lengthy, and it might be challenging to find what you’re looking for.

In a nutshell, MVVM helps in keeping your app’s logic organized. However, if not handled carefully, it might result in a lot of code. It also simplifies dealing with the Android system killing your app in the background by providing tools to save and restore the state.

M.V.I. (Model-View-Intent)

Alright, let’s delve into MVI, or Model-View-Intent. Similar to MVVM, MVI involves three core parts: Model, View, and now, Intent.

MVI Components:

  • Intent: Unlike Android intents, in MVI, it signifies the user’s intention or action, such as clicking a button. These actions, often represented by event classes, are sent to the ViewModel. You might recall this concept from my earlier article where I discussed creating event classes for various user actions on a screen.

Handling User Actions in MVI:

  • User actions, or intents, are directed to the ViewModel in MVI. The ViewModel typically includes an onEvent function where it receives these intents. Then, in an extensive when expression, it checks the type of intent and performs the necessary action. This approach works seamlessly with Jetpack Compose, especially when dealing with child components.

UI States in MVI:

  • Unlike MVVM, MVI employs screen States. Instead of having separate states for each changing value, there’s a single State representing the entire screen. This state is usually a data class that combines all the values subject to change on that screen.
  • When updating the screen State, the common practice is to use the copy function, modifying the fields that have changed. This enhances code readability, as only one State is needed for the whole screen.

Advantages:

  • Readability: MVI can enhance code readability, especially when dealing with screen States. It provides a clear overview of potential changes on the screen.
  • Integration with Compose: MVI integrates seamlessly with Jetpack Compose, simplifying the propagation of events from child composable.

Disadvantages:

  • Race Conditions: MVI is more susceptible to race conditions compared to MVVM. The copy function, used for updating the State, lacks thread safety. It's crucial to take precautions to prevent race conditions, particularly in a Compose environment.
  • Process Death Handling: Managing process death in MVI can be challenging. Restoring the entire screen State might not always be ideal, leading to added complexities and workarounds.
  • UI Re-rendering: Any alteration in the screen State triggers a complete UI re-render. This may be inefficient, especially in scenarios like typing in a text field in Jetpack Compose, where every character update causes a full UI re-render.

In summary, while MVI offers advantages in terms of readability and Compose integration, it comes with challenges like potential race conditions, handling process death, and the tendency to re-render the entire UI with each State change. The decision to adopt MVI should consider these pros and cons based on your specific project needs.

M.V.P. (Model-View-Presenter)

let’s explore MVP (Model-View-Presenter), which stands for Model-View-Presenter. In MVP, the structure involves three main components: Model, View, and Presenter.

MVP Components:

  • Presenter: Unlike MVVM, MVP doesn’t feature a view model. Instead, it employs a presenter. The presenter acts as a counterpart to the view model, but with a crucial distinction — it has awareness of the view it is connected to. In MVVM, the fragment or activity knows about the view model, but the view model remains ignorant of the fragment or activity. However, in MVP, both the presenter and the view are mutually aware of each other.

Presenter-View Relationship:

  • In MVP, the presenter and the view have a direct relationship, knowing about each other. This is a departure from MVVM, where the view model operates more independently of the fragment or activity.

Advantages:

  • Direct Interaction: The close association between the presenter and the view allows for more direct interaction. Unlike MVVM, where the view model might not be aware of the fragment or activity, in MVP, there’s a mutual understanding between the presenter and the view.
  • Simplicity: MVP can simplify communication between the presentation logic and the UI, making it easier to understand and manage.

Disadvantages:

  • Tight Coupling: The close coupling between the presenter and the view might lead to tighter dependencies, potentially making it harder to separate concerns.
  • Testability: While the direct connection can be advantageous, it might make unit testing a bit more intricate compared to MVVM.

In summary, MVP in Android involves a structure where the presenter and the view are closely connected, creating a more direct relationship than in MVVM. This has both advantages, such as direct interaction, and potential drawbacks, like tight coupling between components. The choice between MVP and other architectures depends on the specific needs and preferences of the project.

M.V.C. (Model-View-Controller)

Now, let’s talk about MVC, which stands for Model-View-Controller. In MVC, the C stands for Controller. Similar to the presenter in MVP, the controller doesn’t directly update the view. Instead, it receives events, performs actions using the data model, and then updates the data model with new information. The view, in turn, observes these changes in the data model and updates itself accordingly.

Here’s a breakdown:

MVC Components:

  • Controller: In MVC, the controller is responsible for handling events. Unlike the presenter in MVP, its role is not to directly update the view. Instead, it processes events, interacts with the data model, and updates it. The view observes these changes in the data model and reacts accordingly.

Controller’s Role:

  • The controller receives events, which could be user interactions or other triggers. It then uses the data model to process these events and updates the data accordingly. However, it doesn’t directly manipulate the view.

Advantages:

  • Separation of Concerns: MVC maintains a clear separation of concerns. The controller handles user interactions and updates the data model, while the view focuses on displaying information based on the data model.
  • Responsibility Division: Unlike MVP, where the presenter has a more direct role in updating the view, MVC assigns the responsibility of updating the view to the data model, making the controller’s role more focused on event handling.

Disadvantages:

  • Potential for Complexity: Depending on the size of the project, MVC might lead to more complex controllers as they handle various events and data updates.
  • Observation Overhead: The view needs to observe changes in the data model to update itself. While this separation of concerns is beneficial, it might introduce some overhead in terms of observing and updating.

In summary, MVC in Android involves a structure where the controller is responsible for handling events, interacting with the data model, and updating it. The view observes changes in the data model and updates itself accordingly. This separation of concerns helps in maintaining a clear division of responsibilities in the app architecture.

Okay, let’s wrap up by discussing what I recommend for Android apps. In my opinion, MVVM is a solid choice because it has fewer drawbacks compared to MVI and others. MVVM’s separate states make it easier to restore our app’s state after process death, and we can efficiently combine and transform these states using flow operators. While it comes with the trade-off of having multiple state values (private and public), I believe it’s a manageable compromise. Additionally, there’s a promising feature on the horizon called explicit backing fields, which might simplify things in the future.

However, before you decide on any architecture, it’s crucial to remember that this is just my opinion. Software development is subjective, and it’s perfectly fine if you prefer MVP or any other pattern that works for you. I also use MVP in some of my projects.

The key takeaway here is to consider the goal of these architectures. The ultimate aim is to make your code more readable, maintainable, and testable, facilitating collaboration within a team. Regardless of the pattern, the core principles remain the same — modular design, SOLID principles, proper abstractions, a single source of truth, the single responsibility principle, and separation of concerns. These fundamentals are vital for any architecture.

So, my recommendation is to invest time in understanding these core principles. This knowledge provides flexibility, allowing you to deviate a bit from specific patterns while maintaining a solid and intuitive architecture. Yes, we can debate the merits of MVVM versus MVI, but let’s not forget the importance of these foundational principles.

Now, I’m curious about what architecture you use for your Android apps. Is it MVVM, MVI, or perhaps MVP or MVC? Feel free to share your thoughts in the comments below, also all the information I took it from many websites as some research if you find out any wrong info or misdirected, please point out or comment below.

If you got something wrong? Mention it in the comments. I would love to improve. your support means a lot to me! If you enjoy the content, I’d be grateful if you could consider subscribing to my YouTube channel as well.

I am Shirsh Shukla, a creative Developer, and a Technology lover. You can find me on LinkedIn or maybe follow me on Twitter or just walk over my portfolio for more details. And of course, you can follow me on GitHub as well.

Have a nice day!🙂

--

--

Shirsh Shukla

SDE at Reliance Jio | Mobile Application Developer | Speaker | Technical Writer | community member at Stack Overflow | Organizer @FlutterIndore