The Ultimate Guide to MVC, MVP, MVVM, and MVI for Android Engineers — Part 1
Clearing up the confusion around Android architectures once and for all
Lately, the MVI architecture has been coming up a lot in the Android community. To get a better grasp of MVI, I decided to revisit and study the existing architectures as well.
Since I want to cover MVI in depth, I've split this blog post into two parts. In Part 1, we'll look at MVC, MVP, and MVVM. In Part 2, we'll dive deep into MVI.
In this post, we'll explore the components, pros, and cons of MVC, MVP, and MVVM.
1. MVC
MVC is the foundational architecture that led to MVP and MVVM. Both MVP and MVVM evolved from MVC. Compared to other architectures, MVC has been interpreted and modified in various ways over time depending on the platform. Let's first look at traditional MVC, the form in which it was initially proposed.
Here is what M, V, and C stand for:
1. Model
A collective term for the data and business logic used to implement the application.
(The definition of Model is identical across MVC, MVP, and MVVM.)
2. View
How the model is displayed on the screen; in other words, the UI.
The View is unaware of the Controller and only knows about the Model.
It expects the Model to be passed to it, and it can render the View using the model.
3. Controller
Receives user input and updates the Model accordingly.
Does not directly manipulate the View.
One thing to note is that the View expects the Model to be delivered to it without going through the Controller. Because of this, we have to figure out ways for the View to receive the Model. Here are a few common methods:
1. Model 스스로 자신의 변화를 View에게 알립니다.
2. View가 주기적으로 Model을 가져와 업데이트합니다. (Polling)Personally, I can't clearly picture how to implement these two methods in Android without going through the Controller. That's why I think applying the strict MVC concept exactly as it is to Android development has always been challenging.
If we map each component to Android code elements, it looks like this:
When applying the MVC structure to Android, the Activity takes on the role of the Controller. This is because it can receive user inputs through listeners like OnClickListener and modify the model based on those inputs.
The xml codes then act as the View. At this point, it's hard for the View to know about the Model unless the Activity (=Controller) mediates in the middle. If the Activity mediates between the View and the Model here, the Activity becomes the Controller while also acting as some sort of hybrid of the View and Model.
MVC has been interpreted in various ways over time. In early MVC, the View and Model were connected, but in later iterations, they aren't directly linked. In the evolved form, the Controller handles the View directly. With this modified approach, you can actually implement MVC using Android code. However, there's a lot of debate over whether this modified form can still be called true MVC.
Let's look at the pros and cons of MVC:
Pros
Roles within the code are divided, initiating the separation of concerns.
It is the fastest to learn compared to other architectures.
Cons
The View and Model depend on each other. Specifically, if the Model directly references the View, the logic layer ends up depending on the UI layer, which violates clean architecture principles.
The Controller becomes bloated as it takes on various roles.
It is difficult to clearly isolate the Controller in Android.
2️. MVP
Now let's look at MVP, a variation of MVC.
Here is what M, V, and P stand for:
1. Model
Same as the Model in MVC.
A collective term for the data and business logic used to implement the application.
2. View
How the model is displayed on the screen; in other words, the UI.
Unlike the View in MVC, it receives user inputs.
It holds a reference to the presenter.
3. Presenter
Receives user input from the View, processes the Model, and then updates the View again.
Can be thought of as a bridge connecting the View and the Model.
Has a 1:1 relationship with the View.
Holds a reference to the view.
If we map MVP to Android code elements, it looks like this:
Unlike MVC, MVP has the View receive the user's input.
Because of this, the Activity can be treated as a View.
Let's look at the pros and cons of MVP:
Pros
The ambiguous boundaries from MVC have been sorted out (the Activity is moved to the view layer).
The View and Model (=business logic) do not depend on each other.
Cons
The View and Presenter are coupled 1:1 and know about each other. It becomes difficult to decouple them. (Because of this, they are loosely connected using an interface at the very least.)
To maintain this 1:1 relationship, a presenter is added for every view even if it lacks significant meaning, which inflates the number of presenters.
3️. MVVM
I believe this is the most universally used architecture in Android. It's an architecture that resolves the shortcomings of MVP.
Let's jump right into M, V, and VM.
1. Model
Same as the Model in MVC.
A collective term for the data and business logic used to implement the application.
2. View
How the model is displayed on the screen; in other words, the UI.
Receives user inputs.
Knows about the ViewModel (in other words, the code depends on the viewModel).
3. ViewModel
Is unaware of the View.
Receives user input from the View and processes the Model.
However, it doesn't know exactly what object the view is. It does not import the view.
After updating the model appropriately, it defines states to expose externally, and the view fetches those states on its own.
Does not have a 1:1 relationship with the View.
If we map MVVM to Android code elements, it looks like this:
Through observable patterns, data binding, etc., the view can fetch the viewModel's state values even if the viewModel doesn't reference the view. The diagram has changed by one gray arrow compared to the MVP one. Essentially, the viewModel updates the Model using LiveData, Flow, etc., and the view subscribes to this data.
Let's look at the pros and cons of MVVM:
Pros
The View does not depend on the Model (=business logic).
The ViewModel does not depend on the View.
Unlike MVP, the view and viewModel are not tightly coupled.
Since the viewModel is unaware of the view, dependencies are decoupled, making it easier to swap views.
Because of this, it is the easiest pattern among the above to write tests for.
Since the ViewModel and View don't have a 1:1 relationship, a well-divided ViewModel can be reused across multiple views. However, be aware that recent Android guidelines recommend against reusing ViewModels at the view level.
Cons
It can feel more complex compared to MVC and MVP.
There are additional concepts you need to learn, like data binding.
In the next post, we'll explore MVI!
References
https://martinfowler.com/eaaDev/uiArchs.html
https://academy.realm.io/kr/posts/eric-maxwell-mvc-mvp-and-mvvm-on-android/
https://tomyrhymond.wordpress.com/2011/09/16/mvc-mvp-and-mvvm/
https://ko.wikipedia.org/wiki/%EB%AA%A8%EB%8D%B8-%EB%B7%B0-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC
https://ko.wikipedia.org/wiki/%EB%AA%A8%EB%8D%B8-%EB%B7%B0-%ED%94%84%EB%A6%AC%EC%A0%A0%ED%84%B0