Nikolay Marinov
Nikolay Marinov

Reputation: 2411

(MVVM) View Model per View or per Model?

:)

I’ve watched and read lots of MVVM materials during the past few weeks and there seems to be a major difference which everybody does in one way or another but doesn’t elaborate upon. Do we create a ViewModel per View or per Model?

There’s a question for it, but I don’t think its answered thoroughly. So..

Let’s use a Recipes app for example where we have three different views: RecipesViewController, RecipeViewController and RecipeCell. I think that the correct way to implement MVVM is to create one ViewModel per view instead of creating a RecipeModel and sharing it across them.

This example may be basic enough and we may prefer one ViewModel, but it’s not correct, is it? And if both are acceptable, can someone explain the differences, drawbacks & benefits? And if we have a networking layer, only the ViewModel should communicate with it, right?

Thank you.

Upvotes: 2

Views: 2059

Answers (1)

expandable
expandable

Reputation: 2290

Patterns and architectures can be hard to understand when people do think in the correct way to do implement them.

They are just guidelines. They give you separation of responsibilities and you as a developer decide how to apply them based on your problem. Doing them one way can be harder then doing them the other way and that's pretty much it.

There is not way for a pattern to solve all the problems that you going to have.

From practice people have found out that in most cases its better for a View to communicate with a single ViewModel. My experience has proven that this indeed makes your logic cleaner as a change in couple of ViewModel can break a single View and debugging and tracing what is happening can be harder. If you do need to share some state and/or logic between Views that belongs to a single ViewModel think think how you can have two ViewModels instead of one and add a Model to share that state and logic and have ViewModels share that object.

A ViewModel can communicate with multiple Views (while every View has a single ViewModel). Most of the time if you can make a single ViewModel to communicate with a single View them do it. It makes things easier.

For complex interrelated logic sometimes having a single ViewModel per View can be harder to do. Usually you will divide your ViewModel in hierarchy where you will have one ParentViewModel and couple of smaller finer grained ChildViewModels. But these ChildViewModels may have to communicate with their parent or between each other. By breaking ViewModels into hierarchies you can achieve the single ViewModel for View, but if you can't don't force yourself. Sometimes it's simpler to not do it.

At least don't start by trying to have a single ViewModel for View. Use iterative approach and refactoring. Make one larger ViewModel and hook it to different Views. Later refactor your way towards breaking the MainViewModel into smaller ones and trying to make them communicate with less views possible.

Sharing one Model between ViewModels is perfectly fine. I think that Models are probably the thing that is underused. People do try to add more logic to the ViewModels creating coupling between them while they should use Models instead.

One important thing you need to think about is the division of Presentation and Model. Work more on your Model and you will see great benefits.

If your example you should have a Recipe model as Recipe is your DomainModel and should have data and behavior related to a recipe. Then you will have a RecipeViewModel and is part of your Presentation and has the presentations logic for a Recipe. Then you will have your RecipeView that will be hooked to a RecipeViewModel that has the responsibility of having the actual GUI widgets that represent how a Recipe is Presented to the user and react and adjust it's widgets/controls to changes in RecipeViewModel.

In MVVM, Views usually don't communicate with Models. They do communicate with ViewModels that then communicate with Models.

One big issue that I see is that people treat Models as the thing that they store to the database and everything else (Views, ViewModels, Services etc.) as the application. That is a big flaw. If you haven't read Domain Driven Design I highly recommend it as it explains in great details the value of having good Models.

Here are some resources:

Upvotes: 8

Related Questions