views:

358

answers:

7

Hello,

I just have mixed feelings about MVVM. It seems I need to code so much to get the most remedial things to work. I miss events (commanding is such a pain), and I miss having a reference to the view!

I was just wondering about your feelings of MVVM vs the plain old code behind way. What do you like better and/or what do you normally use or recommend using?

Thanks

+5  A: 

One word:

Testability

Unit test your form-code-behind events. Hah, good luck with that. Also MVVM opens up the ability to use a good IoC paradigm to build up your application. It also keeps your logic detached from your UI, this allows you to hire an actual designer to do your layout, and wire it up to the Interface you expose to them.

But i cannot stress enough:

Testability

Seriously, unit testing your behavior is probably (in my mind) the best part of MVVM.

Aren
I don't really use unit tests. So is that the main argument for mvvm?
Shnitzel
@Shnitzel I guess working code isn't important to you or your company
Chris Marisic
@Shnitzel Even if you have 50% code coverage with unit tests, you're going to save yourself loads of headache time. You really should write just some basic ones to verify the integrity of your software.You obviously didn't read the paragraph in the middle, it explains the other advantages ASIDE from testability.
Aren
Berryl
@Chris, I take issue strongly with that statement, especially if you're focusing specifically on things like TDD. Having automated tests, and regression tests for builds is one thing, but there are many ways to test at the designer level. The important thing is that the code gets exercised. But my big beef with TDD and the like is that unit-level is rarely where applications break. Integration testing is far more crucial.
Cylon Cat
@Cylon Cat, Unit Tests aren't always used for TDD, they can be used in a TAD approach, and they are primarily used to make sure you don't accidentally TAINT something that was working by implementing something new. This is very important because they catch the things you wouldn't always think about. But you have a very valid point, other forms of testing tend to have great pull in actual effectiveness, but most projects should at a very base level have minimal unit testing on the core components to ensure project integrity.
Aren
Berryl, a designer working concurrently with a developer? In LOB apps I find that happens very rarely. Unit Testing has its merits for certain things, agreed. But the majority of a CRUD business app is just data in/out. easy peasy. Unit testing isn't a *must* everywhere.
Shnitzel
The best quality environment I've ever worked in emphasized integration tests, not unit tests. Developers wrote the integration test plan, and that plan had to be approved by our test prime before we could submit any code to the library. (That was an automated lock.) Developers also ran the integration tests, and had to complete them successfully, or their feature would be backed out of the release. These integration tests then became input for system, product, and regression tests. Developers attended system test plan reviews, as well.
Cylon Cat
A: 

From Josh Smith's article on MVVM:

In addition to the WPF (and Silverlight 2) features that make MVVM a natural way to structure an application, the pattern is also popular because ViewModel classes are easy to unit test. When an application's interaction logic lives in a set of ViewModel classes, you can easily write code that tests it. In a sense, Views and unit tests are just two different types of ViewModel consumers. Having a suite of tests for an application's ViewModels provides free and fast regression testing, which helps reduce the cost of maintaining an application over time.

For me, this is the most important reason to use MVVM.

Before, I would have controls which mashed the view and viewmodel together. But a view essentially has mouse and keyboard events as input, and drawn pixels as output. How do you unit test or integration test something like that? MVVM makes this problem go away as it separates the untestable view from the testable viewmodel, and keeps the view layer as thin as possible.

Wim Coenen
+1  A: 

The usefulness of a MVVM-like approach scales with scope and complexity of the application. At one end is "not very complex, not very useful" and the opposite end is "many man-years to build, impossible without something like MVVM".

Testability goes hand-in-hand with this - applications small enough & simple enough that MVVM feels over-the-top are also so small and simple that real unit test coverage is farcical. However, the real world is usually very complicated, which means real-world apps do need unit tests to maintain quality and they do need MVVM to be testable and manageable. Anyone who thinks they are getting by without them are burning a huge amount of energy where very little is required; or worse, letting serious quality problems be masked by something else.

