MVC vs MVP vs MVVM

Both MVP and MVVM are derivatives of MVC (see timelines and how these have evolved). The key difference between them is the dependency each layer has on other layers as well as how tightly bound they are to each other. See diagram and the references column for more details.

These patterns try to address mainly the problems of structuring the code that relate to 1. Application state, 2. Business Logic and 3. State and View synchronization.

 

Machine generated alternative text:
Input
View I’ÇN 
+
I Controllerj
z-
j Model
MVC

 

 

Machine generated alternative text:
14 InpUt
VIew
‘Si
I*mnt.i
MVP

MVP is somewhere in the middle of MVC and MVVM. Also known as Presentation Model pattern

Machine generated alternative text:
View I• Input
‘\
Ivoirw Mod.I
Model I’
MVVM

 

 

 

Explanation and flow
  • A user input like click of a link or a URL results in first interrupt by the controller.
  • A controller can output different views, based on authorization, error validation, success or custom logic, etc. See many-to-one relationship. Also note one-way communication from controller to the view.
  • Controller passes the model to the view, and view binds itself using a templating engine (Razor in case of ASP.NET MVC).
  • Model is usually a data-object POCO (Plain old CLR Object) with minimal to no methods (behavior).
  • A user input begins with the view and not presenter. View invokes commands on the presenter, and presenter in-turn modifies the View.
  • View and Model never communicate or know of (refer) each other.
  • Presenter is a layer of abstraction of the View.
  • There is always a one-to-one mapping between a presenter and the view.
  • Presentation Model and View talk to each other. View grabs properties and calls methods on the PM. PM exposes properties and methods for View and dispatches events, which the View may listen to.
  • PM talks to the Model in the domain layer either through a reference it contains or directly through indirect message.
  • A user input begins with the view and may end up in executing a ViewModel behavior.
  • View and Model never communicate or know of (refer) each other.
  • ViewModel is a strongly-typed model for the view that is an exact reflection (metaphorically speaking) or abstraction of the view.
  • ViewModel and View are always synced.
  • Model has no idea that View and ViewModel exists, and ViewModel has no idea that a View exists, which promotes for decoupling scenarios that pay off the dividend.
References

In C# a reference means that if a class uses the other.

In JavaScript, if a module or in case of View, if HTML contains a reference to the JavaScript module.

  • View refers to the model, but not vice-versa.
  • The controller refers the model, populates it and passes it to the View.
  • View is oblivious of the controller, but refers and expects a particular type of Model.
  • Presenter Model needs a reference to the View.
  • View also has reference to the Presenter which responds to the user events.
  • Presenter has a reference to the view and it populates the View, as opposed to View binding to the Model for every interaction.
  • To decouple, there usually is an abstract class or an interface that View and PM share.
  • Unlike the Presenter, a ViewModel does not need a reference to a view. View binds properties on a ViewModel.
  • The View has no idea that the model class exists.
  • The ViewModel and Model are unaware of the View.
  • Model is completely oblivious to the fact that ViewModel and View exists.
View

Views are often defined declaratively often using a tool or a designer (think HTML or XAML)

  • Views are reponsible to generate the markup, typically using a templating engine or a declarative language (HTML). The views may have conditional coding based on the Model property.
  • Either a different View is used for Edit and Read mode, or same view with conditional logic is used based on model property.
  • View has to expose an interface that can be used by the presenter.
  • Presenter implements this interface and provides the required methods defined in the interface.
  • View uses the interface exposed by the presenter in turn.
  • The view is declarative and contains the data-binding code that refers to the ViewModel.
  • There is a two-way bind and view is always synced with the ViewModel.

Examples you may use in views:

  • Formatting a display field (date string)
  • Showing only certain details depending on state. (only show edit if admin)
  • Managing view animations. (on hover, do something)
Controller or Presenter or

ViewModel

  • Controller or an area is reached through a routing engine which is a set of rules based on the input (URL) or API path in case of AJAX requests.
  • Controller decides which view has to be displayed, based on user input or current state of the user interaction with the application.
  • View sends the input through a url, which is interrupted by the routing engine to route to the appropriate controller.
  • Controller modifies and populates the Model and hands it over to the View.
  • There is typically an action method in a Controller for each user interaction and its variants.
  • The code-behind aspx.cs in asp.net represent the presenter – loosely speaking. The interface in this case will be a page class that is inherited by every aspx.cs file.
  • In the case of composition a Presentation Model may contain one or many child Presentation Model instances, but each child control will also have only one Presentation Model.
  • ViewModel does not need a reference to the View, which promotes loose-coupling and reuse of the same ViewModel for different views. Imagine, same viewModel used for website, mobile application and tablet application.
  • A ViewModel encapsulates the current state of the view as displayed on the screen as well as the various commands or behanviors based on events.
  • A ViewModel may act as an adapter which transforms the raw model data into something that is in the format to be displayed to the user.

Why do we need ViewModels

• Incorporating dropdown lists of lookup data into a related entity

• Master-detail records view

• Pagination: combining actual data and paging information

• Components like a shopping cart or user profile widget

• Dashboards, with multiple sources of disparate data

• Reports, often with aggregate data

Variants:

  • The passive view implementation, in which the view contains no logic. The container is for UI controls that are directly manipulated by the presenter.

 

  • The supervising controller implementation, in which the view may be responsible for some elements of presentation logic, such as data binding, and has been given a reference to a data source from the domain models.

