Pergunta

I am still thinking about clean architecture and just ran into a question regarding the higher levels (Views and Presenters) I am posting Uncle Bobs picture first here that you remember what I am talking about:

enter image description here

Lets say I have a small application where CRUD operations can be performed for customers.

Lets also say there are three ways to output the customer data to the user:

  • A form component, where a new customer with name and birthdate can be updated.

(The same form is also used to create a new customer, but in this case I do not need to load existing data)

  • A detail component where the name and birthdate of the customer are shown on the screen.
  • A PDF-Export where a customer should be displayed in a PDF with the birthdate in US-Format. If the customer is exactly 60 years old, the birthdate should be decorated with special color - these customers get a present. :)

Now lets say I want to implement this. My approach for this looks like this:

enter image description here

You can see that I have only one class for output data (one file) and also just one abtract presenter class that gets the OutputData.

But then I have three concrete presenters with three concrete view models that are responsible for my views. Now my doubts:

  1. Is this correct? Did I understand the clean architecture?

  2. My concrete presenters and my viewmodels for the HTML form and the HTML detail are exactly the same. This feels redundant. Should I avoid this and re-use my view models for both scenarios? Or should I stick with the borders, as the requirements of the future might change for forms, so that I need seperate models/concrete presenters?

  3. If I finally want no US-Format in the date anymore, but lets say... european one. Do I need a new concrete presenter, just for this? Or should the presenter ask the use-case for the global format of the application and then decide on the base of that?

  4. If customers that are 60 should receive a birthday present - this logic has to be in a use case. But I am a little lost where this would go... Probably another use case that gets every night all customers from the repository that are 60 and sends a present... ? But this would not relate at all with the decoration in my view model? So the information about the number "60" would be in my viewmodel and my use case? Two redundant times? Or how?

Foi útil?

Solução

Is this correct? Did I understand the clean architecture?

If you want to create a solution consistent with clean architecture you have a number of issues.

enter image description here

Dependencies should only cross boundaries going in one direction. That keeps the inside from needing to know about the outside. That means the outside can change and the inside won't care. This also helps keep your object graph acyclical. It keeps code changes from cycling through your code. Instead of dependencies tending to form a maze they they tend to form trees.

My concrete presenters and my viewmodels for the HTML form and the HTML detail are exactly the same. This feels redundant. Should I avoid this and re-use my view models for both scenarios? Or should I stick with the borders, as the requirements of the future might change for forms, so that I need separate models/concrete presenters?

Your View Model and Output Data objects shouldn't be the same. If they are that means the Presenter hasn't done anything useful. It's not the views job to transform how data is presented. That's the presenters job.

If I finally want no US-Format in the date anymore, but lets say... european one. Do I need a new concrete presenter, just for this? Or should the presenter ask the use-case for the global format of the application and then decide on the base of that?

Your Database, and Entities should have an agreed on way to store dates. But your Presenters should be free to present those dates in any form they wish.

If customers that are 60 should receive a birthday present - this logic has to be in a use case. But I am a little lost where this would go... Probably another use case that gets every night all customers from the repository that are 60 and sends a present... ? But this would not relate at all with the decoration in my view model? So the information about the number "60" would be in my viewmodel and my use case? Two redundant times? Or how?

If a user typed in a date, or selected today's date, and sent that date to the correct Controller it would build an Input Data with that date in it, using a way to express dates that the Controller and Use Case agree on.

The Controller then calls the correct Use Case Interactor and passes the Input Data. The Use Case Interactor uses either the Entities or the Data Access (or both) to get a list of people with birthdays on this date and uses that list to build Output Data. Output Data need not be a result set. It can conform to any structure that the Use Case and Presenter agree on. It may simply be a collection.

The Use Case calls the Presenter and passes the Output Data. The Presenter is now free to put last name first, first name first, draft happy birthday emails to be sent to each person, or send one email with a list of these people to a florist. Which one it does depends entirely on which presenter you configured to receive this.

Views should not do real work. They should be striped of interesting logic and simply be things you throw data at. Data that is already in its final form.

Licenciado em: CC-BY-SA com atribuição
scroll top