Clean architecture (such as port/adapter architecture) distinguishes between the main port (method) and the auxiliary port (the interface is implemented by the adapter). After the communication process, I hope “use case The “input port” is a main port (hence, just a method), and the “use case output port” is an interface to be implemented, perhaps a constructor parameter with an actual adapter so that the interactor can use it.
To create a code example, this may be the controller code:
Presenter presenter = new Presenter();
Repository repository = new Repository() ;
UseCase useCase = new UseCase(presenter, repository);
useCase->doSomething();
Presenter interface:
< pre>// Use Case Output Port
interface Presenter
{
public void present(Data data);
}
Finally, the interactor itself:< /p>
class UseCase
{
private Repository repository;
private Presenter presenter;
public UseCase(Repository repository, Presenter presenter)
{
this.repository = repository;
this.presenter = presenter;
}
// Use Case Input Port
public void doSom ething()
{
Data data = this.repository.getData();
this.presenter.present(data);
}
}
This explanation seems to be confirmed by the previous diagram itself, where the relationship between the controller and the input port is represented by a solid arrow with a “sharp” head (UML stands for “association”, meaning “there is one” , Where the controller “has a” use case), and the relationship between the presenter and the output port is represented by a solid arrow with a “white” head (UML stands for “inheritance”, this is not the “implemented” one, but may Anyway).
However, my problem with this approach is that the use case must deal with the presentation itself. Now, I see that the purpose of the Presenter interface is abstract enough to represent several different types of presenters ( GUI, Web, CLI, etc.), it actually just means “output”, this is a use case that may be good, but I am not completely confident about it.
Now, browse the clean system on the Web Structured application, I only seem to find a way for people to interpret the output port as returning some DTO. This will look like this:
Repository repository = new Repository();
UseCase useCase = new UseCase(repository);
Data data = useCase.getData();
Presenter presenter = new Presenter();
presenter.present(data);< br />
// I'm omitting the changes to the classes, which are fairly obvious
This is very attractive because we are moving the responsibility of “calling” the presentation out of the use case, Therefore, the use case no longer cares about knowing how to process the data, but just providing the data. In addition, in this case, we still have not broken the dependency rule, because the use case still does not know any information in the outer layer.
However, The use case no longer controls the moment when the actual presentation is executed (this may be useful, for example, doing extra things at that moment, such as recording, or aborting it completely if necessary). Also, please note that we have lost the use case input port because Now the controller only uses the getData() method (this is our new output port). In addition, in my opinion, we have broken the principle of “tell, don’t ask” here, because we ask the interactor to use certain data to do something instead of telling it to do something actual. First place. p>
So, according to the clean architecture, are either of these two options a “correct” interpretation of the use case output port? Are they all feasible?
In this answer to another question, Robert Martin described a use case where the interactor called the presenter when reading the request. There is no mention of MVC, MVVC, etc., so I guess the clean architecture generally cannot Works well with MVC?
Clicking on the map causes either the placePinController to be invoked. It gathers the location of the click, and any other contextual data, constructs a placePinRequest data structure and passes it to the PlacePinInteractor which checks the location of the pin, validates it if necessary, create a Place entity to record the pin, constructs a EditPlaceReponse object and passes it to the EditPlacePresenter which brings up the place editor screen.
blockquote>
The possible explanation is that the application logic that will traditionally enter the controller is moved to the interactor, because we don’t want any application logic to leak outside the application layer. Therefore, the model will not call Demonstrator, because the interactor is not the model, but the actual implementation of the controller. The model is just the data structure passed. This seems to be confirmed by the following:
The software in this layer is a set of adapters that convert data from the format most convenient for the use cases and entities, to the format most convenient for some external agency such as the Database or the Web.
From the original article, talking about interface adapters. Since the controller must be just a thin adapter that converts one data format to another, it cannot contain any application logic, so move it to the interactor. p>
[Update 2017-08-29]
If the model uses presenter-interface, then this is no longer a clean mvc, mvp or mvvm architecture, but something else Something.
Considering the Clean Architecture definition, especially the small flowchart describing the relationship between the controller, the use case interactor and the presenter, I am not sure if I am correct Understand what the “use case output port” should be.
Clean architecture (such as port/adapter architecture) distinguishes between the main port (method) and the auxiliary port (the interface is implemented by the adapter). In the communication process After that, I want the “use case input port” to be a master port (hence, just a method), and the “use case output port” is an interface to be implemented, perhaps a constructor parameter with an actual adapter, so that the interactor can Use it.
To create a code example, this might be the controller code:
Presenter presenter = new Presenter();
Repository repository = new Repository();
UseCase useCase = new UseCase(presenter, repository);
useCase->doSomething();
Presenter interface:
// Use Case Output Port
interface Presenter
{
public void present(Data data);
}
Finally , The interactor itself:
class UseCase
{
private Repository repository;
private Presenter presenter;
public UseCase(Repository repository, Presenter presenter)
{
this.repository = repository;
this.presenter = presenter;
}
// Use Case Input Port
public void doSomething()< br /> {
Data data = this.repository.getData();
this.presenter.present(data);
}
}
This This explanation seems to be confirmed by the previous diagram itself, where the relationship between the controller and the input port is represented by a solid arrow with a “sharp” head (UML stands for “association”, meaning “there is one”, where the controller “There is a” use case), and the relationship between the presenter and the output port is represented by a solid arrow with a “white” head (UML stands for “inheritance”, this is not the “implemented” one, but it may be anyway) .
However, my problem with this approach is that the use case must deal with the presentation itself. Now, I see that the purpose of the Presenter interface is abstract enough to represent several different types of presenters (GUI, Web, CLI, etc.), it actually just means “output”, this is a use case that may be good, but I am not completely confident about it.
Now, browse clean architecture applications on the Web , I only seem to find a way for people to interpret the output port as returning some DTO. This would be something like this:
Repository repository = new Repository();
UseCase useCase = new UseCase(repository);
Data data = useCase.getData();
Presenter presenter = new Presenter();
presenter.present(data);
< br />// I'm omitting the changes to the classes, which are fairly obvious
This is attractive because we are moving the responsibility of “calling” the presentation out of the use case, so the use case is no longer Care about knowing how to process the data, but just provide the data. In addition, in this In this case, we still have not broken the dependency rule, because the use case still does not know any information in the outer layer.
However, the use case no longer controls the moment when the actual presentation is executed (this may be useful, for example, in Do additional things at that moment, such as logging, or abort it completely if necessary). Also, please note that we lost the use case input port, because now the controller only uses the getData() method (this is our new output port). In addition, in my opinion, we have broken the principle of “tell, don’t ask” here, because we ask the interactor to use certain data to do something instead of telling it to do something actual. First place. p>
So, according to the clean architecture, are either of these two options a “correct” interpretation of the use case output port? Are they all feasible?
In this answer to another question, Robert Martin described a use case where the interactor called the presenter when reading the request. There is no mention of MVC, MVVC, etc., so I guess the clean architecture generally cannot Works well with MVC?
Clicking on the map causes either the placePinController to be invoked. It gathers the location of the click, and any other contextual data, constructs a placePinRequest data structure and passes it to the PlacePinInteractor which checks the location of the pin, validates it if necessary, create a Place entity to record the pin, constructs a EditPlaceReponse object and passes it to the EditPlacePresenter which brings up the place editor screen.
blockquote>
The possible explanation is that the application logic that will traditionally enter the controller is moved to the interactor, because we don’t want any application logic to leak outside the application layer. Therefore, the model will not call Demonstrator, because the interactor is not a model, but the actual implementation of the controller. The model is just the data structure passed. This seems to be confirmed by the following:
The software in this layer is a set of adapters that convert data from the format most convenient for the use cases and entities, to the format most convenient for some external agency such as the Database or the Web.
From the original article, talking about interface adapters. Since the controller must be just a thin adapter that converts one data format to another, it cannot contain any application logic, so move it to the interactor. p>
The article says that the use case and the gui (presenter) are independent, So the controller’s job is to talk to the use case (i.e. service or workflow) and the presenter
[Update 2017-08-29]
If the model uses presenter-interface , Then this is no longer a clean mvc, mvp or mvvm architecture, but something else.