R – Does MVVM violate DRY

design-patternsmvvmwpf

It seems that ViewModels that I make look suspiciously like other classes and they seem to require a lot of code repetition, e.g. in a current project I have:

  • SmartForm: Model that represents a data form to fill in, has properties:
    • IdCode
    • Title
    • Description
    • collection of SmartFormFields
    • etc.
  • SmartFormControlView View
  • SmartFormControlViewModel ViewModel
    • IdCode
    • Title
    • Description
    • collection of SmartFormFields
    • etc.

So my ViewModel is basically the same as my Model, just with all the OnPropertyChanged features for binding with the View.

It seems as I refactor and extend this that every little change I make to my model, I have to make a mirror change to the ViewModel.

This seems to violate a basic rule of patterns Don't Repeat Yourself.

Am I implementing the MVVM pattern incorrectly or is it just an inherent characteristic of MVVM that there is always a 1-to-1 repetition going on between Model and ViewModel?

Best Solution

I personally don't think it violates DRY since the model and view-model (I prefer the term presenter) don't point to the same information. For instance your VM and M both have a Title property, but your VM's Title property could also include validation, whereas your model's Title property could assume validity.

While it's true that The VM may contain all of the properties of the model, there is also the possibility of having validations (e.g. Title must be non-blank), data-dependencies, bindable UI-specific properties (icons, colors, brushes, etc.) which aren't part of the view.

Essentially all UI patterns have similar "duplication" in the way you state it: namely cascading modifications. Try changing a model in MVC without changing the controller.

That being said, MVVM (or any UI pattern designed to separate UI, logic, and state) can be overly tedious for simple cases such as your example. When logic becomes little more than state-pass through, the value separating the controller/presenter/view-model decreases.

In your specific case, if there really isn't any logic, validation, or UI specific properties that your VM isn't surfacing, and your model doesn't have to be persisted, serialized, or made backwards compatible with an existing structure (or adding the logic to do so in your VM is trivial), I would strongly consider combining the M and VM to avoid creating properties whose sole purpose is to get/set the underlying model's properties.