Clean Architecture details

1,484 views
Skip to first unread message

Bennie Copeland

unread,
Aug 19, 2013, 8:51:43 AM8/19/13
to clean-code...@googlegroups.com
Hi all. I'm trying to figure out a couple of details when it comes to clean architecture.

  1. According to this post on the clean coders group, it sounds like the interactor layer is supposed to be stateless. So where should intermediate application state live? The example I have is an order system. The user creates an order and adds line items to it, but depending on their customer ID, they cannot order certain products. When they try to add a prohibited item to the order, they should be notified of the error and the item not added. The order shouldn't be saved to the database until the user clicks Submit Order. The business logic of whether they can add a certain lineitem should live in the interactor layer I would expect. When the user clicks Create Order, I expect the AddOrder interactor would create an Order object. When the user adds a product to the order, I expect the AddLineItem interactor to verify the product can be added, and then add it to the order. But where does these intermediate objects live that get built, but are not ready to save in the database? If the interactor layer is stateless, they can't live there. If the delivery mechanism shouldn't know about the entity objects (and only deals in DTOs returned by the interactors), then they can't live there either. That only leaves the Persistence layer in my mind that now has the responsibility to track the serialized objects in the database and the nonserialized objects in memory.

    I could also see the interactor layer being stateless, but having two persistence layers. An AppState object and a Persistence object. Then the CreateOrder and AddLineItem could create the objects and put them into the injected AppState object until the user clicks Submit Order. Then the SubmitOrder interactor takes the built object graph from AppState and saves it to disk/database through the Persistence object.

  2. What is the relationship between the delivery mechanism and the persistence layer? Should the delivery mechanism be calling methods on the persistence layer directly, or should it only interact with it through the interactors? Looking at the TDD tests in Agile PPP C#, the persistence layer is called directly, and if tests are examples of use, then it looks like I can call directly into the persistence layer from the UI. Something about that feels wrong to me because that allows the UI to bypass the interactor layer. But if it is the UI that is responsible for injecting the persistence layer into the interactors, then I don't see a way to prevent it other than a stern "Don't do that"

Thanks,

Bennie

Uncle Bob

unread,
Aug 21, 2013, 11:01:47 AM8/21/13
to clean-code...@googlegroups.com
It's always best if the interactors are stateless.  That doesn't mean that they don't have access to state information, it just means that they don't keep any state locally.  Another way to say this is that two consecutive calls to an interactor can be completely unrelated and need not share state information.

Where is the state stored?  In the DB of course (below a gateway interface!).  How does the interactor access that state?  Probably some kind of session code.

In your particular case, when you are building up an order, the entities getting built up incrementally are not complete orders.  You might want to treat them as separate entities named partial orders.  Only when the order is complete and submitted do you actually create an order entity.

The relationship between delivery and persistence is non-existent.  The delivery mechanism has no idea that the persistence mechanism exists.  On the input side, all data from the delivery system is passed into interactors via plain old data structures.  On the output side, the interactors pass data to the presenters using plain old data structures.  The presenters transform those data structures into presentation data structures that are ready for the delivery mechanism to present.

Milad Bourhani

unread,
Nov 26, 2013, 4:24:06 PM11/26/13
to clean-code...@googlegroups.com
Hi Uncle Bob!

Sorry to bring up a three-month old topic, but I've just joined this group ;-)

Just to get Clean Architecture right, apart from interactors being idempotent, which is of course a desirable quality, what's actually wrong with interactors being stateful?

More to the point, I often find it useful to code interactors a bit like builders, collecting incremental information from the user in order to execute something meaningful at the end (wizard-style).

In that case, wouldn't that partial information be just too fragmented and out-of-context to "deserve" being persisted on a DB? And wouldn't keeping that state in the interactor make it more unit-testable since I wouldn't have to mock out the DB when those partial information are needed?

Thanks,
Milad

Uncle Bob

unread,
Nov 27, 2013, 2:01:48 PM11/27/13
to clean-code...@googlegroups.com
Milad,  It's generally better to externalize stateful data from the iteractors.  In that case of a wizard, the progress of the wizard can be established in a document which is external to the interactors.  

Milad Bourhani

unread,
Nov 27, 2013, 4:18:34 PM11/27/13
to clean-code...@googlegroups.com
Thank you for the answer, which sounds right, but also gets me thinking about where the document should live.

The options I see are:
- the document is part of the request model passed to the interactor; this however leads to the document being passed back and forth between presenter and interactor.. wouldn't it be bad?
- the document lives in the presenter or the controller

Maybe I'm missing something here ;)

Uncle Bob

unread,
Dec 2, 2013, 6:02:03 AM12/2/13
to clean-code...@googlegroups.com
The document would be in your business entities.  The interactors would interpret those entities into response models that the presenters could use.

Milad Bourhani

unread,
Dec 3, 2013, 4:32:01 PM12/3/13
to clean-code...@googlegroups.com
I didn't consider these partially completed wizard-documents to be entities themselves, but it makes sense.

I'm still in the process of fitting the Clean Architecture in our system at work, and stateful/stateless interactors is one of the details that have to be worked out.

Thank you for the explanation ;-)

Jon Reid

unread,
Dec 5, 2013, 12:52:09 PM12/5/13
to clean-code...@googlegroups.com
On Dec 3, 2013, at 1:32 PM, Milad Bourhani <milad.b...@gmail.com> wrote:

I'm still in the process of fitting the Clean Architecture in our system at work, and stateful/stateless interactors is one of the details that have to be worked out.

My first stab at an interactor had state. I was so proud of it, until I read this. I had to think it over, until finally reaching the a-ha! moment a few minutes ago:

My interactor gets results from a web service. Since this is for a mobile app, the service breaks the results into pages. I had the interactor keeping track of the page number, so I could ask it “getFirstPage” to start from page 1, then multiple calls to "getNextPage”. The results were accumulated in the entity.

Moving the page number field from the interactor to the entity changes things. Now the the interactor can actually disappear entirely, and be re-created later. Its lifecycle is no longer an issue, because the entity contains everything needed to continue.

Thanks, Milad (and Uncle Bob of course)!
- Jon

Milad Bourhani

unread,
Dec 5, 2013, 4:18:10 PM12/5/13
to clean-code...@googlegroups.com
No problem, but the merit is all Uncle Bob's ;-)
Reply all
Reply to author
Forward
0 new messages