2

I'm learning the MVVM pattern and something that comes up often is a duplication of data-types.

Say I have a Person datatype. Intuitively I want it to look like this:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public uint Age { get; set; }
}

But instead, the code will have a PersonViewModel a PersonModel class and in many cases there's also a PersonData class which is used for serialization.

A PersonViewModel inherits from a base class for ViewModels and the setters will have RaisePropertyChanged calls.

public class PersonViewModel: ViewModelBase
{
    private string _firstName;

    public string FirstName
    {
        get
        {
            return _firstName;
        }
        set
        {
            _firstName = value;
            OnPropertyChanged("Person");
        }
    }
    ...
}

A PersonModel does not call OnPropertyChanged and does not inherit from ViewModel. Also one of the reasons for this is to not bind the view to the model directly, rather to bind it to a ViewModel.

A PersonData will have the same properties but they'll be marked with the DataMember attribute and the class will have the DataContract attribute.

I have 2 questions:

1) Is it really necessary to have so many classes for the same data type? They usually have the exact same properties. Is it not better to just have one class per data type?

2) One of the problems is that changing one class requires you to change the other classes as well. I thought about using an interface that looks like this:

public interface IPerson
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public uint Age { get; set; }
}

and have the 3 classes implement the interface. If indeed all these classes are necessary is it a good solution for the consistency problem?

3) Is the distinction between "Model" and "ViewModel" really necessary in the data-types level? Sure I can understand why it's a good idea to have one unit of code be responsible for invoking commands, presenting data, etc... and have another unit of code be responsible for the business logic, but is it really necessary when we're dealing with data types that are being used across the entire codebase?

  • The PersonViewModel is there for the benefit of the PersonView. The public properties exposed on that ViewModel are those required by the view itself, some or all of which may or may not correspond to the properties in the PersonModel or the fields in the database. – Robert Harvey Apr 24 at 15:58
2

CRUD operations in MVVM do seem unnecessarily redundant, don't they? But the situation changes when actual business operations are involved.

Let's have a look at a different problem domain.

public class Invoice
{
    public Address BillingAddress { get; set; }
    public Address ShippingAddress { get; set; }
    public List<InvoiceItem> Items { get; set; }
    public double Shipping { get; set; }
    public double Tax { get; set; }
}

In this example Address, Invoice and InvoiceItem are all tables in the database, so you would need three classes to represent those. The fields exposed on the InvoiceViewModel would more closely resemble those of the class above.

Do you need all of these classes? Yes, you do. The whole point is to promote separation of concerns. The ViewModel should only expose those fields that are needed by the View. The View should not have to concern itself with what the database looks like; that is the job of the ViewModel and the underlying Model.

1

You shouldn't be afraid of not following DRY when it comes to data. Its actually a antipattern not to duplicate the data classes. Your read model should not be a 1:1 mapping to your database or datasource.

It should be mapped so that it supports the use case. So lets sayu your database entity is

public class Person 
{
   FirstName
   LastName
   SocialSecurityNumber
   Age,
   SomeListOfRelatedData
}

Lets say your use case is that you should cancel all subscriptions to people under 18 because of new regulations. They want a list of name and the persons age.

That view should be served a custom model only holding the data needed for this specific use case. This grows more important for larger and more complex systems.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.