MVVM Experts need your opinion on MVVM and Dataforms - silverlight

as far as I understand the ViewModel should abstract the model from the view and add additional logic to handle the presentation stuff.
My question is:
How would I create a dataform that is suppose to handle user input for an order and details at once.
It should present fields for entering the orders as well as the fields for 1 detail.
My Model would have an object for an order which contains a list of OrderDetails.
How would look my ViewModel for my OrderEntryForm like?
Would I have an OrderViewModel and an OrderDetailViewModel and my
my OrderEntryForm would contain a property of OrderViewModel and one for OrderDetailViewModel? (nesting ViewModels?)
How would validation be handled in this case? Since Validation should go close to the model?
Especially when I work with RIA-Service...
Wouldn't it make more sense to put it in the ViewModel?
How far would you abstract the Model from the ViewModel?
Example:
private DateTime _OrderDate;
public DateTime OrderDate
{
get { return _OrderDate; }
set
{
if (_OrderDate != value)
{
_OrderDate = value;
OnPropertyChanged("OrderDate");
}
}
}
this would mean I have to map the ViewModel-Property to Model-Properties. Cannot leverage Validation-Logic from the Model here...
This example:
public DateTime OrderDate
{
get { return Model.OrderDate; }
set
{
if (Model.OrderDate != value)
{
Model.OrderDate = value;
OnPropertyChanged("OrderDate");
}
}
}
would requiere to pass in a Model. Have the access to the validation logic of the model but also a coupling...
Most examples on the web show dataforms which use ViewModel's that a just a representation of the tables not a real abstraction...
I know and I saw this
stackoverflow.com/questions/744474/combining-net-ria-services-and-mvvm-in-silverlight-3-0
I also read nikhils blogpost on this but this handles also only Products straight mapping from the tables of the database... =(
I know alot of questions...
What are your opinions on that topic?
How would you handle complex dataforms?

Chris,
I have had the same issue and end up implementing it in a crappy way :-( (two vieModels one per view, but passing the parent to the child View... bad stuff).
From my error I learn that next time I would give a try to:
Generate a single ViewModel, but in the child view pass a detail entity in the datacontext (this detail entity does not have to match with the proxy generated entities, maybe is a container of that entities).
Generate a singleton controller class: this class won't be exposed to the view, it will be transparent for the view, just the detail view model will ask the controller for that dependant data instead of going to the DAL.
Not sure if this are going to be clean solutions, have to give a try and fail :).
I agree with you... there are not real samples with this kind of scenarios.
What do you think?
Thanks
Braulio
PS: About validation, if we create our own super entities, we can there define our validation, in my case I have tried as well extending the entities using partial cases and then I can have an entity myPhoneNumberDetail with my special validation.

I personally think there are no hard and fast rules... well, there is one - be pragmatic.
Pragmatically speaking, a view model is a model, and so is a data model. Both are classes, independent of the UI, and surface state as properties, operations as methods, and notifications as events. The thing that I think in my mind differentiates them is how general they are. I see a model as generally usable across multiple views, vs. a view model optimized for a particular view.
I would personally never abstract for the sake of abstracting. I would never surface top-level properties for every model property and implement it by delegating to an underlying model. This increases work. It increases the amount of code to be tested. It requires propagation of metadata, change notifications etc. If there is some actual logic to add, then yes, there would be properties on the view model I'd expose and delegate to the underlying model as appropriate. Even there I'd ask if it is reasonable/appropriate to expose those as computed properties on the model (view model and data model are both models).
As far as surfacing DAL types directly vs. not, that in my mind is somewhat orthogonal. It depends on other factors - how much do you want to abstract the DAL, how useful a DAL type is - for example, if a DAL type has a lot of foreign keys, a presentation model equivalent or projection might be more useful where there is some denormalization done. Sometimes security might be the reason to write a presentation model/projection - eg. I don't want to send email addresses to the client, and instead want an alternate representation of email addresses.
In my sample, I used a DAL type directly, to simplify and not have an overload of concepts in a single sample. I do want to blog about presentation models and projections in a dedicated manner... and so didn't want to mix posts of viewmodel and .net ria services with presentation model concepts at the same time.

As is so often, with patterns, it really depends. The ViewModel can expose the underlying model, and there is no hard and fast rule that says you "must" hide everything and delegate. I have spoken to many folks that are strict adherents to LOD and still they agree that in the case of UI binding, it does not apply.
Now in the case of whether that model is a DTO or not there you will find a lot of differing opinions. Some believe that the only thing that should ever be on the client is a pure projection i.e. a DTO with all logic living on the server, while others believe that that moving entities between the tiers is fine. That would be an discussion for a different post. :-)
In general the guideline that i would recommend is always at least have a high-level VM which can be used for screen state, etc.
As far as child models, like OrderDetail, then if the child model is sufficent to just bind to then just expose it directly. Now one thing to consider is around notification, if you model is not implementing INPC than you may have no choice but to wrap it in order for binding to properly work.
Even if it implements INPC there may be view-specific concerns that that model does not contain, but which are required to for the view to function. In that case I would use simple aggregation and create an OrderDetailVM that directly exposes the underlying OrderDetail and adds additional properties.
For example
public class OrderDetailViewModel
{
public OrderDetail OrderDetail {get;set;}
public bool IsValid {get;set;}
}
Where IsValid is checking some screen-specific logic.
It really depends though on how much encapsulation you want to achieve. I wouldn't find anything wrong with using a delegation model. Depending on the complexity though it might get unwieldy, for example imagine if OrderDetail had additional children, etc.
HTH
Glenn

