Introduction

In today's world of WPF and WCF client-server applications, MVVM is growing in popularity among multi-tier app developers. In this series of articles, I will discuss why I think MVVM is an abomination to Object Oriented Programming, and I will demonstrate a different way in which developers can write applications.

Model View ViewModel

(Note: if you are familiar with the MVVM pattern already, skip to the Multiuse-Model View section).

To understand why MVVM is not the best way to go, we must first understand what MVVM is and how it works. For a more detailed description about MVVM, read about the Model View ViewModel Design Pattern for WPF.

MVVM consists, basically, of a set of classes that define your data, a set of classes that define your behavior, and a set of classes that define your looks and feel.

Let's take a simple address book application as an example:

Let's assume the application will use the following database table as the persistence storage:

In a typical WPF/WCF application, you would likely have a project that contains your Data Object Model, another project that contains your Data Transport Object Model and converters between the data objects and the DTO objects, a project that contains your View Model and converters between the DTO objects and the VM objects, and another project that contains your Views. Implementations might vary slightly across projects and developers, but for the most part, a typical address book application might look like this:

Notice that we have three classes that are a representation of the data stored in the contact table (Contact, ContactDTO, and ContactViewModel). All these classes expose more or less the same number of properties, with the difference that the ContactDO class has logic pertaining to the database (most likely a map if you use NHibernate), ContactDTO is a (most likely SOAP) serializable object, and ContactVM contains ICommands and other view-related properties.

When I see this, what immediately pops to mind is my programming 201 class back in college: fundamentals of programming, when we talked about the four basic principles of Object Oriented Programming (for those of you who don't remember, they are: Encapsulation, Abstraction, Inheritance, and Polymorphism). I don't know about you, but I certainly don't see any of these principles being applied in the MVVM pattern. We have three classes that do almost the same thing (there goes Encapsulation), they are not tied together whatsoever (tough luck Abstraction), they do not share their properties with each other (oops - too bad Inheritance), and they are not swappable in different contexts (Polymorphism). So, what's the big deal, you might ask. If you have ever worked on an MVVM application, I'm sure you've noticed (as I have) that adding a new piece of data (property) or functionality (methods, classes, etc.) to an existing object model is a huge pain in the ass, time consuming, cumbersome, and most importantly, there is a high chance of forgetting something and producing faulty code. Think about it: if you want to add a column to your database table, you would have to change at least 5 classes (sometimes more, depending on the project). The chances of forgetting something or screwing something up are 500% higher than if you only had one class to worry about. Not to mention 5 times the amount of time it'll take to make the change (not counting the time spent debugging the errors caused by what you forgot to change).

To summarize, here is a list of the pros and cons for MVVM:

Pros:

Hard separation between logic (view model) and display (view).

Easy to unit test UI logic.

Leverages WPF technologies such as binding and commanding.

Cons:

Does not conform to Object Oriented Programming standards.

It is too complex for simple UI operations.

For large applications, it requires a large amount of metadata generation.

Requires duplication of code.

It is complex to maintain.

The Multiuse-Model View approach

So we know that MVVM is quite the opposite of what we want as object oriented developers, it is hard to maintain, and requires duplication of code. But the question is: what is a feasible object oriented solution to this problem? The answer is MMV: a pattern that uses Encapsulation, Abstraction, Inheritance, and Polymorphism to transport data all the way from the database to the view.

Let's take our Address Book example one more time. Given the same contact table, let's draw a new solution:

Whoa, what happened to all the projects? Now, we have 6 projects instead of 7, but only one class that represents the contact table. We still have a public and a private web server, we have the very same shell application and the very same view as in the MVVM pattern, but we now have one project for the entire data model (plus one core project that we will get to later). So, let's take a closer look at the Contact class:

This is a simple class with four properties and a method to perform some action particular to a contact (in this case, from an object model point of view, we want to be able to send emails to the contacts in our database). A couple of things pop right out by simply glancing at this:

First of all, we see the TableAttribute for the class. For the time being, ignore this since it is specific to retrieving data from the database. This might not be necessary depending on the flavor of persistence library that you like the most (for example, if you use NHibernate, you would have either a mapping class or an XML file).

Second, we notice that all of our relevant properties are declared as virtual. This ties to our third point.

Third, this class inherits from a generic MultiuseObject class (where all the magic happens).

Notice how much cleaner and simpler to read this one class (that encapsulates everything you need) is. If you wanted to add or remove a column from the database, all you would have to do is to add a corresponding property to this class, and voila, you're done! The MultiuseObject class takes care of getting and saving the object from the database, it takes care of sending objects and collections of objects from the private server to the public server and from the public server to the client, and it even implements INotifyPropertyChanged and creates ICommands for you. How does it do all of this? Well, let's take a look at our sample MultiuseObject<t> class:

Comments and Discussions

Thanks for sharing this refreshing idea. I can't say I agree with your assertions against MVVM, but I do appreciate that you need to use the right tool for the job. If MVVM gets in your way, then you shouldn't use it. It's not a silver bullet. With that said, I have worked on many applications that successfully used MVVM, and didn't find them to be painful to maintain or troubleshoot. In fact, quite the opposite.

I don't follow your assertions :
each modification of your class will impact every layers of the application : what if it's a big project and different teams works on each layer :it will need a re-deployement of every layer for each modification of the data classes...

I typically hate "what about" posts, as I feel they are generally nitpicky in nature, but I think one of the core MV<x> patterns (whether you agree that VM = P in the <x> portion or not), is the ability to use multiple views for the same data.

So, what about multiple views of the data?

Given your new pattern, can you describe to us how to accomplish the following:

1) Show a screen that "edits" a contact, having a separate TextBox for First Name, Middle Name, and Last name.

