Reputation: 2411
:)
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
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:
https://martinfowler.com/bliki/PresentationDomainDataLayering.html
Developing GUI Applications. Architectural Patterns Revisited
http://aspiringcraftsman.com/2007/08/25/interactive-application-architecture/
Upvotes: 8