To clarify, the VM is an abstraction of the Model, not of the View and not the other way around.
You can certainly use multiple VMs to correspond to discrete portions of your View. If you're not going to need separate VMs for Order and Details, you can just have an OrderAndDetialsViewModel that contains everything, and the whole View will bind straight to that. This is where the abstraction comes in.
You are right, that your model's validation logic is going to be distinct from your ViewModel's validation logic, if you put any in there. In no case will the validation be in the View.
I'm not sure I follow your second example. What is the Model object? Your VM may know about the Model(s) from which it is composed, but it is not going to expose it/them as such directly to the View.
I hope this helps somewhat. Please let me know if there is any part of your post that I failed to address.

Related

Brand new WPF Application, MVVM, and how to use POCO partical classes generated from ADO Entity Data Model....?

I've asked this before, but I actually still needed help...
Here's the scenario:
I'm starting a new WPF application, and want to use MVVM. Because our DBA has created a database with tables we need to perform CRUD operations on, I used the Database First approach (ADO.NET Entity Data Model functionality) and got my .edmx, .tt, dbcontext partial classes, etc. created for me.
Now, where do I go from here with the MVVM approach? I do not want to use a framework, and want to get the basics down of MVVM first, before I use external tools. Is there a tutorial anywhere that can help me just get started?
Again, sorry for asking this again, but I really can't find any help, and I have to use the stuff our DBA created.
Your question is really broad, but you might want to start out by deciding how your ViewModels are going to get their data and submit their updates through the EF classes.
While you can bind your EF types directly to your view I've found that a better approach is to keep your ViewModels separate from the ORM model types as much as possible. Model the needs of the View in terms of the behaviours (ICommands) and data (ViewModel props or child ViewModel props or ObservableObjects) apart from the EF types.
Then create a service type that can be injected or instantiated within the ViewModel that will interact with the data model directly and translate the ViewModels into Data Models and vice versa. You can either do that work manually, with LINQ/Lambdas, or using something like AutoMapper to define the relationship between your ViewModels and the data Models (EF Types). This maintains a clear line between the data schema and the ViewModels and I think you'll find changes in the data model having less of a ripple effect on your app this way.
That middle layer that I referred to as a 'service type' might just be some type that exposes a higher level interface than a repository focused more on business operations than on crud operations, but internally makes all the repository or EF calls on behalf of the viewmodels.
If you want to avoid using a framework that's fine, but you still should probably download the MVVM Light core libraries and have a look at what's included. Its pretty lean and will give you the basic nuts and bolts to support MVVM. You can choose to roll your own after that if you wish, but it might not be worth it.
EDIT: Since you said you're short on time...while I don't encourage it, a more expedient but less robust solution might be to just bind your views directly to your EF types as properties of your ViewModels.
// Using the ViewModelBase included in MVVM Light
// which gives you the special Set() method
public class EditCustomerViewModel: ViewModelBase{
public EditCustomerViewModel(){
_currentCustomerCommand = new RelayCommand(SaveCustomer);
}
private Customer _currentCustomer;
private void SaveCustomer(){
using(var ctx = new EfDataContext()){
// Save operation here
}
}
public Customer CurrentCustomer{
get { return _currentCustomer; }
set { Set(()=>CurrentCustomer, ref _currentCustomer, value); }
}
public ICommand SaveCustomerCommand{ get { return _saveCustomerCommand;}}
}
Then in your view you can bind your controls, whatever they may be to the CurrentCustomer properties. You can do your EF save via a command, displayed here as an implementation of the MVVM Light RelayCommand. So, quick and dirty approach could work, but if you can try to abstract the data models away from the ViewModels by presenting the data in types crafted explicitly to to serve the needs of the view.

