I stumbled across this article whilst looking on Jesse's site
for an answer to a specific WPF Toolkit Charting question; however
it does strike some chords of similarity to the questions we are
often asked.
http://jesseliberty.com/2010/05/08/mvvm-its-not-kool-aid-3/#more-1334
MVVM, MVP, MVC or MVMBO JVMBO
To be honest I was an advocate of COM and advocate of MVC/MVP and
now I am an advocate of MVVM. Is it because its new? Well possibly,
but in this case its less of that and more about a pattern I can
really see the benefits of.
Let me qualify that, I really am an advocate of the current MVP
pattern I use at work and do think that there is benefit in
conforming to a standard way of working; but in my humble
opinion a good development pattern must conform to three
principles:
1. Confirm the separation of View and Business Logic
2. Mean you write a similar amount or less code and not extra code
for no reason
3. Make sense
My like of MVP was not without reservation; for me it broke
rule one and often a little of rule two.
Breaking Rule One:
If the view needs to know the shape of the presenter then it
definitely breaks rule one; it could be my interpretation of our
implementation but because the view needs to know the shape of the
presenter or the Presenter needs to know the events on the view
there is a clear link back to the model and so the references are
cyclic or tied.
Within MVVM the links are one way only, and the VM satisfies
only the provision of data in a service oriented way, the view asks
for some data or a response to a command, if the ViewModel can
resolve it then it does, if not then neither the View nor the
ViewModel breaks it just fails (semi) silently.
Breaking a little of Rule two:
In the MVP pattern and MVC there was a tendency to hook up a huge
trail of events from the View back to the Presenter. I am not
saying this is what the pattern dictates but it tended to be how we
implemented it. That meant we had an event in the presenter that
handled a specific UI change to update the model. We had to hook up
the events at View creation and write the code to update the
underlying model.
Within MVVM that is not the case as this is handled for us by
the binding of the UI elements data to the ViewModel.
CommandBinding further support this pattern. The eventing mechanism
is slightly more code it does further support rule one. Overall it
should mean you write less code.
There is a caveat here, Value Converters, there are lots of
them, where you might have previously just had a small function in
your view to convert a bool to a state now you do it with
converters. You could still do it at the ViewModel level and
sometimes that makes sense but converters keep the ViewModel pretty
tidy especially where you need lots of ViewModels to do the same
thing.
Rule three:
There was a statement that sticks with me, along the lines of this
sentiment
"the inherently boring nature of
these business problems lead many programmers to seek out new
problems to solve, the most common of which is the meta-problem: a
problem with the process of creating a solution for the actual
problem"
We can all pinpoint places in code we have stumbled across when
a particularly elegant solution has been employed to solve a
problem that is actually much simpler. Developers (not us clearly)
have coded for the unseen, and often the unneeded. In doing some
VAT re-work last year, some of the code was written using a near
perfect implementation of an observer pattern with a concrete
implementer class for each VAT rate, academically beautiful,
however completely unnecessary and when the VAT rate changed a new
class was needed. Brilliantly flawed design.
In the MVVM world, it seems to me anyway, there is less stuff
you HAVE to do, it works in a relatively straightforward way; rules
one and two are satisfied and the split between them seems to still
be in the right direction; I write less code, most of the time
and it easier to test because of the separation.
The downside:
Yes there is a downside, in fact there are a couple of issues that
need resolving; firstly binding that fails does so with a terse
message that is not so easy to Debug, the fact that a property
cannot be resolved does not tell you why until you get your head
round what information can be gleaned by interpretation. Once you
get your head around the messages though, its actually pretty easy
to sort out. Secondly, and perhaps more of an issue, using command
binding causes a memory leak when clearing down views. Events are
still hooked up from the ViewModel and so are still left hanging
about and not collected by managed Garbage Collection. An article
that explains this issue is detailed here
http://edgeug.net/blogs/nondestructive/archive/2008/07/29/wpf-memory-leak-in-command-binding.aspx,
it also helpfully suggests a solution. There are other solutions to
this but they involve forcing a GC collection. Not a showstopper in
my opinion but an annoyance nonetheless and one that is bound to
trip up the unwary.
The wider picture
In our applications we further separate out our layers into a
databroker and dataservice layer that have responsibilities for
getting the data and transforming it into the shape we need or
handling errors in the fetching process. This is further divorced
from the data source by Web Services and Stored procedures that
limit the applications exposure to changes. So the MVVM pattern is
the last bit of separation along a chain of 'independence'.
Summary
Are there more upsides and downsides, yes quite likely, I have not
written every application I need to yet; Have I written vast
amounts of application infrastructure? No; will MVVM be suitable
for everything? No; Do I recommend that for most WPF UI related
work, this is the pattern you should look to first? Yes.