It's easier to explain with a short example. It's also better if Presenter and Conttroller are separated as in Uncle Bos's explanation. It's by the way necessary if you want to implement Dependency Injection with an IoC container.
Let's say you have a simple use case where the user can search a client from its Id and display its Name, or an error message if the client is not found.
Your View class gets a Controller and a Presenter in its constructor.
It has a TextBox for the Id to search, and a Button to launch the search.
It also has 2 TextBlocks for the client's Name and the error message. These 2 are bound to properties in the Presenter.
When the user clicks the Button, the View gets the TextBox content and calls controller.Search(id)
.
Ultimately, the UseCaseInteractor
completely controls the behavior, whether it choose to display the client or an error message (or anything else...).
Some pseudo-code for the C#:
class Controller {
Controller(IUseCaseInput){ }
Search(clientId){ input.Search(clientId); }
}
interface IUseCaseInput { Search(clientId); }
class UseCaseInteractor : IUseCaseInput {
UseCaseInteractor(IUseCaseOutput) { }
Search(clientId){
client = ...
if (client == null) {
output.SetError("Argh!.";
} else {
output.SetClient(client);
}
}
}
interface IUseCaseOutput {
SetError(message);
SetClient(client);
}
class Presenter : IUseCaseOutput {
string Error { get; set; }
string Name { get; set }
SetError(message) { Error = message; }
SetClient(client) { Name = client.Name; }
}
Not very natural when you are used to MVVM, but does perfectly the job to defer all decisions to the use case. It resembles much more what an MVC framework does for the Web.