What is the point of having both Model and ViewModel in M-V-VM?

I always find it tempting to put a model and a view-model together in one class, and I don't see the downside of doing that.
There must be a good reason for separating them. What am I missing?
ViewModel is the soft-copy of the View i.e. if you have a updateable ListBox on View, you will have an ObservableCollection in your ViewModel that represents that list of items in the listbox. Similarly if you have a Button on your View, the VM will hold its Command.
Model will be actually what has the data that the View shows. So the type collection in your VM is of, can be termed as a Model class.
E.g. a Employees ListView is a View, and has a data context which is the instance of EmployeeViewModel class that has an ObservableCollection property of Employee class where Employee class becomes a Model.
Usually there is 1-1 relationship between View and VM and 1-N relationship between VM and Model.
The model is the domain of your application and so contains your domain logic such as business rules and validations. The ViewModel is the model for your view. It handles the interactions between the user and the view, i.e. when the user clicks a button the view model will handle that interaction and may or may not make changes to the model. Normally in an OO language, you want your objects to have a single responsibility only.
In WPF the ViewModel usually implements the INotifyPropertyChange interface which is then observed by the view for any changes. You wouldn't want the model to implement this interface since it is not related to your domain in anyway.
Another reason for separation is that sometimes your view might not necessary show all data that is in the model. For example, if your model exposes 15 properties but in one of your view the user needs to see only 5 of those properties. If you place your model in the ViewModel the view would be exposed to all 15 properties whereas if you encapsulate the model in the ViewModel then only those 5 properties would be exposed to the View.
There are probably many more reasons but in general it is a good design principle to keep them separated. With that being said, if your application is small enough you can get get away with having your model and ViewModel together to reduce redundancy in your code.
The first real downside of doing this is a lack of separation of concerns. And soon this will lead to redundant code. Now, that said, I've seen a lot times where developers have used their Model objects as ViewModels. And if we're totally honest with ourselves, in a very thin app, separating these concepts can actually lead to more redundancy.
The best thing you can do is learn more about MVVM, and its roots in MVC and Presentation Model, but I think it's a great thing that you're asking this question and that you're not blindly following dogma. In fact, I often don't even start with MVVM at all when I begin a small app. I'll often start with a hundred lines or so in the code-behind, proving a concept, and then start refactoring it into MVVM.
More to the point of your question, the model and view-model have - in a conceptual sense - very different purposes. The Model includes your business logic (domain logic), data model (objects, attributes and relationships), and data access layer. The ViewModel is essentially an adaptor for the Model, adapting it for the specific purposes of the View. In some cases you might have 3 different views (and view-models) for a given data model object. Each view-model would be adapting those same attributes on the model object for the specific purposes of that particular view.
My simple answer (and I don't pretend to be WPF Guru) would be that , in WPF, you'd need a VM when:
1. You don't want to expose all your Model to a specific view
2. Your model is not in "WPF style" (doesn't implement INotifyPropertyChanged, no observable collections or no Commands).

One Model Entity, Multiple Pages -> Multiple Views? Multiple ViewModels?

Due to limited screen real estate I will be capturing user input for a single entity using multiple pages (displayed consecutively - think wizard). In my model I expect it is correct to model this entity as a single class.
In an MVVM implementation I am assuming it is best MVVM practice to consider each page as a seperate View. Is this correct?
Is there a consensus on the best MVVM practice for whether each Page has it's own ViewModel or should there be one ViewModel instance that is referenced by the multiple Pages?
To illustrate:
Option 1
Class A (X, Y, Z)
ViewModelA1 (X)
ViewModelA2 (Y)
ViewModelA3 (Z)
View1 captures ViewModelA1
View2 captures ViewModelA2
View3 captures ViewModelA3
Option 2
Class A (X, Y, Z)
ViewModelA (X, Y, Z)
View1 captures ViewModelA.X
View2 captures ViewModelA.Y
View3 captures ViewModelA.Z
The word "View" says it all. It's a view of the data. The ViewModel's job is to make the data coming from the model presentable. Whatever needs to be done to the data happens in the viewmodel so that the view can show it.
Normally you will have a one to one relationship of you view to viewmodels, because normally you only want to show that data in one way. (one "view")
Where I deviate from the normal practice (possibly from MVP pattern?) is that if you want to show the data in a number of different ways (for example you want a bar graph or a line graph, or a pie chart) and the data is the same for all of the views then you only need one viewmodel. Its a case of the DRY principle. If you have three viewmodels and they are all the same, then use one viewmodel. Multiple Views. One viewmodel.
I'm sure there are folks that would argue strongly one way or the other. From my perspective, it all depends on what code you need to re-use. There are both View-centric and Model-centric ways of constructing your ViewModels, and I don't think that either one is always going to be the right approach.
If you find that your ViewModels tend to be heavy on UI-specific logic, a good design will tend towards a 1:1 relationship between Views and ViewModels, with each ViewModel wrapping multiple Models. The danger in this approach is that you can spend a lot of code wiring up the data in each ViewModel and keeping it in sync, and this wiring would need to be repeated across each ViewModel. Uggh.
However, you may also have a situation (as I do in my current project) where the ViewModels have to cope with complex relationships in the underlying model, and where the various Model entities can be updated from multiple endpoints (i.e., either the user or a duplex WCF service). When this is the case, you spend a lot of time in each ViewModel making sure that its data is in sync with the underlying models, and it would be silly to re-do all that logic in each ViewModel. In this scenario, I've found that the cleanest approach is for your ViewModels to map more-or-less 1:1 with models, and to be re-used across multiple views. The downside to this approach is that you can end up with a lot of UI-specific code from various different Views mixed into the same class, and that can make it hard to test and maintain. (Yes, I know that ViewModels are supposed to not be tightly coupled with any specific UI, but you still end up with a lot of code that says, in effect, "When the user executes this command bound to some UI element that I'm pretending not to know anything about, do this other thing that I'm pretending I don't know is going to result in a dialog box being raised." Even at that level of abstraction, the logic coded into the ViewModel can vary from View to View.)
Then there are various hybrid approaches, which are likely the most helpful in real-world scenarios. For instance, you might end up employing an inheritance hierarchy within your viewmodels, so that you deal with the generic wiring in one or more base classes, and then add in the UI-specific pieces in the classes further down the inheritance chain.
For what it's worth, one of my frustrations with most MVVM articles and what-not is that they deal with excessively simplistic scenarios that don't reflect the complexity you find in the real world. As soon as you get past a Customer -> Order -> OrderDetail sort of form, I've found that most of the recommendations I've read tend to breakdown, and I'm left finding my way on my own.
Relevant best practices, regarding MVVM, as I was taught (and practice):
Each page/View has a single ViewModel.
The ViewModel should only have fields/properties relevant to the View that uses them.
ViewModels can be combined from multiple underlying logical Models/classes as appropriate.
The above can end up with more models but they are easier to work with over time as the changes to a single View/ViewModel don't impact other Views or ViewModels
This matches your first option.
In an MVVM implementation I am
assuming it is best MVVM practice to
consider each page as a seperate View.
Is this correct?
Yes, I would do so depending how complex is it. I think that MVVM for most of the WP7 apps is just an overkill.
Option 1 is the better model to use.
I am not sure what you mean with the X, Y and Z.
You should simply pass the same instance of the model to each ViewModel
Class Model
{
string X { get;set;}
string Y { get;set;}
int Z { get;set;}
}
Class MainViewModel
{
// constructor
ViewModel()
{
model = new Model()
SubViewModel = new SubViewModel(model);
}
Model model {get;set;}
SubViewModel sub { get;set;}
}
Class SubViewModel
{
// ctor
SubViewModel(Model model)
{
this.model = model;
}
Model model { get;set;}
}
The MainViewModel handles navigation between each SubViewModel, but they are all looking at the same instance of the Model, so they all have the same data.
On some Tasks I may have multiple models associated with a single ViewModel and multiple views for that Task. For Example, Creating a product with grouping, images, etc.. Focused around the product.
I also have Tasks where multiple ViewModels are used driven by the Task through multiple Views. For Example, Creating a User account in the application with a mashup of multiple 3rd party accounts like Facebook, Twitter, etc where each 3rd party API has it's own set of requirements but appears as a single Task to the user through a series of steps. Focused around the User account.
MVVM pattern is flexible dependant on the need. Define the task, break it down, and decide on which best suits the task.
Look, what are you asking is this:
I have 1 M.
I have 3 Vs. (Assuming that it's preferable for you to create 3 Vs).
Should I have 1 VM or 3 VMs ?? In other words you ask, in which side the VM concept is closer ? On the M or the V side ?
From my experience thus far with the pattern, the VM is MUCH more closely related to the V.
So the quick answer to your question is: 3 VMs (Option1). Option 2 is the wrong way to think of this pattern.

Grids with ViewModels - WPF

Sorry if this has already been asked, but I just want to make sure that I'm doing this right.
If I have a domian object that has say 10 properties on it. I have a grid on my main form that I want to show the pretty much all the the properties from the model.
I created a viewmodel to wrap the domain object to show in the gridview but then I have to expose all the properties again. I just feel binding straight against the model through the viewmodel feels dirty and defects the purpose a bit.
So for example I don't really like this:
{Binding DomainObject.Property}
where DomainObject is property on my view model.
So my main question is, should I expose all the properties on the model through the view model just to bind it to the grid?
EDIT: Just for added information the domian objects are LINQ-To-SQL objects, so I don't think they implement INotifyPropertyChanged but I'm not sure.
Some people will say it doesn't matter, others say it does. I'm in the latter camp, for these reasons:
You increase the dependencies of the view, as it now depends on the data model, not just the view model.
You require the designers need to know the properties and structure of your data model.
You create more work for the (almost inevitable) refactoring when you decide you need a layer of indirection for formatting, validation, or whatever it might be.
As Thomas pointed out, data models often don't implement change notification
Yes, it's a little more work, but I believe it's worth it to reduce decoupling, maintenance headaches, collaboration with designers, and correctness.
PS. If you find yourself in this situation a lot, you might consider an implementation of ICustomTypeDescriptor that wraps any data object and exposes its properties with change notification. That way your VM can extend this generic wrapper until you decide you need to pull properties out for purposes such as formatting and validation.
If you need change notification on the properties and the model doesn't implement INotifyPropertyChanged, then you need to create new properties on the ViewModel. Otherwise, it's probably not a big issue to bind directly to the model : the MVVM pattern is just a guideline, you can bend the rules a little if necessary...
I think it is a matter of personal preference. I happen to believe it is perfectly fine to expose the Model in a single object from the ViewModel. Recreating all the properties of the Model in the ViewModel just results in a bunch of extra code.
However, this only works provided your Model implements change notifications so the data binding works.

The model in MVVM: business object or something else?

I'm trying to get to grips with MVVM and so I've read a bunch of articles - most focus on the View -> ViewModel relationship and there's general agreement about what's what. The ViewModel -> Model relationship and what constitutes the Model gets less focus and there's disagreement. I'm confused and would like some help. For example, this article describes the Model as a business object whereas this article describes a class which manages business objects. Are either of these right or is it something else?
I think you are on the right track. The "model" is vague in a lot of cases because it is different things to other people, and rightly so.
For me, my business objects that come back from my WCF service I consider my model. Because of this my projects don't have that pretty file structure with the holy trinity of namespaces: *.Models, *.ViewModels, and *.Views. I personally consider objects coming back from business logic or anything of that nature the "model".
Some people tend to lump both the business objects and the business logic together and call that the "Model", but I find that a little confusing because I picture a Model to be sort of more static than I do business logic, but it's semantics.
So when you look at examples of MVVM projects and don't see anything very clearly "Model", it's just because folks treat them differently. Unless an application is very standalone, I would actually be very suspicious of an application with an actual *.Model namespace, to be honest.
The other thing that is great here is that many times you already have an investment in these types of business objects and I think a lot of people see "MVVM" and immediately assume they need to start defining the "M", even though what they already have is perfectly fine.
The confusion between a Model and a ViewModel is pretty common, too. Essentially I know I need a ViewModel if I need a combination of data and behavior. For example, I wouldn't expect INotifyPropertyChanged to be implemented on a Model, but I would a ViewModel.
From the other answers it should be obvious that the relationship between ViewModel and Model is somewhat fuzzy. Be aware that there is nothing stopping you from having ViewModel and Model in the same class, and when your requirements in a particular area are simple enough maybe this is all that you need!
How you structure the separation between ViewModel and Model will very much depend on the needs of the project or software that requires it, how demanding your deadlines are and how much you care about having a well structured and maintainable code base.
Separating ViewModel and Model is simply a way of structuring your code. There are many different ways of structuring your code, even within this pattern! It should be no surprise then that you will hear different approaches preached by different programmers. The main thing is that the separation can help to simplify and make reusable the independent portions of code. When you have cleanly separated business data, business logic and presentation logic you can easily mix, match and reuse your views, logic and data to create new UIs. The separated and simplified code is also often easier to understand, test, debug and maintain.
Obviously not everyone will agree with this answer. I think that is part of the inherent fuzziness of the problem. In general you need to consider and trade-off the advantages versus the costs of having a separation between ViewModel and Model and know that it is not always a simple task to decide what goes in the ViewModel and what goes in the Model. It will probably help to lay down some ground rules that you or your organisation will follow and then evolve your rules as you understand which level of separation best suits your problem domain.
I think it is worth mentioning that I used to use a similar approach to MVVM when programming Windows Forms and the fact the WPF has more direct support for this (in the form of data binding and commands) has really made my day.
There are a lot of different implementations and interpretations.
In my mind, however, the value of the ViewModel comes from coordination.
The Model is representative of business data. It encapsulates scalar information, as opposed to process.
The View is obviously the presentation of the model.
The ViewModel is a coordinator. In my opinion, the job of the view model is to coordinate between the view and the model. It should NOT contain business logic, but in fact interface with business services.
For example, if you have a view that is a list of widgets, and the widgets are grabbed from a service, then I'd posit:
The Model is a List<Widget>
The View is a ListBox bound to the ViewModel property Widgets
The ViewModel exposes the Widgets property. It also has a IWidgetService reference it can call to in order to get those Widgets.
In this case, the view is coordinating with a business object so the view doesn't have to know anything about it. The model should be ignorant of view models, views, and every thing else ... they should exist independent of how they are used. The IWidgetService would get bound to the view model using some source of dependency injection container, either constructor injection with Unity or an import using MEF, etc.
Hope that makes sense ... don't overload your viewmodel. Think of it as a coordinator that understands business objects and the model, but has no knowledge of the view or how business process is performed.
The value added by the model is its decoupling from the ViewModel and the View. Think if you had to construct and maintain business logic in the ViewModel you would have lots of duplicate code.
For instance - if you had a car game with a GearBoxView (a control in the CockpitView), CarViewModel and CarModel - the advantage of abstracting what is in the CarModel from the CarViewModel is that the CarModel can be used in the WorldViewModel and any other ViewModel. The CarModel can have relationships with other Models (GearsModel, WheelModel, etc).
Your question specifically asked about using a Model as a business object or to manage business objects: my answer is it can do both - and should be responsible for both.
Heres an example
public class WorldModel //Is a business object (aka game object)
{
private List<CarModel> _cars;
public List<CarModel> Cars
{
get //Here's some management of other business objects
{
//hits NetworkIO in a multiplayer game
if(_cars == null)
{
_cars = myExternalDataSource.GetCarsInMyGame();
}
return _cars;
}
}
public Level CurrentRaceCourse { get; set; }
public CourseTime TimeElapsed { get; set; }
}
I think of the model as something that contains the smallest units of business entities. The entities in the model are used not only across the view models in my application but even across applications. So one model provides for many applications and, for those applications using MVVM, many view models.
The view model is an arbitrary collection of entities from the model that are brought together to serve whatever the view needs. If a view requires 2 of these and 1 of those, then its view model provisions them from the model. Generally, I have 1 view model per view.
So a model is like a grocery store. A view model is like a shopping cart. And a view is like a household.
Each household has unique requirements. And each household has its own shopping cart that cherry picks what the household needs from the grocery store.
My thoughts
(The "Model")
Have one model. Just data no methods (except if apt for the platform some -simple- getters/setters).
(The "View Model")
To my mind the rationale for a view model is:
(1) to provide a lower-RAM-requirement backup copy of fields so views hidden behind other views can be unloaded and reloaded (to conserve RAM until they reappear from behind views covering them). Obviously this is a general concept that may not be useful or worthwhile to your app.
(2) in apps with more complex data models, it is less work to lay out all application fields in a view model than to create one reduced model corresponding to the fields of each possible data change, and easier to maintain, and often not significantly slower performance wise.
If neither of these apply, use of a view model is inapt in my view.
If view models are apt, have a one to one relationship of view models to views.
It may be important to note/remind/point out that with a lot of UI toolkits if the exact same "String" object is referenced twice (both in the model and the view model) then the memory used by the String object itself is not double, it is only a little more (enough to store an extra reference to the String).
(The "View")
The only code in the view should be (the required) to show/hide/rearrange/populate controls for initial view load and (when user is scrolling or clicking show/hide detail buttons etc) showing/hiding parts of the view, and to pass any more significant events to the "rest" of the code. If any text formatting or drawing or similar is required, the view should call the "rest" of the code to do that dirty work.
(The "View Model" revisited)
If the (...facts of which views are showing and...) the values of view fields are to be persistent ie survive app shutdown/restart, the view model is part of the model :--: otherwise it is not.
(The "View" revisited)
The view ensures that the view model is as synch'ed with the view in terms of field changes as is appropriate, which may be very synched (on each character change in a text field) or for example only upon initial form population or when user clicks some "Go" button or requests app shutdown.
(The "Rest")
App start event: Populate the model from SQL/network/files/whatever. If view model persistent, construct views attached to view models, otherwise create initial view model(s) and create initial views attached to them.
On commit after user transaction or on app shutdown event: Send model to SQL/networkl/files/whatever.
Allow the user to ("effectively") edit the view model through the view (whether you should update the view model on the minutest change of a character in a text field or only when the user clicks some "Go" button depends on the particular app you are writing and what is easiest in the UI toolkit you are using).
On some application event: the event handlers look at the data in the view model (new data from the user), update the model as required, create/delete views and view models as required, flush the model / view models as required (to conserve RAM).
When new view must be shown: Populate each viewmodel from the model just after the viewmodel is created. Then create view attached to view model.
(Related issue: what if any data set primarily for display (not editing) should not be entirely loaded into RAM?)
For sets of objects that should not be entirely held in RAM cause of RAM use considerations, create an abstract interface to access information on the overall count of objects and also to access the objects one at a time.
The interface and its "interface consumer" may have to deal with the number of objects being unknown/estimated and/or changing depending on the API source providing the objects. This interface can be the same for the model and the view model.
(Related issue: what if any data set primarily for editing should not be entirely loaded into RAM?)
Use a custom paging system through a slightly different interface. Support modified bits for fields and deleted nits for objects - these kept in the object. Page unused data out to disk. Use encryption if necessary. When editing of set done, iterate it (loading in pages at a time - one page can be say 100 objects) and write all data or only changes in transaction or batch as appropriate.
(Conceptual significance of MVVM?)
Clean platform-agnostic way to allow and lose data changes in views without corrupting model; and to allow only validated data through to the model which remains as the "master" sanitised version of data.
Crucial to understanding the why is that flows from view model to model are conditional on data validation of user input whereas flows in the opposite direction from model to view model are not.
The separation is achieved by placing code that knows about all three (M/V/VM) into a core object responsible for handling application events including startup and shutdown at a high level. This code necessarily references individual fields as well as objects. If it didn't I don't think easy separation of the other objects can be achieved.
In response to your original question, it is a question of degree of interrelationships of validation rules on update of fields in the model.
Models are flat where they can be but with references to submodels, directly for one-to-one relationships or through arrays or other container objects for one-to-many relationships.
If the complexity of validation rules is such that merely validating a successful user form fill or incoming message against a list of field regular expressions and numeric ranges (and checking any objects against a cached or specially fetched copy of relevant reference objects and/or keys) is enough to guarantee that updates to business objects will be 'with integrity', and the rules are tested by the application as part of the event handler, then the model can just have simple getters and setters.
The application may perhaps (best) do this directly in-line in event handlers where the number of rules is so simple.
In some cases it may be better even to put these simple rules in the setters on the model but this validation overhead is then incurred on database load unless you have extra functions for setting without validate. So for simpler data models I tend to keep the validation in application event handlers to avoid writing these extra setters.
But if the rules are more complex either:
(a) a single method taking a special object that is really a composite of the usual business objects containing data for myriad field changes is written for each complex model change, and the method can succeed or fail depending on validation of the rules - facade pattern;
or
(b) a "dry run" / hypothesis / "trial" copy of the model or a subset of the model is created first, setting one property at a time, and then a validation routine run on the copy. If validation is successful, the changes are assimilated into the main model otherwise the data is discarded and an error raised.
The simple getter/setter approach is in my view preferred when analysing each individual transaction unless the vast majority of updates for your app are complex, in which case one can use the facade pattern throughout.
The other way the model ends up getting more complex than a bunch of fields with (possibly) simple getters/setters is if you start "enhancing" classes' getters/setters (with an O2R mapper tool), or adding extra aspects like calls to transaction monitoring APIs, security APIs (to check permissions, for logging etc), accounting APIs, methods that pre-fetch any related data needed for a get or set, or whatever upon get or set. See "aspect-oriented programming" for an exposition on this area.

Resources