MVC / MVP / MVVM

Three ways to keep the user interface apart from the domain logic. Know who talks to whom in each, why the differences matter for testing, and which one a given platform pushes you toward.

Overview

Every screen has the same three jobs: hold the data, draw it, and react when the user does something. MVC, MVP and MVVM are three answers to one question: which object does each job, and who is allowed to talk to whom. Get that right and the domain logic can be tested without a screen, the screen can be redrawn without touching the logic, and two people can work on the two halves at once.

The three patterns are a family, and interviewers like to hear the lineage. MVC came first: Trygve Reenskaug designed it at Xerox PARC in 1978 and 1979, for Smalltalk. MVP grew out of work at IBM and Taligent in the 1990s; Martin Fowler later split it into two variants, Supervising Controller and Passive View (2006). MVVM was named by John Gossman at Microsoft in 2005 for WPF, which relies on data binding; Fowler notes it is the same idea as his Presentation Model (2004) under a different name.

A strong answer names the three parts, draws the arrows, and then says the one thing that separates the patterns: how the view gets updated. In MVC the view watches the model. In MVP the presenter pushes into a passive view. In MVVM a binding layer copies view-model state into the widgets.

The problem all three solve

Without any separation, one class does everything. That class cannot be unit-tested, because every test needs a real window, and any change to the layout risks the business rules.

  • Hold the data and the rules — The account balance and the rule that it cannot go negative — Model
  • Draw it — Widgets, HTML, layout, colors — View
  • React to the user — Turn a click into a call on the model, then get the screen updated — Controller, Presenter or ViewModel

The Model is the same in every pattern: domain objects that know nothing about the screen. The differences are all in the third box and in the arrows around it.

MVC: the view watches the model

In Reenskaug's design the view and the controller are a pair that both know the model. The controller handles input and changes the model. The view observes the model and redraws itself when the model announces a change. The controller does not push data into the view; the observer relationship does that.

Web frameworks reuse the name with a different flow. A request comes in, a controller action runs, it reads or writes the model, and it hands data to a template that renders one response. There is no long-lived view watching a model, because the page is rebuilt on every request. Rails describes itself this way in its guides, and Spring calls its servlet framework Spring Web MVC. Django deliberately says MTV instead: its view decides which data to show and its template decides how, and it treats the framework itself as the controller.

  • How the view learns of a change — Observes the model — Rendered fresh on each request
  • Lifetime of a view — As long as the window is open — One request
  • Who calls the view — The model's notification — The controller, by returning a template
  • Where input arrives — Controller, per widget event — Controller action, per HTTP request

MVP: the presenter drives a passive view

MVP removes the arrow from model to view. The view becomes an interface with methods like show_balance(text) and show_error(text). The presenter is the only object that knows both the model and the view: it takes the user event from the view, calls the model, and tells the view exactly what to display. In Fowler's Passive View variant the view has no logic at all.

The payoff is a presenter test with no UI framework in it. The fake view records what it was told to show.

MVVM: the view binds to a view model

MVVM keeps the idea of a presentation object but changes how the view is updated. The ViewModel exposes properties (a balance string, an error string, a flag that says whether a button is enabled). The view binds widgets to those properties, and a binding mechanism copies changes across. The ViewModel never holds a reference to the view, so it can be tested by reading its properties. Gossman's original point was that on WPF the view is written declaratively, often by a designer, and data binding is what makes that split possible.

A ViewModel is a plain object with observable state. This one notifies subscribers when a property changes; a UI framework would do the subscribing for you.

Android's Jetpack ViewModel is the same idea with platform support: it is a screen-level state holder that survives configuration changes and exposes state through observable types such as StateFlow, which the UI collects.

The three side by side

  • View knows the model — Yes, it reads it — No — No, only the ViewModel
  • Middle object knows the view — Controller is paired with it — Presenter holds a view interface — ViewModel does not
  • How the view updates — Observes the model — Presenter calls view methods — Binding copies properties
  • Unit test of the middle object — Needs the model; view is separate — Fake view records calls — Read the ViewModel's properties
  • Needs a binding framework — No — No — Yes, or you write one
  • Typical home — Server-side web frameworks, classic desktop — Platforms without data binding — WPF, Android Jetpack, declarative UI toolkits

Choosing in an interview

Say the reason with the choice. 'Web, so MVC: each request is rebuilt anyway.' 'A binding toolkit, so MVVM: the framework does the view update for me.' 'No binding and a lot of screen logic, so MVP: I can test the presenter with a fake view.'

What you will be able to do

  • Name the three parts and draw the arrows for MVC, MVP and MVVM from memory, and point at the one arrow that differs.
  • Explain why a passive view makes the presenter testable, and write that test.
  • Describe what a binding layer does in MVVM and what it costs.
  • Say which pattern a given platform pushes you toward, and why.
  • Recognize a fat controller and move its logic into a use-case class.

Interview questions

  • Walk me through a button click in MVC, MVP and MVVM.
  • Why is MVP easier to unit-test than classic MVC?
  • What does data binding change in MVVM, and what does it cost?
  • What is a fat controller, and how do you fix it?
  • Do Rails, Django and Spring MVC really implement MVC?

Sign up free to read the full topic

More Low-Level Design topics

Start free on Cariara · Coding problems · System design studio