controlleruse-caseclean-architecturepresenter

clean architecture : can the preseter talk to to the controller?


in the clear architecture, what uncle bob suggested.

I have a lot of questions about how to correctly distribute the responsibility.

enter image description here

it seems that there is no relationship between controller and presenter. the controller's job is to take the input and trigger the use case and the presenter's job is to take the output data provided from the use case and display it on the view.

here it seems that the view very dumb object and its only function is to display the data to the UI, it makes sense in case the controller is invoked by an external agency only.

but how the controller is accessed in the case of the web?. the user interacts with the view so the view should hold the instance of the controller and enough intelligence to invoke the correct methods of the controller. in this case, the view. is not really a dumb object it has the intelligence to how to invoke the controller,

or it's the job of the presenter to invoke the controller? depending upon the Contax and then finally invoke the view to display the data.

or the controller is closely bonded to the view? so that all the intelligence exists in the controller only and the view transfers the raw event and data. But doing so the controller will know too much about the view and will be dependent on the view.

one more question, say suppose after invoking the use case, u which was success full but the UI want some more data to display the result to the UI.

so where does the logic of fetching more data reside?

  1. is it in the view hereafter the use case was successful the use case will invade the presenter, and the presenter will send the msg to view, then the view will request more data from the controller to display?

  2. is it in the Presenter? so after the use case was successful with the success message. then presenter will invoke the controller to get the additional data to display and pass it to the view.

  3. is it in the controller? where after getting the success return response from the use case the controller will again invoke the other use case which will display the additional data to the view via presenter.

  4. is it in the use case?. where the use case will itself decide to send additional data to display to the user, however, I am not convinced with this since it should not be up to the use case to think about which data is being presented, it will bind the use case to the one type of presentation since the same could not be a true presentation, for example, CLI might not require the additional data.

Also who actually creates the controller and presenter, is the main function creating every presenter and controller, or does the high-level controller create the low-level controller and presenter and pass it to the presenter?


Solution

  • but how the controller is accessed in the case of the web?. the user interacts with the view so the view should hold the instance of the controller and enough intelligence to invoke the correct methods of the controller. in this case, the view. is not really a dumb object it has the intelligence to how to invoke the controller,

    The term controller is highly overloaded. In case of a web application you have 2 kind of controller.

    Both controllers can have presenters. One is responsible for transforming the use case's response model to the rest representation for transfer and the other for transforming the http response to a ui model.

                                             http request
      +------+   event   +---------------+   ------------>  +-----------------+     +-------------+
      | View |  -------> | ui controller |                  | rest controller | --> | input port  |
      +------+           +---------------+   <------------  +-----------------+     +-------------+
         |                      |            http response           |          
         |                      |                                    |
         V                      V                                    V
      +----------+ update +---------------+                 +-----------------+     +-------------+
      |   model  | <----- | ui presenter  |                 | rest presenter  | <-- | output port |
      +----------+        +---------------+                 +-----------------+     +-------------+
    

    or it's the job of the presenter to invoke the controller? depending upon the Contex and then finally invoke the view to display the data.

    No, the controller uses a presenter. It instantiates a presenter and passes it to the input port. In a rich client application the presenter will update the ui model in a web application you have two presenteres, because you have to deal with the transport across the wire aspect as shown above.

    or the controller is closely bonded to the view? so that all the intelligence exists in the controller only and the view transfers the raw event and data. But doing so the controller will know too much about the view and will be dependent on the view.

    You usually separate the event listener from the controller part of the view to decouple them.

    +------+   event   +----------------+  implements  +---------------+  call +------------+
    | view |  -------> | event listener | <----------- | event handler | ----> | controller |
    +------+           +----------------+              +---------------+       +------------+
    

    You also often see that the controller is an event listener and implements the event handler part.

    one more question, say suppose after invoking the use case, u which was success full but the UI want some more data to display the result to the UI.

    so where does the logic of fetching more data reside?

    Usually the use case should provide all the data that the user interface needs. If the user interface needs to call another use case you integrate use cases in the ui. This also means that you don't have one application api. This often happens when microservice architectures are used.

    So when you need to integrate on the ui side, I would let the ui controller emit events (not ui event) so that other ui controllers can listen to them. For the ui controllers it doesn't matter if the trigger event is emitted from the view or from other controllers. Thus I would also implement an event handler for that.


    EDIT

    i didn't get the If the user interface needs to call another use case you integrate use cases in the ui. This also means that you don't have one application api could you please provide little bit more context/ex.

    Let's assume you have an application where a customer can place orders. An unregistered customer can also create an account when the order is placed, so that the customer can log in later to see all placed orders.

    If you have a dedicated application api the ui only talks to one service that is made for it's purpose and this service (application api ) integrates the other services. In this scenario the ui will only make one api call to it's app api. This call includes the order and maybe registration information. When the call is finished the order is placed and the user is registered.

                                            +--------------+
                                      +---> | user service |
                                      |     +--------------+
    +--------+         +---------+  --+  
    |   ui   |  ---->  | app api |  
    +--------+         +---------+  --+
                                      |     +---------------+
                                      +---> | order service |
                                            +---------------+
    

    On the other hand you can also integrate at the ui side. In this scenario the ui first calls the order service to place the order and then the user service to register a new user or vice versa.

                         +--------------+
                   +---> | user service |
                   |     +--------------+
    +--------+   --+  
    |   ui   |  
    +--------+   --+
                   |     +---------------+
                   +---> | order service |
                         +---------------+
    

    Both scenarios can be applied in a monolithic or microservice architecture.

    There is a lot more to discuss about pros and cons of both scenarios. But I have to stop here, because it would go far beyond your question.