Rex M
+1  A: 

I'm definitely in the minority on this one, but I tend to agree with @Shnitzel. MVVM, and the binding that goes hand-in-hand with it, are great ideas, but they're poorly served by the current MS tools. The syntax for all but the simplest bindings is very difficult to get right, and is made much harder by the fact that WPF and Silverlight silently swallow all the errors. (Yes, some of the errors show up in the debug window, but not enough of them, and without enough detail.) You can use hacks like writing a debug value converter, but the fact remains that the toolset is still pretty immature. (And then there's my standard complaint, that data binding isn't strongly typed, which means that the tools CAN'T catch the errors for you.)

I hear everyone when they insist on testability, and I'm a big fan of automated testing. But at least with the current state of our tooling, MVVM's improved testability comes at a pretty big price.

Consider this scenario: you've got a large app with 50+ forms/pages, and you've just engaged in a major refactoring of your Model and ViewModel. In the process, you renamed a bunch of classes and properties, etc. Now find every place in your XAML that you need to change to reflect the new class and property names. So much for testability, eh? Not only will the IDE not catch your binding mistakes, the compiler won't catch them, and, best of all, the app won't even throw an error at runtime. You have to get a tester to run through the whole app, and make sure that all your bindings are still doing what you want them to do. Ugggh. Ugly and painful. At least when I was doing things the old-fashioned way, the compiler would tell me when I misspelled something.

Going back into my cave to avoid the slings and arrows quickly headed my way...

Ken Smith
Actually I really like the binding engine with wpf/silverlight. I'd use binding with code behind so it's not just an mvvm thing. My gripe is mainly not being able to call methods on view objects easily.
Shnitzel
@Ken - just a felt tipped dart :-). Refactoring and debugging xaml *is* way more painful than I'd like, but the problem there isn't really caused by using the mvvm design pattern. And the only alternative I can think of today is if you can push more of the databinding out of the xaml and into the code, at the price of being less able to support a designer.
Berryl
I agree that the problems I outlined aren't inherent in the MVVM pattern -- just in the only tools and frameworks available for us to use on the MS stack :-). The fundamental problem, in my lonely opinion, is that data binding doesn't have an option to be strongly typed. As soon as you type "{Binding...}", you're working without a net. The assumption at MS seems to be that GUI is hard, and data is hard, but wiring them up is so trivial that you don't need any tooling support to help you out. That's not just wrong, it's wildly and astonishingly wrong.
Ken Smith
A: 

MVVM has its pain points - like all the boilerplate code needed for commanding, messing with the binding syntax and the incredibly stupid hacks need to close a form.

-- but --

This is all due to lack of a good framework - this video was the big eye opener for me, if you pick the right framework it can take care of all the nasty parts automatically (and if you can't find a good framework writing your own mini-framework that solves your pain points is easier than dealing with "naked" MVVM).

Just look at that video and see how with a good small framework you can write MVVM apps with less code than the alternative.

Nir
+3  A: 

People have mentioned testing, which is a good point. Another point in my opinion is reuseability, bind the same viewmodel to different views. E.g maybe you have a simplified view for some users and a more advanced one for others.

I see people mentioning how handling of events is a pain and such. There are MVVM frameworks which handles this. In my opinion it's also acceptable to hook event handlers to code-behind and call methods on the viewmodel from code-behind. It's certainly better than not be using MVVM because of the hard times people may have hooking up events.

Another HUGE advantage lies in the nature of the MVVM, separation of GUI and business logic. If you work with designers, they are all up in the XAML world, talking about gradients, borders, shading and what not. While you, the programmer happily codes away on your ViewModel with unit-tests. So when the designer has a prototype ready, it's just a matter of hooking up the commands, and bindings. Easy piecy GUI ready =)

hkon
+1 The possibility of using the same ViewModel for different views is really a very practical thing and saves me a lot of time.
HCL