I’m designing a shipping application and trying to use Clean Architecture. I’m trying to figure out where to hold state of a Shipment object so that I don’t have to re-instantiate a new object every time a user clicks on a button in the UI. Here is the flow.
Should the state of the shipment object be an instance variable on the UI Controller, Use Case Interactor or the Repository? Ideally, I'd like to save it somewhere so I don't need to keep creating a new object every time a user clicks a button on the UI.
Thank you in advance!
Can a DDD repository be stateful?
Yes, absolutely -- that was part of the point in the original description
A REPOSITORY represents all objects of a certain type as a conceptual set (usually emulated). It acts like a collection, except with more elaborate querying capability.... For each type of object that needs global access, create an object that can provide the illusion of an in memory collection of all objects of that type.
In other words, the point is to separate the application component from the implementation details of the collection. As far as the app can tell, the repository can be implemented as a stateful, in memory, key/value store.
Ideally, I'd like to save it somewhere so I don't need to keep creating a new object every time a user clicks a button on the UI.
As a matter of keeping your code easy to understand, you should probably just create a new object every time, and deal with the complications of caching only when you have a clear business case for it.
That said, there's absolutely no reason that the implementation of the repository can't include a cache of recently used objects. You just have to be willing to invest in the cache invalidation strategy.
Remember, Phil Karlton taught us years ago
There are only two hard things in Computer Science: cache invalidation and naming things.
Theoretically it is by definition always stateful. You are asking if a Repository can use a cache when loading/storing the Aggregates. So yes again, but. Caching is a complicated thing that should be avoided unless is necessary.
In this particularly case, using a cache hurts the horizontal scalability of the Application. It is hard to have multiple instances of it. It is hard to use optimistic locking at the database/persistence level, the Aggregate's version needs to be correctly set when loading an Aggregate (it must be the greatest) otherwise the expected version (the loaded version + 1) doesn't match. In other words, it is hard to invalidate the cache in an efficient way, as @VoiceOfUnreason said.
So, if you are willing to loose horizontal scalability then yes, you can cache the Aggregates.
P.S. this does not apply to Event sourced aggregate repositories. In that case, you could keep the snapshots in memory but still touch/query the Event store for the new events.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With