After doing a few Projects using the MVVM Pattern, Im still struggling with the Role of the ViewModel:
What I did in the past: Using the Model only as a Data Container. Putting the Logic to manipulate the Data in the ViewModel. (Thats the Business Logic right?) Con: Logic is not reusable.
What I'm trying now: Keeping the ViewModel as thin as possible. Moving all Logic into the Model Layer. Only keeping presentation Logic in the ViewModel. Con: Makes UI Notification realy painful If Data is Changed inside the Model Layer.
So I will give you an Example to make it more clearer:
Scenario: Tool to Rename Files. Classes: File : Representing each File; Rule: Contains Logic how to Rename a File;
If Im following approach 1: Creating a ViewModel for File, Rule and the View -> RenamerViewModel. Putting all Logic in the RenamerViewModel: Containing a List of FileViewModel and RuleViewModel and the proceeding Logic. Easy and fast, but not reusable.
If Im following approach 2: Creating a new Model Class -> Renamer, which contains a List of File, Rule und the proceeding Logic to interate over each File and apply each Rule. Creating a Viewmodel for File, Rule and Renamer. Now the RenamerViewModel only contains an instance of Renamer Model, plus two ObservableCollections to wrap the File und Rule List of the Renamer. But the whole Logic is in the Renamer Model. So if the Renamer Model is triggered to manipulate some Data by Method Calls, the ViewModel has no Clue which Data is manipulated. Because the Model doesnt Contain any PropertyChange Notification and I will avoid that. So the Business and Presentation Logic is seperated, but this makes it hard to notify the UI.
Putting business logic inside the viewmodel is a very bad way to do things, so I 'm going to quickly say never do that and move on to discussing the second option.
Putting the logic inside the model is much more reasonable and it's a fine starting approach. What are the drawbacks? Your question says
So if the Renamer Model is triggered to manipulate some Data by Method Calls, the ViewModel has no Clue which Data is manipulated. Because the Model doesnt Contain any PropertyChange Notification and I will avoid that.
Well, making your model implement INotifyPropertyChanged
would certainly let you move on to better things. However, it's true that sometimes it is not possible to do that -- for example the model may be a partial class where properties are auto-generated by a tool and don't raise change notifications. That's unfortunate, but not the end of the world.
If you want to buy something then someone has to pay for it; if it's not the model that gives such notifications then you are left with only two choices:
The first option is again a bad idea, because in effect it is going back to putting "business logic" inside the viewmodel. Not as bad as putting all the business logic in the viewmodel, but still.
The second option is more promising (and unfortunately more work to implement):
For more information on such an implementation see also my answers here and here.