2) Show a screen that displays a list of contacts (in a grid) where one column contains the entire name in LN, FN MN format. As I understand it, your solution to this would be to simply add another property to the Contact object? (Not sure if this is correct or not, please advise).

I think the MVVM pattern is first and foremost only about how you link your UI with the business logic model object. You often must enrich it with some enable/disable/change selection logic, that's why you would wrap that object into a dedicated ViewModel. The goal is to have no code at all in the code behind file of the XAML besides the InitializeComponent() call. It might be tedious to wrap up all properties up, but mostly you don't need to if you are okay with using some property path syntax here and there (e.g. something like "... {Binding=MyContactViewModel.Model.FirstName} ...". This over-all approach isn't so wrong and devilish at all.

How that business object is read from and saved to the repository is not part of MVVM, although those practices demonstrated here in this article as bad examples are surely the way Microsoft mostly proposes in their samples.

Often it really boils down to measure writing lot of code by hand versus using a lot of reflection magic/dynamic code emission/code generation. I agree that defining extra DTO and Request/Response objects is redundant. You mostly know or can easily determine which properties are scalar and which contain reference to other objects. In my opinion, the model objects should be simple base classes without much logic or just plain interfaces. The implementation of these models with more logic and all that property changed event stuff can happen by IOC/dependency injection.

I played a bit with MVVM and quite enought to agree with you ... MVVM is everythings except good OOPS programming and few re-utilisability. I also changed things in DataBase and i have to rebuild the classes that goes along and falled into misery. The architecture is certainly too much dependent of Visual Studio .. a glicth can happend easy.
My opinion was not to used this kind of thecnologie...until i read you'r article wich is very interesting and offer an alternative.

You might be following the principle of Encapsulation, Abstraction, Inheritance, and Polymorphism, but it's only in your 201 class that you’re actually suppose to do all of that in one, single monster-class. And you’re only suppose to do that to show that it’s actually possible – not to show that it’s practical.

Your 'MultiuseObject<t>' class is breaking just about all of the SOLID principles put forward by Robert C. Martin, and this kind of big-ball-of-mud that you've created with MultiuseObject<t> is exactly what gets OO programmers into troubles every time. How many responsibilites does this class have? How many reasons to change does it have? How many dependencies does this class take?

Saying that this will lead to easy unit testing og UI logic would be - in my opinion - quite a bit of stretch. You might be able to test properties of a Contact, but how would you go about implementing a command that loads all the contacts from the database? How would you unit test that?

I'm not sure, but I think there is a serious flaw in your idea, although I do actually believe in the wrongness of MVVM.

I'm writing mostly n-tier layered apps since .NET2 using remoting.
In my expierence client side code should not have anything to do with business logic and even stricter with the DAL(Data Access Layer).
If I understand correctly your approach, because each object inherits a base class for all functionality, this functionality is available on all layers of the application, which I find wrong mainly for security reasons.

Also you may want to checkout Expression trees that can provide the same functionality as dynamic assemblies, but there are more easy to understand and readable. Of coarse their full pottential will be available with .NET4.

Regardless of whether you are right o wrong, Great job.
Thanks for the effort