(This is closer to MVVM)

Model

Models are often received from a service or through a dependency injection interface, which has more or less data presented in a format that caters to a larger consumer base than it maps to our UI needs.

  • Model object that you receive from the underlying services are raw and in the format that caters to different consumers of the service.
  • Not the entire model may be used by the view, but just the smaller subset of it.
  • Typically there is a need to collect different models from services into a single model.
  • Typically a domain layer object that contains, domain models, commands and subscription service.
  • Model is typically a server class transformed into a JSON or XML sent over the wire, or for server-side it may be a pre-defined domain class that is more general than what the view requires.
  • In case of undoable operations a ViewModel can refer to the model to restore the original state.
Applications
  • Perfect for web/HTTP, and accomodating of its stateless nature and addressability.
  • Disconnected stateless applications.
  • REST based thin clients as routing is inherent to this pattern.
  • Mobile applications implemented using HTML5.
  • Classic Webforms ASP.NET
  • SmartUI or Rapid App Development.
  • SharePoint webparts.
  • Windows Forms (WPF)
  • Migrating from legacy code, where UI logic is already wired up.
  • Heavy intranet work-flow based applications.
  • State heavy web applications or views.
  • Silverlight or Rich Internet Apps.
  • Windows phone or Android.
  • Highly event driven and stateful UI.
  • Two-way binding.
  • UI where a user interacts with app for a long time before saving the state.
  • Works well where connection between the view and rest of the program is not always available.
Patterns and Practices
  • Front controller

Think of Spring framework.

  • Controller is like the Strategy design pattern.
  • Page Controller

Think ASP.NET aspx pages with a complete Page lifecycle. (Init-Load-Validation-Event-Render-Unload)

  • Presenter acts as a mediator.
  • Observer or Publish/Subscribe (INotificationPropertyChanged, IObserver)
  • ViewModel exposes a Observable.
Framework/Library Client-side:

  • Backbone.js, knockback.js, Spine.js, angular.js.
Client-side:

  • Riot.js
  • GWT
Client-side:

  • Knockout.js
  • Kendo (MVVM)
Server-side:

  • ASP.NET MVC
  • Spring MVC
  • Ruby-on-Rails
Server-side:

  • Classic ASP.NET
  • JSP Servlets
Server-side:

  • WPF (Desktop) or Silverlight
  • Windows Phone apps (XAML)
  • Adobe Flex
Advantages
  • Routing is inherent to this pattern and Controller acts as a mediator of presentation (View) and data (Model).
  • Routing gives the greater control of the application structure and makes it manageable.
  • The abstractions are properly separated, which enables more control over each layer, especially the view which now is clearly separated from the state.
  • Separation helps with testability.
  • The goal of MVP is to separate out the state and behavior out of the View, which makes it easier for legacy sphagetti applications to be migrate to MVP as a first step.
  • Since Presenter model always is written against an interface, it provides a GUI agnostic testable interface.
  • Imposes a consistent interface pattern that developers can follow.
  • Attempts to clearly separate the declarative UI with the business logic.
  • Promote parallel development, where UI developers write the binding and the model and viewModel are owned by application developers.
  • Clearly separates the view logic and makes it dumber with least amount of logic.
  • In practice a website, mobile application and tablet application all need different views, but can share the same viewModel.
  • ViewModel is easier to unit test than event driven code, and leaves the issues of UI automation testing out of the way.
  • ViewModel can be re-used for different representations as it is highly decoupled from the View.
Disadvantages
  • If the model data is coming from the backend, it typically needs some sort of transformation like converting an enum to string, or as complex as calculating number of days from different data property of the model. Slowly the view starts holding more and more logic.
  • Mechanisms like ViewBag/ViewData exist which are abused to substitute the actual need for model, when model size is not large.
  • In practice the Model from the back-end repository is not useable due to different property names or data structure format. A new abstraction of the Model is created and often a pain to map this new ViewModel to the Model and manage changes.
  • The design pattern seems to work against the constraints of the HTTP web, as it demands heavier bandwidth which is not free or unlimited.
  • The view is still tightly coupled compared to MVC.
  • Debugging the events fired from the UI is harder due to its intermingling with the View.
  • It is hard to stick to one of the variants of MVP in all cases, resulting in a mixed code-base.
  • Cannot always be done in parallel as the interfaces need to be defined and agreed upon first.
  • For simpler application it is an overkill.
  • As opposed to MVC, the declarative bindings in MVVM make it harder to debug.
  • Data-binding on simpler controls are more code than data itself.
  • Data-binding implementation keep a lot of in-memory book-keeping.
  • Does View development drive ViewModel or vice versa, makes it harder to communicate.
  • Sometimes criticized as markup and JS code (the data-bindings) are inter-mized. Data-binding un-managed can consume considerable memory.
  • John Gossman points out that generalizing Views for a larger application becomes more difficult.
  • ViewModel is a class that is not a POCO or POJO, but its still worth the effort.
History/Evolution
  • Designed by Trygve Reenskaug in 1979 during his time working on Smalltalk-80 at Xerox-PARC. The definition has evolved heavily during following years.
  • Proposed by Mike Potel from Taligent Inc in 1996. It’s a subsidiary of IBM.
  • Defined by John Gossman at Microsoft in 2005 for use with Windows Presentation Foundation.

References and Further Readings