I have a hard time understanding how to actually implement the clean architecture,
taking note of the following point regarding the clean architecture.
- the inner circle should not know about the outer circle
- the use case should not know about the web/framework
- the use case should not know about view
traditionally while developing any react or any other application. the main focus is on the "VIEW" so, the view defines the use case and the use case defines the entity. hence the end result was that the use case is tightly coupled with the view.
so the control starts from the view when the user interacts with the UI, and the view calls the use case and uses case uses the entity and returns the result to the view.
with this, it's hard to see the use case and views as separate.
how do we achieve the separation of the view from the use case? and flow of control from the controller to the use case to the and then to view.
The Problem
from the above diagram, it's clear that the controller calls the uncase interactor via the input port interface. and the use case updated the UI with the Output port.
so, let's say we have the entity as follows.
{ x : "data x", y : "data y", z : "data z"}
the output will be displayed either in the CLI or WEB.
and suppose there is some use case operation op()
after performing the op()
the result will be displayed to the user.
but, if the UI is WEB then the data x
and y
should be displayed.
and if the UI is CLI then the data and z
should be displayed.
how do we distribute the logic to achieve clean architecture?.
one solution could be, we can have the output port interface like.
interface Presenter
{
public void presentForWeb({ x : "data x", y : "data y" });
public void presentForCli({ z : "data z" });
}
but this violate the architecture. since the Use case, they should know about the UI to be able to properly display the data.
Another solution would be, to have the output port as
interface Presenter
{
public void present({ x : "data x", y : "data y", z : "data z" });
}
this is almost a good solution, but there we are passing some redundant data. so what if the z data is large we only need to pass it when using the CLI.
is there a better solution, to achieve the clean architecture?