Currently, I am developing a WPF application that adheres to the MVVM (Model-View-ViewModel) pattern. The application already includes some view code that presents a user interface by implementing DataTemplate for various Model classes. To ensure a proper separation of concerns and to prevent the View from directly knowing about the Model, I decided to create wrapper classes for these Model classes within the ViewModel.
However, I am now faced with a design decision regarding the implementation of the ViewModel class. Specifically, I need to determine whether the ViewModel should be a completely new class or if it should implement an existing interface or abstract class from the Model.
If I choose to implement an interface or abstract class from the Model in my ViewModel, does this imply that the View will have some level of awareness about the Model? Is this approach aligned with the principles of the MVVM pattern, or does it violate the separation of concerns?
To encapsulate some logic within the ViewModel, I am considering a constructor in the ViewModel that accepts an instance of a Model class and is marked with internal access. Will this design choice impact the testability of my code? How can I ensure that my ViewModel remains testable if such internal constructors are used?
In my application, I have a Model with a hierarchy of classes:
Square
, Sphere
, Cube
, and Ellipse
, all derived from a base class FigureBase.There are also various other classes that work with FigureBase.
In total, there are over 20 classes derived from FigureBase, each with unique properties that need to be modified through the UI using DataTemplate
and then saved/serialized for future use.
Should the View code directly create a DataTemplate for each Model class such as Square, Ellipse, etc., or should each of these classes have a corresponding ViewModel wrapper like SquareWrapper
which implements INotifyPropertyChanged
and handles serialization logic?
If I choose to implement an interface or abstract class from the Model in my ViewModel, does this imply that the View will have some level of awareness about the Model?
The view will always have some level of awareness of the model, since it is intended to present data from the model to the user. So there will by necessity be some level of coupling between the model and view.
Is this approach aligned with the principles of the MVVM pattern, or does it violate the separation of concerns?
The pattern specifies a separate model and view model, so it seem difficult to argue that it does not goes against the pattern.
But as with any pattern it is a good idea to think about what problem it is intended to solve and when and where it is applicable. The view model tend to be full of things like handling and presenting errors, dealing with translations, verifying input etc. So it usually make sense to separate these concerns from the concerns of the model. There is also a general recommendation of composition over inheritance that highlights some of the problems of overuse of inheritance.
But it is perfectly possible that these concerns are not relevant for your particular use case. Perhaps there are no input verification, translations or error handling to worry about? Perhaps this is a short lived application where maintainability is less important?
In the end I would recommend using a separate model and viewmodel, but do not bend over backward just to fulfill some design pattern. Think about what you are doing and why, talk with your colleges, and do whatever you think is best for your particular situation.