Is this the same thing as the 'ViewModel' from the Model-View-ViewModel (MVVM) design pattern
Nope.
That would be this:
That has cycles. Uncle Bob has been carefully avoiding cycles.
Instead you have this:
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:
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:
flow of control goes in the same direction the source code dependency does.
In a implementing relationship:
flow of control typically goes in the opposite direction the source code dependency does.
Which means you're really looking at this:
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:
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.
ViewModel
is wrapper forController
,Presenter
andViewModel
in Uncle Bob's Clean architecture.Controller
->ICommand
andPresenter
->data-binding mechanism
.