The ViewModel


In large applications with large models, the UI will soon fill up with unnecessary business logic. The logic remains but the developer has to return someday and clean it all up (Sure!).

Every developer knows that the degrees of freedom rapidly decrease once you fill your UI with business logic, which can turn out to be unhelpful:

  1. You cannot easily reuse the logic placed in a UI so you copy it and increase the maintenance
  2. You forget about rules placed in UI so your system gets a life of its own
  3. Once you have logic in the UI, you cannot be expected to know it all so you become afraid to make changes to your system because something will or may break (BAD!)
  4. You dare not give the UI to that brilliant designer because the designer will break logic for sure

Still, I see business logic in the UI everywhere I go. When I ask about it, I always get answers like: “Well, this is not finished yet”, “Well, this is really special stuff, only used in one place”, or “Yea I know it sucks, I will fix it later”. But “Later” never comes, does it? It will always just be “Later”.

I am no Superman for sure. I see business logic in UI I have written myself too.

If everyone or at least most of us are getting into these situations, could it be that we are doing things the wrong way? Could it be that doing things the right way is a bit too complicated?

These are some strategies to help developers do the correct thing and actually follow the coding guidelines:

  1. Automated review tools like FXCop
  2. Peer review (that usually will be done “later”)
  3. Some other strategy that will force violators (you and me) to mend our ways – even if the correct way is really complicated (maniac team leader with rabies foam in the face)
  4. Make it easier and faster to follow the “coding guidelines” than to be quick and dirty.

Unsurprisingly, I am in favor of making things easier. But to be able to make things easier, we need to understand what causes things to go wrong in the first place: Why is the UI filling up with business logic? I think there are a couple of reasons. Depending on how far you are from being model-driven, some of these reasons will apply:

  1. The UI will need to transform data (could be business logic) in order to display it according to specification.
  2. Actions performed in UI act on selections from UI components that have data in the transformed presentation format, and need to be transformed back (could be business logic) to model-scope in order to let the model work on the data (business logic). You also need to check that the parameters sent to the model method are valid (could be business logic).
  3. The existing business logic may not match 100% with what your action should do; you may want to call two, three, or more methods to get the job done (new business logic) and do some small checks based on the results of each method (could be business logic).
  4. Validation – your UI will do a lot of small checks to see that the data fulfills the overall rules for your application (business logic)

How do we make these reasons go away?

  1. We do it by offering a good and simple way to transform model-elements (or data if you will) into data elements suitable for rendering to match the specification.
  2. We do it by making it easy to add business logic where it belongs (in the model) and call it.
  3. We offer a clean and easy way to add validation logic.

By setting the model in focus, and making it simple to add methods, derive attributes, and derive associations, you can do everything you need for a specific UI in the model. This is sort of a good thing. The problem is that if you have 100 UIs, your model will fill up with 100 times x derived attributes and derived links. It will eventually become difficult to see the trees for the forest in a model like that.

Furthermore, when a UI is dropped and deleted for some reason, will we remember to drop the derived associations and derived attributes we added to the model to accommodate it? Probably not.

A transformation layer between the UI and the Model can fix this. The transformation layer is allowed to have business logic, as long as it is unique for the context it works on. If the logic is not unique, it should go into the model, ready to be re-used. We call this transformation Layer for a ViewModel.

A ViewModel transforms a piece of the model for a specific purpose. The purpose is often, but not always, to prepare the model information for interaction with a user for a specific use case – a UI. It can also be for creating data transfer objects that are suitable for exposure for another application or system, or for some reporting engine or the like.

Why does having rules in a ViewModel much better than having them in the UI? There are several reasons:

  1. Testing; it is a good thing to be able to test the logic separated from the UI because it is awkward and error-prone to test and read the results back from the UI.
  2. ViewModel re-use; you may have different UI’s for the exact same use case (beginner/advanced, Web-api/Rich client, etc).
  3. Design time type checking; most UI-binding strategies rely on using strings that can only be checked at runtime (true for WinForms, WPF, Silverlight, and ASP.NET), whereas a good ViewModel is type-checked at design or compile time.
  4. The designer working on the UI can harm important logic if the logic is in the UI.
  5. If you have dedicated designers, you will not want to wait for them to release a UI file in order to fix the business logic.
  6. The UI may be on the other side of a network (another physical tier) so the UI cannot have access to the domain layer tier.
  7. UI and logic have very different motivators and hence will often change for different reasons (looking good versus working correctly) - mixing them up adds confusion regarding the distinction between these important aspects.
  8. Security; a designer that has access to the ViewModel cannot go beyond the ViewModel and unintentionally expose confidential information in the use case at hand.

You do not have to use a ViewModel pattern to create a great application - it is just that is a good idea to use the ViewModel pattern when building applications that are going to be worked on for a long time, released in several versions over several iterations, and will most likely see different developers and UI-designer, and may very well be radically changed with regards to presentation framework during its lifespan. In short – it is always a good idea for successful applications to use a ViewModel pattern.

The MDriven Book - Next Chapter: The declarative ViewModel

This page was edited 50 days ago on 10/02/2024. What links here