MVVM: An alternative approach on how to implement the Model-View-ViewModel pattern

Jul 3, 2009 at 11:45 AM

Most implementations of the Model-View-ViewModel (MVVM) pattern show that the ViewModel encapsulates the Model. The View works on the ViewModel but isn’t allowed to collaborate directly with the Model.
=> One ViewModel object per Model

An alternative view of this pattern sees the ViewModel as abstraction of the View.
=> One ViewModel object per View

The “Model-View-ViewModel Pattern” article describes the alternative approach.

Code examples can be found on the WPF Application Framework project site: http://waf.codeplex.com
 

What do you think of this alternative approach?
 

Jul 6, 2009 at 3:03 PM

The very definition of MVVM is that the ViewModel is an abstraction of the View.  None of the knowledgable MVVM advocates have made the claim that the View should never directly access the Model, though there are good reasons to prefer not doing so.  In any event, it's highly unlikely there will be a one-to-one relationship between the ViewModel and the Model.  Heck, it's possible there won't even be a one-to-one relationship between the View and the ViewModel, though that's far more likely.  Some comments on the "article" itself:

* You're going to confuse readers when you call the pattern Model-View-ViewModel but then say the "most approved description of this design pattern" (approved by whom?) is Martin Fowlers article on Presentation Model. Honestly, there's enough confusion about whether or not these are the same pattern (they are!) and if they are, why we have two names. Not mentioning the details here is just going to make matters worse.

* If you've thrown a controller into the mix, you're not following MVVM/Presentation Model, but some other pattern. I'm disappointed that little about this is discussed.

* IView is never defined. This article presents this as a single pattern, but seems to be an implementation of multiple patterns, rather than a pattern itself.  If it is a pattern, stuff like this needs to be defined.

* Weak events are not a WPF concept. For that matter, neither is commanding. Though these live in assemblies associated with WPF, they are usable in WinForms (commanding less so, due to the lack of ICommandSource on controls in WinForms, but that can be worked around).

* The stricture about "having to" use weak events when the ViewModel listens to events on the Model uses a stronger statement than you should. You're likely to need to address lifetime, and weak events are one way, but this isn't a "have to" scenario.  Oh, and this statement backs up what I said in the last bullet point, as the ViewModel and Model have no relationship to WPF at all, and yet you're employing weak events ;).

* I've not looked at the WAF project, but the discussion about all Views needing to implement IView makes me cringe.  There are abstraction solutions that won't require tedious reimplementation of an interface all over the place, which probably isn't going to be a very DRY architecture.  An IView interface isn't a bad idea, but it should be something provided by the framework and not something the user has to implement over and over again.

I am interested, though, and will check WAF out when I get the time.

Jul 8, 2009 at 7:42 PM

Hi wekempf!

Thanks a lot for your comprehensive response. Some comments from me:

  1. At the moment I’m developing an application where the Model already implements the INotifyPropretyChanged interface. When all of the View <=> Model communication has to go through the ViewModel then I would write a lot code to relay the Model property changed events through the ViewModel. This code gets really ugly when I have to use the WeakEvent pattern because of different life times.
    So we decided that the View is allowed to bind directly to properties of the Model.
     
  2. You really got me :-). I have to change the “most approved description…” passage.
     
  3. The pattern description mentions in a short note that the MVVM is about the same as the PresentationModel pattern. You are right about the confusion whether these two patterns are the same (I agree, they are!).
     
  4. The Model-View-ViewModel pattern doesn’t define a Controller – that’s right. I already considered naming it “MVC with MVVM” or something similar. Maybe I should rethink it again.
     
  5. The IView interface is described in the pattern explanation but what’s missing is that this interface is optional. However, WAF needs the view to implement the IView interface which is provided by the Framework. The IView interface just defines the “DataContext” property so that the ViewModel class can set itself as DataContext of the view.
    My sample creates an own IView interface for every view because I use them as key for the IoC Container MEF.
     
  6. The concepts of weak events and commands aren’t limited to WPF but the .NET Framework weak event implementation is. The WeakEventManager inherits from DispatcherObject and so this class can only be used within the Dispatcher thread. I believe it should still work in WinForms applications too because they share the same UI thread (important for interop). Though, I wouldn’t recommend using the WeakEventManager in an ASP.Net environment.
     
  7. In my opinion the Model must not have any dependency to WPF or any other UI technology. This way I’m able to reuse the Models in different application types (Web, RIA, Rich Client).
     
  8. I use the ViewModel in WPF applications only. So they are allowed to use some low level concepts of WPF (commanding, weak events) with the result that they can never be reused in an ASP .NET app.
       
Jul 8, 2009 at 9:43 PM

1. Just because you have to write plumbing code isn't necessarily a good reason to avoid the abstraction.  More importantly to me, though, is that I often don't care about INotifyPropertyChanged on Models.  My ViewModels implement IEditableObject, and as such won't update the Model until EndEdit() is called, so there won't be any meaningful PropertyChanged notifications from the Model to relay through the ViewModel.  However, like I said, there's nothing in the MVVM pattern that prohibits you from exposing the Model to the View.

2. :)  Nit picky, yes, but this is an area that's caused me grief.

3. Most people seem to agree they are the same, though some consider MVVM a WPF specific refinement.

4. I need to study WAF to see how you're utilizing the controller. I've not found the need for one yet.

5. I didn't see a description of IView in the pattern.  If it's just an interface with a DataContext property, that's not such a big deal and easily handled by a framework like WAF.  This gets into the "view first" vs. "viewmodel first" MVVM debate. I've always preferred view first, but I'm starting to change my mind on that one.

6. As a stateless environment, there's probably little need for a weak event concept in ASP.NET. Your point is taken here, though.

7. We're in full agreement on that. Not sure what I said to cause you to point this one out in a bullet?

8. That's generally the easiest route to go, but it is possible to reuse a ViewModel in WinForms or even ASP.NET (though as a stateless environment it would probably limit your VM design fairly severely and isn't something I'd consider).

I really need to find the time to look at WAF.  While I'm unlikely to use it over my own Onyx framework, there seems to be enough interesting ideas here to contemplate.