13

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?

  • 2
    That does not address your question but I suggest you use Alistair Cockburn’s Hexagonal architecture instead. Robert Martin’s Clean architecture draws inspiration from it but is uselessly complicated and not very consistent. See this excellent article on the Hexagonal architecture. – Maggyero Apr 3 at 12:24
  • 1
    Well... currently I am learning the clean architecture. The example from my question is made up to get an understanding. But I will read your article anyway :) – David Mason Apr 3 at 12:53
  • 3
    Make sure you're asking questions like "what purpose does this serve? How does it benefit my application?" – Robert Harvey Apr 3 at 12:59
13

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.

| improve this answer | |
  • 1
    Thanks for that detailed explanation. I read already some articles of you here and learned a lot from the way you explain things. Really! – David Mason Apr 4 at 18:31
  • 1
    Unfortunately in my drawing I made a mistake - of course the concrete presenters cross the line to the right. Sorry - my visio skills are the reason - i corrected my picture. Now two other questions: If I add the field "age" as a number field in my HTML-form, I also have to put this age field in my ViewModel. If the customer edit form is called later, again to update the age, the viewmodel should send the current age back to the form. But in this case the age would still be an int, not string and not a bool. But in Martins book I read only strings and bools are allowed in a ViewModel. – David Mason Apr 4 at 18:35
  • 1
    So What to do in that case? Second question: Why does the view not know about the controller? Somehow the user needs to interact with the controller - in my opinion through the view! So shouldnt there be a sharp headed arrow from the view to the controller box? Why is this missing in all diagrams I find? – David Mason Apr 4 at 18:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.