100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
.NET

MVVM vs MVC vs MVP

A comparison of how MVC, MVP, and MVVM each connect the middle layer to the View, and when to choose each.

FoundationsIntermediate10 min readJul 10, 2026
Analogies

MVVM vs MVC vs MVP

MVC, MVP, and MVVM are all attempts to separate an application's data and business logic from its UI, but they differ in how the middle layer talks to the View. In classic MVC, the Controller receives input and updates the Model, and the View queries the Model directly and re-renders on its own. In MVP, the Presenter takes over both input handling and the job of pushing formatted data into the View through an explicit interface, so the View is a thin, passive contract. In MVVM, the ViewModel exposes observable state and commands, and the View binds to them declaratively, so no code ever manually pushes values into UI controls.

🏏

Cricket analogy: Comparing three broadcast setups: in one, commentators (Controller) shout updates and the scoreboard operator checks the official scorebook (Model) themselves; in another, a producer (Presenter) explicitly types each number onto a fixed graphics template; in the third, the graphics system (View) is simply wired to auto-update from the official digital scoring feed (ViewModel), no manual entry needed.

MVC: Controller-Centric

In MVC, the Controller is the entry point for user input: it receives a click or form submission, mutates the Model accordingly, and then either the View re-queries the Model or the Controller selects and configures a View to render. Critically, the View in classic MVC is allowed to read from the Model directly, which means the View and Model can become coupled, and the Controller can end up making direct calls into View APIs to update it, blurring the boundary the pattern was meant to enforce. This is the pattern behind most server-rendered web frameworks like Ruby on Rails and ASP.NET MVC, where a new View (HTML page) is generated per request.

🏏

Cricket analogy: In Rails-style MVC, think of a scorer (Controller) recording a boundary into the official scorebook (Model), and then the stadium screen (View) is instructed by the scorer's assistant to redraw the full scorecard from that book, page by page, for every single ball.

MVP: Presenter and the View Interface

MVP tightens MVC's loose boundary by making the View a passive interface with methods like ShowError(message) or SetItems(list), and it is the Presenter's job to call those methods explicitly after computing what the View should display; the View never reads the Model on its own. Unlike MVVM, there is no automatic binding: every update is an explicit, imperative method call from Presenter to View, which makes MVP a natural fit for platforms like older Android (with Activities/Fragments as the View) or Java Swing, where a built-in reactive binding system is absent. This explicitness makes MVP very easy to reason about and mock in tests, at the cost of more boilerplate than MVVM's binding.

🏏

Cricket analogy: A commentary producer (Presenter) explicitly calls out to the graphics operator, 'put up 145 for 3,' rather than the graphics screen (View) reading the scorebook itself, meaning every single number displayed passes through an explicit instruction.

kotlin
// MVP: explicit Presenter -> View interface calls (classic Android)
interface LoginView {
    fun showError(message: String)
    fun setLoginButtonEnabled(enabled: Boolean)
}

class LoginPresenter(private val view: LoginView, private val authService: AuthService) {
    fun onUsernameChanged(username: String) {
        view.setLoginButtonEnabled(username.isNotBlank())
    }
    fun onLoginClicked(username: String, password: String) {
        if (!authService.validate(username, password)) {
            view.showError("Invalid credentials")
        }
    }
}

// MVVM equivalent: no explicit calls, just bound observable state
class LoginViewModel : ViewModel() {
    val username = MutableStateFlow("")
    val canLogin = username.map { it.isNotBlank() }
    val errorMessage = MutableStateFlow<String?>(null)
}

The core structural distinction: MVP's Presenter actively pushes data to the View via method calls on an interface, while MVVM's ViewModel passively exposes observable properties that the View pulls in via a binding framework — this is why MVP requires a mock View in tests, while MVVM tests often just assert on ViewModel property values directly.

Choosing Between Them

Choose MVC when building server-rendered, request/response web applications where a fresh View is generated per request and there's no persistent client-side UI state to keep in sync. Choose MVP when your platform lacks a mature reactive binding system, or when you want maximum explicitness and don't mind writing interface boilerplate — this made MVP popular for early Android before Jetpack and LiveData existed. Choose MVVM when your UI framework provides first-class observable state and binding, such as SwiftUI, Jetpack Compose, Angular, or WPF, since MVVM lets that binding infrastructure eliminate the boilerplate that MVP would otherwise require by hand.

🏏

Cricket analogy: A local club match scored purely on a paper scorebook that's re-copied for each new edition of the newsletter behaves like MVC's per-request regeneration; a franchise league with a dedicated statistician manually phoning updates to graphics behaves like MVP; an international match on a modern broadcast with live sensor-fed graphics behaves like MVVM.

A frequent point of confusion is that MVP and MVVM look nearly identical on a whiteboard — both have a middle layer that isn't the Controller — but the test is always 'does the View get updated via explicit method calls (MVP) or via bound, observable properties (MVVM)?' If your 'ViewModel' is manually calling methods on a View interface, you have actually built MVP with a different name.

  • MVC's Controller updates the Model directly, and the View may query the Model on its own, which can blur boundaries.
  • MVP replaces the View's direct Model access with a passive interface that the Presenter updates via explicit method calls.
  • MVVM's ViewModel exposes observable properties and commands, and the View binds to them declaratively with no manual push calls.
  • MVC fits server-rendered, request/response applications like classic Rails or ASP.NET MVC apps.
  • MVP suits platforms without mature reactive binding, historically early Android and Swing.
  • MVVM shines on platforms with first-class binding, such as SwiftUI, Jetpack Compose, Angular, and WPF.
  • The dividing line between MVP and MVVM is explicit method calls versus automatic data binding.

Practice what you learned

Was this page helpful?

Topics covered

#NET#MVVMDesignPatternStudyNotes#MicrosoftTechnologies#MVVMVsMVCVsMVP#MVVM#MVC#MVP#Controller#StudyNotes#SkillVeris