Reputation: 2809
I have a hard time understanding how to actually implement the clean architecture,
taking note of the following point regarding the clean architecture.
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?
Upvotes: 4
Views: 5355
Reputation: 51323
I think that you have 2 different use cases, since they have different results.
use case's result is
{ x : "data x", y : "data y" }
use case's result is
{ z : "data z" }
Thus the controller either invokes use case 1 and passes a
interface Presenter
{
public void present({ x : string, y : string });
}
or the controller invokes use case 2 and passes a
interface Presenter
{
public void present({ z : string });
}
Since the controller is a part of the user interface it will be a different one for the CLI than for the web.
Upvotes: 3
Reputation: 3563
In Clean Architecture "use case" (or "use case interactor") refers to the class/component which contains the business rules/business logic. The Dependency Rule defines that the use case (the business logic) should not have (compile) dependencies to the view, any external framework or IO.
One benefit of this architecture is that all the business logic can be easily tested independently from any external dependencies.
Another benefit is that concrete external services or concrete (UI) technologies can be replaced without impact on the core of the software system, the business logic.
As you can see in the lower right corner of the picture the control flow still goes from view to controller to use case (business logic) and back to presenter and then back to the view. The input and output port defined by the use case allow this control flow by still avoiding (compile) dependencies from business logic towards controller/presenter/view.
You can find a more detailed discussion on how the business logic remains independent from the view on my blog: http://www.plainionist.net/Implementing-Clean-Architecture-Controller-Presenter/
Upvotes: 8