Tuesday 26 October 2010

Cargo Cult MVVM => The death knell of WPF

The MVVM Cargo Cult is certainly a strong and powerful one.  It seems to be worshipped by every two bit WPF/Silverlight developer on the planet. Developer job sites list this as one of the multitude of pointless acronyms you must know, and if you are a non believer then you are a philistine who is not worthy of their time.

Millions of bloggers give thanks to their software gods by offering tips on how to use this magical beast, hoping that these same gods will look kindly upon them and deliver the software they crave. The less clever among them heap scorn on the gods and wait for a mystical MVVM tome that will explain their every confusion and answer all questions on this mystical pattern.

So lets get back to reality...
Over the last 17 years I have developed a truckload of GUI applications using a wide range of languages from assembler and C++ through to Winforms and WPF. I have also created several complicated multi threaded silverlight and WPF Apps using MVVM, I was pragmatic and used it only when it made sense and when it is worthy of my time. I too was tempted by its claims, but not any more.

It is my considered opinion that if MVVM could be erased from space and time we would all be producing better applications and in general be a lot happier.

The MVVM pattern was designed to try and accommodate the flawed XAML concept which was naively put forward by Microsoft all those years ago. They had big plans to replace HTML with this stuff, big plans which are now a distant memory.

WPF is dead!
Its been hanging on for grim death for years but MVVM has ripped open its chest and let the world see the true horror that is hidden within. It has laid bare the evil black magic that must be carved into XAML to make MVVM work. This pattern is the final dagger in WPF's barely beating heart.

MVVM asks you to create untyped XML files that contain free text view model names, property links, black magic bindings, mystical triggers, obscure commands, baffling templates and untraceable style overrides.
Then in the 'real' code you create notification properties with untyped string names, cross your fingers observable collections, even more magical routed events and commands and then pray to the gods you can make it all link together.

As I write this blasphemy I can hear the impassioned cries of  'Testability!' and 'Separation of concerns!'. Wondrous tails of a soon to be future where designers and developers live in a perfect world of magical collaboration and mutual respect. Its within our grasp they cry!

Sorry guys, you have all been led down the garden path on this one.
MVVM and WPF basically produces unmaintainable code as soon as the application gets even slightly complex. XAML is the problem, all these binding features MVVM forces you to use are at best an Alpha in WPF, and because WPF is such a sprawling mess of legacy 'features' it wont be fixed ever.

Trying to fix bugs in someone else's MVVM screen is nigh on impossible because its so hard to decipher the flow of control. When you make changes most of the time you only get runtime errors instead of compile time. Debugging these runtime errors is painful as they are generally hidden in the black magic of bindings or triggers or some other crazy abstraction in XAML.

MVVM testability claims are dubious at best. If you breakdown your frontend code correctly you can test it pretty well anyway, you dont need MVVM for that.

Also the mantra that  XAML lets designers design and developers code is flawed. It sounds great but in practice any slightly complicated screen basically needs a developer to make such complicated XAML that its sticky taped together just to work, and as soon as a designer tries to load it into blend or edit manually. Kaboom!  

Finally, MVVM produces terrible performance. It is nearly impossible to see where the bottle necks are as all rendering is done via black magic bindings and triggers. Trying to get any WPF application running smoothly is a struggle but using MVVM  makes it even worse. As have I often said during WPF development, 'My old C64 scrolled smoother than this and it only had 38k of available memory'

If you insist on still using this pattern remember this.
MVVM is a sharp tool, be very careful or you will cut yourself.


GCS Wiz




