Clean Architecture – What Is the View Model?

Architecturedtomvvmplugin-architectureview

In his book 'Clean Architecture', Uncle Bob says that the Presenter should put the data that it receives into something he calls the 'View Model'.

enter image description here

Is this the same thing as the 'ViewModel' from the Model-View-ViewModel (MVVM) design pattern or is it a simple Data Transfer Object (DTO)?

If it is not a simple DTO, how does it relate to the View?
Does the view get updates from it through an Observer relationship?

My guess is that it is more like the ViewModel from MVVM, because in Chapter 23 of his book, Robert Martin says:

[The Presenter's] job is to accept data from the application and format it for presentation so that the View can simply move it to the screen. For example, if the application wants a date displayed in a field, it will hand the Presenter a Date object. The Presenter will then format that data into an appropriate string and place it in a simple data structure called the View model, where the View can find it.

This implies that the View is somehow connected to the ViewModel, as opposed to simply recieving it as a function argument for example (as would be the case with a DTO).

Another reason why I think this is because if you look at the image, the Presenter uses the View Model, but not the View.
Whereas the Presenter uses both the Output Boundary and the Output Data DTO.

If it is neither a DTO nor the ViewModel from MVVM, please elaborate as to what it is.

Best Answer

Is this the same thing as the 'ViewModel' from the Model-View-ViewModel (MVVM) design pattern

Nope.

That would be this:

enter image description here

That has cycles. Uncle Bob has been carefully avoiding cycles.

Instead you have this:

enter image description here

Which certainly doesn't have cycles. But it's leaving you wondering how the view knows about an update. We'll get to that in a moment.

or is it a simple Data Transfer Object (DTO)?

To quote Bob from the previous page:

You can use basic structs or simple data transfer objects if you like. Or you can pack it into a hashmap, or construct it into an object.

Clean Architecture p207

So, sure, if you like.

But I strongly suspect what's really bugging you is this:

enter image description here

This cute little abuse of UML contrasts the direction of source code dependency with the direction of flow of control. This is where the answer to your question can be found.

In a using relationship:

enter image description here enter image description here

flow of control goes in the same direction the source code dependency does.

In a implementing relationship:

enter image description here enter image description here

flow of control typically goes in the opposite direction the source code dependency does.

Which means you're really looking at this:

enter image description here

You should be able to see that the flow of control is never going to get from the Presenter to the View.

How can that be? What does it mean?

It means the view either has it's own thread (which is not that unusual) or (as @Euphoric points out) flow of control is coming into the view from something else not depicted here.

If it's the same thread then the View will know when the View-Model is ready to be read. But if that's the case and the view is a GUI then it will have a hard time repainting the screen when the user moves it around while they wait for the DB.

If the view has it's own thread then it has its own flow of control. That means to implement this the View will have to poll the View-Model to notice changes.

Since the Presenter doesn't know the View exists and the View doesn't know the Presenter exists they can't call each other at all. They can't fling events at each other. All that can happen is the Presenter will write to the View-Model and the View will read the View-Model. Whenever it feels like it.

According to this diagram the only thing the View and the Presenter share is knowledge of the View-Model. And it's just a data structure. So don't expect it to have any behavior.

That might seem impossible but it can be made to work even if the View-Model is complex. One little incrementing update field is all the view would have to poll to detect a change.

Now of course you can insist on using the observer pattern, or have some frameworky thing hide this issue from you but please understand that you don't have to.

Here's a bit of fun I had illustrating the flow of control:

enter image description here

Note that whenever you see the flow going against the directions I defined before, what you are seeing is a call returning. That trick won't help us get to the View. Well, unless we first return to whatever called the Controller. Or you could just change the design so that you can get to the view. That also fixes what looks like the start of a yo-yo problem with Data Access and it's Interface.

The only other thing to learn here besides that is that the Use Case Interactor can pretty much call things in whatever order it wants as long as it calls the presenter last.

Related Topic