10

After 2 years, I'm still struggling with MVVM as a practical method of producing working software. In some cases it's great. I did a multithreaded application that controlled a small assembly line that would have been a nightmere without MVVM concepts. An abstraction from the physical assembly line was almost a no brainer.

However, my career mostly revolves around internal line of business applications - formalizing and optimizing the operations of a business. In such apps, there is generally a business teir revolving around CRUD and compound operations. In LOBs, my view models end up being a very simple collections of one line wrapper functions of the business class methods and in the end only end up complicating the simplest of tasks like showing a message box or opening a window. Doesn't anybody else find it odd when people go into long discriptions of "dependency injection" and "messaging providers" for a Window.ShowDialog call that has been around for decades? How many other questions are there on stack overflow asking for advice for tasks that were extremely simple in winforms?

Don't get me wrong - I get MVVM and how it could be invaluable to large teams doing horizontal development of a shrink-wrapped and marketed software package. Unit testing the view models could save millions by avoiding a bad RTM bug and dedicated UI developers could give a rich experience. But when the cost of redeployment is minimal and all the business cares to pay for is simple working software, why should i spend time unit testing a simple "wrapper" vm when my business logic is already unit tested? How much time is the business really going to allow me to spend on cute animations and color schemes? Is there anything left for a junior developer to do (tracking down a bug in a save functionality used to be looking at "Save_Click", but now you have to understand the patterns and the project as a whole especially if you're relying on templating to marry up the VM with the view).

Admittedly, I really like the databinding of WPF. To take advantage of it, I set the data context to the window itself, where it has access to the business class as well as any other observable properties. Yes I break nearly every MVVM "rule" by doing so. But at least I have simple event driven code that's easy to read AND I get to take advantage of the new databinding and validation. The problem is in the designers - which I don't use all that much but hope to now that it's better integrated in 2012 - the designer shows the hundreds of properties that a window and its base classes have.

For those that can relate can you point me to resources, books, or even just changes in perspective that made this easier to swallow. I'll give MVVM another shot, but the last time I felt pretty stupid for worrying about dependency injection just to show a message box from a VM I had no intention of unit testing. Even if I did unit test are we really getting more quality by trading run time testing for compile time errors of those dreaded "tightly-coupled" applications?

I realize one answer is to just stay in winforms. But as one of the last supporters of WebForms (I have much of the same critique of the trend of web developement), i felt a little like a dinosaur as it is when I descovered there's no more WebForms left in the Microsoft certification tracks. Moving forward is the only option, even if I don't like it.

2
  • 1
    While I don't encourage it, it is still possible to write a WPF application WinForms-style with events and code behind. For simple one-off apps, it's not a big deal. It comes down to what you value and what provides value to the business. I am a big fan of TDD and MVVM, but if it really isn't providing value, don't do it. It's not a religion. Just remember that code often lives a lot longer than we think it will.
    – Matt H
    May 31, 2013 at 3:43
  • "Doesn't anybody else find it odd when people go into long discriptions of 'dependency injection' and 'messaging providers' for a Window.ShowDialog call that has been around for decades?" I find it annoying, but the sort of person who gets into all of that (to the detriment of actually getting anything done) has always been a part of the field, and, unfortunately, probably always will. Best strategy is to ignore / distract them as much as possible. Jun 28, 2016 at 15:00

1 Answer 1

10

My perspective is from years of experience working with Winforms, the "old fashioned way," with events and code-behind. So I can tell you with absolute certainty that, once you get beyond the simplest of applications, your code quickly becomes a big ball of mud. It was inevitable, because that's the way applications were written back then.

Webforms is just the same, except that it throws in the additional complication of being a stateful abstraction over a stateless system (the web). As Rob Conery put it:

WebForms is a lie. It’s abstraction wrapped in deception covered in lie sauce presented on a plate full of diversion and sleight of hand. Nothing you do with Webforms has anything to do with the web – you let it do the work for you.

This, from the guy that wrote a fully functional object-relational mapper using the dynamic keyword in C# and only four hundred lines of code. When he speaks authoritatively about something, I listen.

The application I'm currently working on is a Winforms application, with several tabs in the main form. I can dynamically load forms into each of the tabs. While I didn't follow MVVM or MVP (you can, with libraries like this one), I did aggressively push every bit of code I could out to a separate assembly, leaving only that code that is absolutely required to run the form. There's still several hundred lines of code in there, not counting the partial class containing the form's control definitions, properties and event handler assignments, but I should never have to touch it again, unless I need to add something new to the form.

