You could use a shared reference between the view and the presenter to store the viewModel (as a data structure).
For example, using dependency injection:
Response perform(Request request) {
ViewModel viewModel; // <-- just a space in memory
Controller(&UseCase(&Presenter(&viewModel))).execute(request);
return View(&viewModel).execute();
}Another possible solution is to make use of type erasure to hide the return types of the Presenter, UseCase and Controller, then you can return an instance of the ViewModel from the Presenter to the UseCase to the Controller respectively.
For example:
class Presenter: ... {
...
Object execute(OutputData) {
...
return aViewModelInstance
}
}
class UseCase: ... {
...
Object execute(InputData) {
...
return aPresenter.execute(aOutputDataInstance)
}
}
class Controller: ... {
...
Object execute(Request) {
...
return aUseCase.execute(aInputDataInstance)
}
}Then in the outermost layer, cast to the ViewModel type:
Response perform(Request request) {
viewModel = (ViewModel) Controller(&UseCase(&Presenter())).execute(request);
return View().execute(viewModel);
}class Presenter<T>: ... {
...
T execute(OutputData) {
...
return aViewModelInstance
}
}
class UseCase<T>: ... {
...
T execute(InputData) {
...
return aPresenter.execute(aOutputDataInstance)
}
}
class Controller<T>: ... {
...
T execute(Request) {
...
return aUseCase.execute(aInputDataInstance)
}
}Then in the outermost layer:
Response perform(Request request) {
viewModel = Controller<ViewModel>(&UseCase<ViewModel>(&Presenter<ViewModel>())).execute(request);
return View().execute(viewModel);
}Response perform(Request request) {
return View.run(Presenter.run(UseCase.run(Controller.run(request))))
}