Canemacchina
Canemacchina

Reputation: 179

Clean Architecture: controller and presenter should always be separate classes or can be the same?

I understand the purpose of controllers and presenters in Clean Architecture and what I am saying is not that the use case should call the controller to present data (or, at least, knowing it has to call the controller), but suppose we have set up the interface part of our application in this way: (pseudocode)

interface OutputPort {
    + present(response: Response)
}

interface InputPort {
    + run(data: inptuData)
}

class UseCase implements InputPort  {
    - presenter: OutputPort

    + run(data: InputData) {
        ...
        response: Response = ...
        this.presenter.present(response)
    }
}

In this situation, our UseCase is perfectly unaware of external circles. It implements an InputPort interface to expose an API to let the external circle call him, and it requires an OutputPort (in Clean Architecture the Presenter) that will be used to pass and "display" results.

So now normally we have:

class Presenter implements OutputPort {
    + present(response: Response) {
        ...
    }
}

class Controller {

    - presenter: Presenter;

    + executeUseCase() {
        data: InputData = ...
        useCase: UseCase = UseCase(presenter)
        useCase.run(data)
    }
}

why instead I cannot do this?

class Controller implements OutputPort {

    + present(response: Response) {
        ...
    }

    + executeUseCase() {
        data: InputData = ...
        useCase: UseCase = UseCase(this)
        useCase.run(data)
    }
}

It's just for SRP purpose or there are other reasons? Suppose the controller and Presenter are short enough and make use of same objects, is not worthier maintain the two implementations in a single class until the code requires the split?

I mean, every time we talk about the Clean Architecture, we usually think at web applications or mobile applications, where the interaction with the external world are always users and UI, so in that case, is quite clear that maintain the two classes separate is a benefit. But suppose the external actor is an external API that could send a signal to inform us to perform an action and should receive signals based on the action performed. In this situations, if I create a separate Controller and Presenter, I should give both a reference to the external API: to the controller to let him listen for the signal and trigger the use case, to the Presenter to let him send a signal to the API at the end of the use case. Considering the simplicity of this interaction, is not better to let the controller and the presenter be the same class (although still implementing a separate interface to let be open to a future split) to avoid spread in the application the knowledge of the external API?

Upvotes: 3

Views: 1889

Answers (1)

René Link
René Link

Reputation: 51333

First of all your dependencies are compliant with the clean architecture in both cases.

Suppose the controller and Presenter are short enough and make use of same objects, is not worthier maintain the two implementations in a single class until the code requires the split?

You can do that, but if you separate the two they might be easier to test. Because you will not need to setup the controller's dependencies when you want to test the presenter logic and vice verse.

I mean, every time we talk about the Clean Architecture, we usually think at web applications or mobile applications, where the interaction with the external world are always users and UI, so in that case, is quite clear that maintain the two classes separate is a benefit. But suppose the external actor is an external API that could send a signal to inform us to perform an action and should receive signals based on the action performed.

If you use a presenter you usually deal with a user interface, but the concept of the presenter can be seen more general.

If the controller is invoked by another external system. This system also want's the data in some format. Maybe it is a binary format, but maybe it is XML or JSon. In all cases you have to deal with the transformation of the use case's output to the way it is presented to the outside. Thus a presenter is not necessarly a UI component.

So the term presenter, serializer or maybe formatter are all based upon the same concept. And if you separate it in an own class you can easily test it.

Here is diagram that I drawed to show how the clean architecture can be applied in a messaging environment. E.g. JMS. This would be an architecture were the outside is definitely not a user interface. Of course the MessageProducer should use a presenter or serializer or whatever you call it to create outgoing messages. It is an older drawing. Maybe I will change it some time.

Clean Architecture in a messaging environment

As long as you honor the dependency rules of the clean architecture, you can easily replace the way your use cases are presented to the outside.

Upvotes: 2

Related Questions