I have a static method that I can hand a form and a collections of Key/Value pairs, and it will (using Reflection) automatically match up the keys to the fields in the form, and populate the form with the collection's values. I can also do the reverse, getting a collection of Key/Value pairs from the form's fields. That whole thing is about twenty lines of code, but it pays for itself every time I use it, because I don't have to write forty custom assignment statements for forty controls on a form.

I can take that Key/Value list, and serialize it to XML, allowing me to persist it to a file. I have other forms that I can hand a conventional DTO, and map its fields to the form. None of this would be practical in the "big ball of mud" style of Winforms. It's almost trivial when adequate decoupling is utilized.

Does any of this sound familiar? It should; it's essentially a poor-man's form of data binding.

Admittedly, I really like the databinding of WPF. To take advantage of it, I set the data context to the window itself, where it has access to the business class as well as any other observable properties.

Good for you. It doesn't have to be MVVM compliant. But remember, patterns like MVVM were created to help developers build big systems. If you just need to display a dialog, you may not need all of that plumbing.

Part of the complexity of systems like WPF is inherent in all programmer libraries that seek to solve a specific problem in a generalized way. To do that, you have to account for every practical way a programmer might use your library. That adds complexity, but for those who design their libraries well, it also brings to the table a philosophy of doing things in a uniform and consistent way.

Consider John Resig's jQuery library: it is the very essence of a coherent design, and it hides a lot of weird details about the DOM, and variations in the way browsers handle it. Is it simpler just to write a few lines of Javascript? Sometimes. But the benefit of writing jQuery code in a coherent, uniform API makes it easier for the next person who comes along to understand what you did, and maintain that code if needed.

My real experience with "big application" models is in using ASP.NET MVC. ASP.NET is to ASP.NET MVC as Winforms is to WPF. When I worked in ASP.NET, I always struggled to bend it to my will. ASP.NET MVC bends to you. It is a joy to use; it produces a system structure that is clear and organized, and gives you full control over your application and markup. You can use Javascript, jQuery and CSS liberally, and ASP.NET MVC stays out of your way.

My only hurdle was getting used to it, and getting to know it on its own terms.

Further Reading
You Should Learn MVC by Rob Conery

12
  • Thank you for the truely thoughtful response big ball of mud - I definately felt that way in the days of classic asp and spaghetti code. 3 tiered design with vb6/mts fixed a great deal of that, and then .net's release brought it all together. But now if feel the returns on additional patterns are rapidly deminishing - like spending $1M to take .1 sec off your quarter mile time. "I did aggressively push every bit of code I could out to a separate assembly" - don't you find that this gives an incredibly fractured development experience - constantly jumping from file to file to read two lines?
    – b_levitt
    May 31, 2013 at 12:31
  • 3
    don't you find that this gives an incredibly fractured development experience - constantly jumping from file to file to read two lines? -- No, it is the opposite. Putting in another assembly like this frees your mind to focus on each class and method on its own terms, as its own little black box. That's very hard to do with a big ball of mud. MVC operates on the same principle: thin controllers, fat model, no code in the view unless absolutely necessary. May 31, 2013 at 14:51
  • 3
    Yagni only applies when you are writing the code yourself. If you are writing a generalized library that must satisfy a wide audience with diverse needs, you are going to need it. May 31, 2013 at 14:53
  • 1
    I have nothing against the ASP.NET life cycle, by the way; I have seen people use it to excellent effect. I just find it counter-intuitive, that's all. ASP.NET MVC doesn't force you to do any client-side development, if you don't want to; you can use "dumb" views, and it works perfectly fine. Worth noting: a lot of this stuff can be code-generated (just like a Windows form), so it's not like you're writing all of the code yourself. I do understand that this is less true with WPF, where you have to deal with XAML, and I do think there's room for improvement there. May 31, 2013 at 15:04
  • 2
    dozens of lines of plumbing to replace Window.Show -- That's a bit of an oversimplification. If the window needs data, there's always going to be some kind of plumbing to get that data into the window's controls, and vice versa. You can either write that repetitive code over and over again for every form you create, or employ some form of generalized solution like data binding. May 31, 2013 at 19:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.