Value of MVVM in a Line of Business Application (and a Rant of Current Development Practices)

mvvmwpf

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.

Best Answer

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