MVC vs MVP vs MVVM with C# examples

iamprovidence
7 min readOct 21, 2022

--

In the beginning, there were nothing. Then the Developer wrote, “Hello world”, and the program started. And Developer saw that the program was good. Customer asked the Developer to add a new feature, so Developer did it. And it was good. The Customer asked to add a new feature once again, what Developer did. Gluttonous Customer asked for another feature, and that is where everything start breaking apart 😁.

Moral of the story: don't add new feature?🤔 No! Learn how to handle complexity.

However, knowing how to handle complexity is not enough. It is also important to know when it starts. Just like, there are no benefits in building a highway when you leave in a village, there is no need for microservices when all you do is CRUD.

Today we will see how architecture evolved. What the difference between family of MV* patterns. And how they applied in DotNet environment.

Core of MV*

The first programs did not have any architecture and basically were aiming to just implement a task. Quickly enough, it resulted in a big ball of mud:

Even in Ancient Rome knew a principle of divide and conquer. And that how our first big architectural pattern was born.

You may heard of MVC pattern before. The idea of it is very blonde: to split business logic from presentation. So you don't end in a situation where your UI support only English and adding another language support, breaks all the business logic. May sound wild to you, but that is an example from personal experience.

MVC got so popular that everybody start using it, with slight differences, adjusted according to their need and capabilities of their framework. For example, MVVM was introduced together with WPF mainly because of binding mechanism. The only differences between those patterns are what stand between Model and View and how arrows are drawn on the diagram.

Give those images a little glance. You will quickly spot that both View and Model are present on all of those. Even though View is how you see your program, the core and most important component here is Model. It is the heart of your application. While View is so fragile that can change every year, Model will always stay the same.

You may come across different terminology. Basically there is two type of Model:

  • Data model — which is just simple dto
  • Domain model (not class!) — your business logic, its concepts and rules

In all of those MV* patterns, M stands for Domain model.

Domain model itself also have several types (actually there are more, but we are interested only in those two):

  • Active model — can fire a domain event of some changes
  • Passive model — does not propagate information about it state

On the all diagrams above, you can see an arrow from Model titled as “Fire events”. It is only valid for Active model. It does not appear much, and for beginner developers (whom I always be) it just make stuff more confusing. So we won’t focus on it. Just ignore that arrow 😃

So, now our simplified image of world have a next look:

Don't think we are talking about some abstraction here. Since I already promised you examples in C#, here you have what a Passive domain model of online store can be:

It is a couple of classes that represents domain behavior. It is a key concept in an all MV* patterns and will remain the same regardless of frameworks.

On the other hand, View is just a user interface. It can vary on framework, so here just a few examples of what view can be: web page, desktop window, console-line interface, REST API and so on.

Now, when everything established, and you can see the similarity, let's have a look at differences of those patterns.

MVC

  • A connecting link between Model and View here is a Controller.
  • The Controller receives an input from View and passes it to Model. Controller can not update View without user interaction.
  • Apply it when view is disconnected from a program. A great example for it would be web page which is separated from server.
  • This pattern is a heavily used by ASP.

In ASP MVC out View likely would be represented as HTML page. User interact with a view by pressing a button. This likely would end up in sending HTTP request from client’s browser to server:

The input passes to the Controller, which manipulates Models:

At the very end we could fire some DomainEvent and send that to a View with SignalR, but there is no reason to make it so complicated. So instead, our Controller simply shows a new View with the data it got from our Model.

When you create a new ASP project you will notice a Model folder contain data models and not domain model. You can not blame Microsoft for that. They were creating a generic template that would suit any domain. To not to leave that folder empty they got to put just anything there. Little did they know what a disservice they will do for entiry developers community. Since there is no place for logic to put in, developers start not only misunderstanding MVC but also writing business logic directly inside controllers. But that’s another story to tell…

MVP

  • A connecting link between Model and View here is a Presenter.
  • Presenter is doing all the same job that Controller did. The only difference here, that with Presenter we have access to view and can update it manually.
  • Use in situations where access to view from program is always present, but there is no binding mechanism.
  • Windows Forms is a perfect example of this.

In WinForms, our View is a just bunch of windows called forms. Which is just a simple class that inherit from Form. User interact with a view by pressing a button, which trigger callback function LoadOrdersButton_Click. Our View has direct reference to Presenter and can pass input without making any HTTP requests:

And our Presenter similarly to Controller manipulates Model. The key point here that it has direct reference to the View as well and can update it whenever it likes, which gives us live experience:

Once again, we could have DomainEvents that would be passed to our Presenter, but we decided to omit that.

MVVM

  • A connecting link between Model and View here is a ViewModel.
  • ViewModel is just like Presenter. It has access to View and can update it. The only difference here that we don't need to do it manually. The update performed by binding mechanism through events.
  • Use in situations where access to view from program is always present and binding is a thing.
  • An example where MVVM is possible is WPF.

As always, let’s start from a view. In WPF view is also a desktop window, but this time represented with xaml files. The user interacts with View by pressing buttons which passes calls to ViewModel, while ViewModel updates it back with event. Mechanism when UI elements are linked to data, called binding:

Our ViewModel is doing the same that Controller and Presenter did. The only difference here is that all the work is done behind the scene, and we don't need to worry about it. In WPF, binding is possible through INotifyPropertyChanged interface. You can implement it yourself, or use a data structure that already did it, like ObservableCollection in our example:

Summary

Of course, that is just the tip of the Iceberg. The evolution of architecture have not stooped here. There are other patterns to investigate, but we already ate a big piece of cake, so you can be proud of yourself. Let’s just stop here for now and see what we learned 😌

As you can see, all MVC, MVP, MVVM patterns are quite similar. They were created to separate view from business logic. The only difference between those, what component stands between View and Model, which is defined by how many access from your program to view there is.

For Active model, we would also have DomainEvents. Those are omitted here, but when you understand the original idea with Passive model, it would not be a struggle for you to enhance those examples.

I hope it was educational for you, and now you can spot a difference between those patterns. If you still can’t, just review those examples once again. Compare what is similar and different between Controller, Presenter and ViewModel.

For your information, I do not claim for academic credibility, just wanted to share my vision, so don't go harsh on me in comment section 😁 Or do if you think I am wrong here 😜

Clap if you got to this point 👋

You can also support me with link below ☕️

And don't forget to follow, if you want to continue this architecture maturity journey with me ✅

--

--

iamprovidence

👨🏼‍💻 Full Stack Dev writing about software architecture, patterns and other programming stuff https://www.buymeacoffee.com/iamprovidence