Reputation: 1082
We want to model a warehouse application. Let us assume we identified the following real world objects:
There are the following constraints:
For the start we have one operation:
Of course this is very simplified.
How should this be modelled?
Stockitem could be a value object I think. One solution would be to model the whole warehouse as an aggregate with palette and compartment entities. The move operation could be implemented without any problems in this case regarding its constraints (invariants). But this approach has obvious drawbacks. The Event log for this aggregate will grow infinitely. Two move operations could not be executed in parallel because of the aggregate versioning and so on. And from a ddd point of view, it feels not right for me.
Another approach would be to make each palette and each compartment its own aggregate. But how would the move operation be implemented then?
Problem 1 : Who loads referenced aggregates?
I think it should stick to the palette. The palette could reference the compartment it is in (its an aggregat). But how is this reference implemented (CQRS/ES)? The Comandhandler of the move command obviously will load the palette aggregate from the palette repository and call the move method on it. Who loads the referenced compartment? And who loads the compartment it should be moved to? I read that aggregates should not access repositories. Should the commandhandler load both compartments? Should the compartments be given to the move method as parameters? Or should the commandhandler set the current compartment to the palette and give the target compartment as a parameter?
Problem 2 & 3 : Constraints and bidirectional association between aggregates
What about the constraints? To check if the target compartment is empty, the compartment needs to know the palette that is stored in it. This would be a bidirectional association that should be avoided. And because they are different aggregates, they could not be updated in the same transaction. Has the palette to fire a domain event to inform the compartment that it will move to it? Has it to be implemented as a saga with undo action? What if two moves conflict, one wins, but the loosing palette could not be moved back, because the old compartment is filled up in the meantime?
This all seems very complicated to me regarding the really simple problem.
In the books and the examples it seems all so clear. But if I try to use it, I seem to do it wrong.
Could somebody guide me in the right direction please?
Upvotes: 4
Views: 1838
Reputation: 15907
You should just start object modeling the behaviour, and don't think about aggregates and value objects at all. Once you've modeled the needed behaviour, you'll know what are the entities, aggregates, roots and value objects.
In the explanations by Vaughn Vernon he makes it clear that you need to work out the details of what you need before you can make these decisions.
Upvotes: 1
Reputation: 14072
Problem 1
I think you need to do some transactional analysis in addition to the business analysis here.
If your domain is highly collaborative (which is what DDD is recommended for), how often do moves to a given compartment happen ? Would it be feasible contention-wise for the Move operation to happen under a transaction that spans across the 2 Compartment
aggregates (source and target) ? Or would eventual consistency suffice, where the source Compartment would signal the world via an event that the Palette has left it, and the target Compartment would somehow be informed later, in an asynchronous way, that the Palette is joining it ?
A palette floating "in limbo" for a small amount of time can be perfectly acceptable, that's something you need to ask a domain expert about.
Problem 2
A bidirectional association is not the only solution. You could ask the PaletteRepository
for all the Palettes that have CompartmentID X. Alternatively, Compartment could (should) have a list of Palette IDs, not a full reference to them.
Overall, I think you should look first if there's a business implication/answer to all the design questions you're asking yourself. The domain expert will usually have an educated opinion on whether eventual consistency is realistic or immediate consistency is required, what should happen in case of conflict, etc.
Upvotes: 1