跪拜 Guibai
← All articles
Android · Android Jetpack · Architecture

MVC, MVP, MVVM: The 50-Year Evolution of Android Architecture

By 李斯维 · · 107 views · 3 likes · 2 comments
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Choosing the wrong architecture early in a project locks in technical debt that is far more expensive to fix than any bug. The progression from MVC to MVVM is not academic—it is a record of which coupling points actually hurt in production and which abstractions survive real iteration pressure.

Summary

Android development has cycled through three major architectural patterns in under a decade, each a direct response to the failures of the last. MVC arrived first, splitting network calls from Activities but leaving the View and Controller hopelessly coupled inside the same class. MVP fixed that by introducing a View interface and a Presenter that owned all logic, at the cost of an explosion of boilerplate interfaces and manual lifecycle management. MVVM, pushed by Google's Jetpack, eliminated the Presenter entirely by making the ViewModel a pure state container that the UI observes reactively.

The shift from imperative to declarative UI control is the thread that connects all three. In MVC, the Controller tells the View what to do; in MVP, the Presenter does the same through an interface; in MVVM, the ViewModel just mutates state and the framework handles the rest. That last step required Google to build a data-binding infrastructure—LiveData, then StateFlow—that Android never had natively, porting a concept Microsoft first shipped in WPF back in 2005.

MVVM is not the end of the line. Compose and unidirectional data flow (UDF) are pushing Android toward MVI, where all state changes funnel through a single reducer and the UI is a pure function of state. The names change, but the underlying lesson stays the same: the architecture that survives is the one that makes the View as dumb as possible and the data flow as predictable as possible.

Takeaways
MVC on Android forces Activity to act as both View and Controller, so the separation is cosmetic and the class still bloats with business logic.
MVP introduces a View interface and a Presenter, completely isolating the View from the Model but creating an explosion of boilerplate interface methods.
MVVM replaces the Presenter with a ViewModel that holds observable state; the View observes state changes and updates itself, so the ViewModel never touches the UI.
Data binding is the prerequisite for MVVM—without it, the ViewModel degenerates into a Presenter and MVVM collapses back into MVP.
Google did not invent MVVM; Microsoft did for WPF in 2005, and Google ported it to Android by building the missing data-binding infrastructure (LiveData, then StateFlow).
Repository is the Model-layer entry point in Google's architecture, encapsulating all data sources so the ViewModel never knows whether data comes from network, database, or cache.
MVI is not a separate architecture but MVVM with stricter rules: all state changes go through a single reducer, and the UI is a pure function of state.
Architecture is the hardest decision to change later; idioms and design patterns can be refactored incrementally, but a wrong architectural choice forces a rewrite.
Conclusions

Google's pattern of letting the community experiment for years before anointing an official architecture is a deliberate risk-management strategy, not neglect—it lets others pay the cost of discovering what breaks at scale.

The real value of MVVM is not the ViewModel class itself but the elimination of imperative UI updates; once the Presenter stops calling view.showX(), the entire testing and maintenance model changes.

Android's architecture story is really a story about the platform catching up to capabilities that desktop GUI frameworks had decades earlier—data binding, observable state, and declarative UI are old ideas that mobile simply lacked the infrastructure to support.

Every architecture solves the previous one's coupling problem by introducing a new abstraction, and that new abstraction immediately becomes the next coupling problem—Presenter interfaces in MVP, then ViewModel state management complexity in MVVM.

The Chinese Android market's shift from startup-driven chaos to enterprise maintenance work mirrors the architectural progression: MVC was good enough when speed mattered more than correctness; MVVM became necessary when apps had to survive years of maintenance by multiple teams.

Concepts & terms
MVC (Model-View-Controller)
A GUI architecture from 1978 that splits code into three layers: Model (data + business logic), View (UI rendering), and Controller (input handling). On Android, Activity typically serves as both View and Controller, which undermines the separation.
MVP (Model-View-Presenter)
A 1996 evolution of MVC that completely isolates View from Model by routing all communication through a Presenter. The View exposes an interface the Presenter calls; the View never touches the Model directly.
MVVM (Model-View-ViewModel)
An architecture Microsoft created for WPF in 2005, ported to Android by Google via Jetpack. The ViewModel holds observable state; the View binds to that state and updates automatically. The ViewModel holds no reference to the View.
Data Binding
The mechanism that makes MVVM work: when ViewModel state changes, the UI updates automatically without imperative calls. On Android, this was first implemented via LiveData and later StateFlow with Compose's collectAsStateWithLifecycle.
Repository
In Google's Android architecture, the single entry point for the Model layer that abstracts all data sources (network, database, cache). The ViewModel calls the Repository and never knows where the data actually comes from.
UDF (Unidirectional Data Flow)
A pattern where state flows down from a single source of truth to the UI, and events flow up from the UI to mutate that state. It is the foundation of MVI and Google's current recommended architecture for Compose.
MVI (Model-View-Intent)
An evolution of MVVM where all state changes pass through a single reducer function, making state transitions explicit and predictable. Google describes the same idea using 'UDF' and 'state hoisting' rather than the MVI label.
Sealed Class (UiState)
A Kotlin construct used in MVVM to model UI state as a finite set of types (Idle, Loading, Success, Error). The View switches exhaustively on these types, making it impossible to forget to handle a state.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