MVVM Vs MVP Vs MVC
MVVM Vs MVP Vs MVC
MVVM Vs MVP Vs MVC
Those who know me know that I have a passion for software architecture and after
developing projects using Model-View-ViewModel (MVVM), Model-View-Presenter
(MVP), and Model-View-Controller (MVC), I finally feel qualified to talk about the
differences between these architectures. The goal of this article is to clearly explain the
differences between these 3 architectures.
Common Elements
First, the lets define common elements. All 3 of the architectures are designed to separate
the view from the model.
Model
Implementation: Create classes that describe your domain and handle functionality. You
probably should end up with a set of domain objects and a set of classes that manipulate
those objects.
View
Thin layers
They communicate with the model and the view
Implementation:
Every views codebehind implements some sort of IView interface. This interface has
functions like displayErrorMessage(message:String),
showCustomers(customers:IList<Customer>), etc. When a function like
showCustomers is called in the view, the appropriate items passed are added to the
display. The presenter corresponding to the view has a reference to this interface
which is passed via the constructor.
In the views codebehind, an instance of the presenter is referenced. It may be
instantiated in the code behind or somewhere else. Events are forwarded to
the presenter through the codebehind. The view never passes view related code (such
as controls, control event objects, etc) to the presenter.
Implementation:
The views datacontext is set to the ViewModel. The controls in the view are bound
to various members of the ViewModel.
Exposed ViewModel proproperties implement some sort of observable interface that
can be used to automatically update the view (With WPF this is
INotifyPropertyChanged; with knockoutjs this is done with the functions
ko.observable() and ko.observrableCollection())
A class is required to interpret incoming requests and direct them to the appropriate
controller. This can be done by just parsing the url. Asp.net MVC does it for you.
If required, the controller updates the model based on the request.
If required, the controller chooses the next view based on the request. This means the
controller needs to have access to some class that can be used to display the
appropriate view. Asp.net MVC provides a function to do this that is available in all
controllers. You just need to pass the appropriate view name and data model.
MVVM and MVP implementation seem pretty straightforward but MVC can be a little
confusing. The diagram below from Microsofts Smart Client Factory documentation does a
great job at showing MVC communication. Note that the controller chooses the view
(ASP.NET MVC) which is not shown in this diagram. MVVM interactions will look
identical to MVP (replace Presenter with ViewModel). The difference is that with MVP,
those interactions are handled programmatically while with MVVM, they will be handled
automatically by the data bindings.
MVVM
Use in situations where binding via a datacontext is possible. Why? The various
IView interfaces for each view are removed which means less code to maintain.
Some examples where MVVM is possible include WPF and javascript projects using
Knockout.
MVC
Use in situations where the connection between the view and the rest of the program is
not always available (and you cant effectively employ MVVM or MVP).
This clearly describes the situation where a web API is separated from the data sent to
the client browsers. Microsofts ASP.NET MVC is a great tool for managing such
situations and provides a very clear MVC framework.
Final notes
Dont get stuck on semantics. Many times, one of your systems will not be purely
MVP or MVVM or MVC. Dont worry about it. Your goal is not to make an MVP,
MVVM, or MVC system. Your goal is to separate the view, the model, and the logic
that governs both of them. It doesnt matter if your view binds to your Presenter, or
if you have a pure Presenter mixed in with a bunch of ViewModels. The goal of a
maintainable project is still achieved.
Some evangelists will say that your ViewModels (and Presenters) must not make your
model entities directly available for binding to the view. There are definitely
situations where this is a bad thing. However, dont avoid this for the sake of avoiding
it. Otherwise, you will have to constantly be copying data between your model and
ViewModel. Usually this is a pointless waste of time that results in much more code
to maintain.
In line with the last point, if using WPF it makes sense
to implement INotifyPropertyChanged in your model entities. Yes, this does break
POCO but when considering that INotifyPropertyChanged adds a lot of functionality
with very little maintenance overhead , it is an easy decision to make.
Dont worry about bending the rules a bit so long as the main goal of a maintainable
program is achieved
Views
o When there is markup available for creating views (Xaml, HTML, etc), some
evangelists may try to convince developers that views must be written entirely
in markup with no code behind. However, there are perfectly acceptable
reasons to use the code behind in a view if it is dealing with view related logic.
In fact, it is the ideal way to keep view code out of your controllers, view
models, and presenters. Examples of situations where you might use the code
behind include:
Formatting a display field
Showing only certain details depending on state
Managing view animations
o Examples of code that should not be in the view
Sending an entity to the database to be saved
Business logic
Happy coding.