Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clarification and naming convention for Model and ViewModel in MVVM

Tags:

c#

mvvm

xaml

I'm confused in what should be a model or a view model and how should these be named.

For simplicity sake, I'll leave the INotifyPropertyChange out of it.

The following class is clearly a model:

class CountryModel
{
    public string Name { get; set; }
    public string Location { get; set; }
}

What you mostly see on the web is that a view model would be defined as follows:

class CountryViewModel
{
    public CountryViewModel
    {
        // initialize data (not ideal place, I know, but keeping it simple!)
    }

    public ObservableCollection<CountryModel> Countries
    {
        private get;
        set;
    }
}

Why isn't the above a model of Countries, i.e. CountriesModel, for example? Why is it considered a view model?

Should that technically be the case? Should we have another class for the view model, then?

class CountryViewModel
{
    private ObservableCollection<CountryModel> _countries = new ....;

    public CountryViewModel
    {

    }

    public ObservableCollection<CountryModel> Countries
    {
        private get { return _countries ?? _countries = LoadCountries(); }
        set { _countries = value; }
    }

    private ObservableCollection<CountryModel> LoadCountries()
    {
        ObservableCollection<CountryModel> countries = new ...;
        foreach (CountryModel country in CountriesModel)
        {
           countries.add(country);
        }
        return countries;
    }
}

Is the above making sense? I just don't understand why it seems to be a standard and why you would call CountriesViewModel when to me it should be CountriesModel and a CountryViewModel should be created accessing the data from the CountriesModel.

Also, if you stick to what's on the web, i.e. CountryModel and CountryViewModel that contains an observable collection of CountryModel, then how would you deal with countries containing each a list of cities? I would have a CityModel as a POCO and then for the list of cities, I would create a CityViewModel having an observable collection of CityModel.

But then what? Am I supposed to make the CityViewModel part of my CountryModel? That doesn't seem right at all! Maybe it is and someone could clarify that. This is where I get confused even more as I would have created a CountryModel with properties Name, Location and a property of type List<CityModel>, but how do I represent this correctly in MVVM?

How to define this correctly? Especially the part where you have a list of objects and each of those objects contains another list. Which is a model, a view model and how do I handle the list inside my model?

like image 573
Thierry Avatar asked Sep 07 '13 04:09

Thierry


People also ask

How do you name a ViewModel?

Naming Conventions for Name of a Type“ViewModel” is simply added to a “Page”-suffixed name to yield the name of its ViewModel. However, only “Model” is added to a “View”-suffixed name to yield the name of its companion ViewModel.

What is the ViewModel in MVVM?

The ViewModel is a model for the View of the app: an abstraction of the View. The ViewModel retrieves the necessary data from the DataModel, applies the UI logic and then exposes relevant data for the View to consume.

What is the role of ViewModel?

ViewModel is a class that is responsible for preparing and managing the data for an Activity or a Fragment . It also handles the communication of the Activity / Fragment with the rest of the application (e.g. calling the business logic classes).

What goes in a ViewModel?

ViewModel: A class that exposes the model as a public property so that the view can bind to it. It should contain methods that interact with the model. It could also contain properties of it's own.


1 Answers

Typically, people make a view model for every view they have in their system. The purpose of the view model is to facilitate the view's data. View models are usually a flattened version of their domain model counterparts, but this can seem confusing when you have flat domain models that are really just data transfer objects (DTOs). Do not be afraid to have view models that closely resemble a domain model; they are different abstractions of the data intended to live and work in different areas/layers of your application.

As for your questions/examples, if you had a view in your application that represented countries and cities in a hierarchical nature then yes it would be perfectly acceptable to have a CountryViewModel that was composed of a CityViewModel, along with any other view models that helped comprise the data for that particular view. It is also possible to use inheritance in view models so that you could have base view model class that held error information for anything that went wrong, such as issues retrieving the data, issues mapping the data or issues validating the data.

Since you will generally want to have a view model per view in your application, you many times end up with a set of view models that match the CRUD operations for your domain model object. For instance, say you have an Account domain model, then you would probably have a CreateAccountViewModel, DisplayAccountViewModel, DeleteAccountViewModel and UpdateAccountViewModel.

Many people get concerned with duplication in their code and think that it is wrong to have a domain model and view model that are almost identical in structure and data types, but remember that they serve very different purposes; domain models exist to facilitate the data for the problem space you are working in, while view models exist to facilitate the data for displaying information to the user in a view.

It is also not unheard of to have a data model class in a data-access layer that differs from the domain model, but mirrors the structure of the data being retrieved from a database table. This is how you can use a micro-ORM like Dapper. Instead of writing the ADO.NET DataReader mapping logic, you create a data model class that matches the column names in the query you use to retrieve the data from the database and then use that class as the object to "dump" the data into. From there you could have mapping logic to build a domain model class that gets passed back down the layers of your application.

like image 197
Karl Anderson Avatar answered Oct 26 '22 23:10

Karl Anderson