12 comments:

  1. C64 had 64K of memory. It's in the name, dude :-P Although I seem to recall that after BASIC and all the rest had been loaded, you only had about 15K left to play with.

    ReplyDelete
  2. Even with this the c64 still managed to do parallax scrolling!

    ReplyDelete
  3. The title of this is a bit misleading. As a reader, I thought this would be about MVVM with perhaps some good alternatives presented, but really your issue is XAML and WPF itself.

    FTR, I really do like the XAML model. That's why I joined Microsoft.

    In WPF and Silverlight development, you should use *some* architectural pattern. I don't personally care what it is, but IMHO it should leverage binding. Many of the features in the platforms are easier to use with binding.

    MVVM happens to be a leading pattern. However, many people throw a lot of extra complexity into the definition of MVVM, burdening it with things that really are optional and confusing the community in the process.

    Before joining Microsoft, I wrote a good number of Silverlight applications, and a smaller number of WPF apps. Once we started using MVVM (and to be clear, we weren't religious about it), the code became much clearer and easier to understand. We didn't use an MVVM toolkit, we didn't adopt IOC in most cases, and didn't worry about mocking. We did test.

    I do agree that debugging binding, prior to VS2010 and .NET 4, was a real mess. It gets much easier in VS2010 when you turn on the options to show binding trace information.

    Performance issues you've mentioned have little to nothing to do with MVVM. With a couple exceptions around raising large numbers if INPC notifications and related (which we're addressing in WPF next), those are more about being smart about how much data you load, how you bind it, how you use virtualization etc. You'll run into the same issues when using LHS = RHS code rather than binding.

    Pete Brown
    Microsoft Community PM WPF/Silverlight

    ReplyDelete
  4. You're late to the name, Mr Speaking Stones: http://en.wikipedia.org/wiki/Cargo_cult_programming

    ReplyDelete
  5. Very true, I cannot lay claim to that particular gem. However it still stands up as the defining description of the software industry as a whole.

    ReplyDelete
  6. I completely disagree.

    For the past 13 years I have been building large complex application in MFC, Win32, and Windows Forms. In all of these, it was a pain to separate the UI from the actual code so it rarely was done. This lead to harder to maintain code.

    Now we are migrating to WPF using MVVM and the results are amazing. A large chunk of WinForms tedious UI code gets eliminated when moving to XAML and bindings. The separation of UI and ViewModel lets us do drastic changes to the UI without touching a single line of code. There's more sharing between our many window types by reusing ViewModels for different views. Everything is now easier to maintain and we do amazing things we couldn't even dream of with WinForms.

    I've met other programmers share this author's opinion at my company, and each time, they were trying to follow MVVM without actually understanding WPF. They were trying to apply MVVM with a superficial "WinForms" approach to WPF, by ignoring bindings, and trying to construct their UI through code instead of XAML. They didn't understand how to properly use XAML data templates, template selectors, styles and triggers to really enforce the separation between the View and ViewModel.

    Of course that part is more complicated than just blindly manipulating your UI from code, WPF has a much steeper learning curve than WinForms. But I've yet to see a better pattern than MVVM to develop maintainable WPF apps.

    ReplyDelete
  7. Anthony, I think some of the MVVM separation concepts are a good thing, but I have been using these ideas for years. Also I certainly wouldn't say winforms or mfc are the solution either.

    However surely we should have a better system by now. I mean .NET winforms is nearly 10 years old and it's still heavily used because WPF never really took off.

    To answer the 'other programmers' comment I have just spent the last year with a team of 30 people building a very complex multi threaded trading GUI using pure MVVM in WPF, all done with binding and triggers and styles etc. I would say we are pushing WPF pretty hard, and it is working, but nothing like we had hoped. The viewmodel part is fine, its the binding and triggers that are painful, not too mention WPF performance. For me this is the issue, MVVM binding hides so much from you that you will always have performance issues on anything complex, so in the end you get slow memory hungry applications.

    WPF=slow at the best of times, more abstraction makes it worse.

    I have a question:
    Is this where you saw windows development heading when you first did MFC 15+ years ago?
    I would certainly have expected a lot better.

    ReplyDelete
  8. I'm sorry, but whatever it is that you have been using, it's not MVVM.

    I have been creating client applications with WPF and MVVM for over a year, sometimes using various MVVM frameworks, sometimes simply following the pattern on my own. Not ONCE have I had to "create untyped XML files that contain free text view model names, property links, black magic bindings, mystical triggers, obscure commands, baffling templates and untraceable style overrides." Nor have I had to "create notification properties with untyped string names, cross your fingers observable collections, even more magical routed events and commands."

    You apparently don't even understand the point of MVVM. All it says is that the technology-dependent GUI code of the screen that directly interacts with the user (the "view") should be separated from the logical representation of the state and behavior of the screen the user is interacting with (the "view model"), so that you can implement the logic of the screen without having to worry about GUI-specific concerns. In that respect it is no different than any other pattern when encourages the concept of separation of concerns. It doesn't even really have anything to do with XAML. You can implement the MVVM pattern in WPF without writing a lick of XAML if you want to; I know, I have done it (although I wouldn't really want to again. despite what you say, XAML is useful for what it was originally designed for, i.e. "application markup". It is when you try to go beyond markup that it suffers. In that way it is very similar to HTML).

    "Is this where you saw windows development heading when you first did MFC 15+ years ago?"

    Absolutely it is. The power and flexibility we have now with WPF (and other GUI technologies, to be fair) is what makes me excited about being a programmer. I'm sorry that you seem to have looked at how far we have come and become scared of heights.

    ReplyDelete
  9. Hi David, thanks for your feedback. It is interesting that you stick up for Wpf/MVVM when it is pretty common knowledge that it is a flawed and dead product. Since I wrote this blog Microsoft has effectively abandoned it.

    As for other GUI technologies, I have been writing some Ios Apps lately and even though objective C is pretty horrible, it has let me produce beautiful applications that run silky smooth with minimal fuss. That's what I want on windows, smooth, fast, responsive Apps. Wpf is incapable of delivering this, just look at Evernote4. They tried wpf for years but eventually abandoned it for good old c++. The Reason? They couldn't get performance and it used to many resources. Thats microsoft all over really and I have used their stuff for years. HTML5 is the new Microsoft direction, light weight and portable. Something in between this and wpf would suit me.

    ReplyDelete
  10. "It is interesting that you stick up for Wpf/MVVM when it is pretty common knowledge that it is a flawed and dead product. Since I wrote this blog Microsoft has effectively abandoned it."

    I would challenge you to support either of those statements with evidence, as I have been heavily involved with WPF for the last year and I see no evidence that WPF or MVVM are dead (MVVM was a community invention to begin with, and was never explicitly adopted by Microsoft; so the idea that they "abandoned" it doesn't make much sense).

    I have read a lot about Evernote switching to "good old C++", and it is pretty clear that there were all C++ programmers who tried to make the jump to .NET, because they could see C++ getting left behind. They failed to fully understand either the .NET platform or WPF - both of which admittedly have a significant learning curve - and therefore it is no surprise that they failed to make the most out of either. Though they tried to blame it on WPF, retreating to C++ was a sign of their own failure, not that of the technology.

    ReplyDelete