proophsoftware / es-emergency-call

Struggling with CQRS, A+ES, DDD? We can help you!
BSD 3-Clause "New" or "Revised" License
26 stars 0 forks source link

Samples, Locations and PickLists / How to avoid bidirectional associations #4

Open UFOMelkor opened 7 years ago

UFOMelkor commented 7 years ago

Let's start with a short introduction into the domain. We store samples, that (mostly) consist of human body fluid, within large refrigerators. The samples are not stored directly in the refrigerators, because this would make it hard to find them again. Therefore the refrigerators are divided with towers, drawers, shelfs, etc. For this specific problem it is enough to know that the samples are stored into locations that can be moved into other locations.

Next thing existing in the domain are pick lists. Employees search some samples they need an the computer and create a pick list with them. Sometimes later somebody takes the pick list and goes to the different locations to pick the samples. To minimize the distance to walk, the samples are automatically ordered on the pick list by their distance to each other.

There are some situations where IMHO a bidirectional association is necessary between two aggregates.

Let's have a look at one scenario and one part of my model:

Given a pick list with two samples was produced
When someone moves one sample to another location
Then the pick list should be re-sorted
Command Aggregate Event
MoveSampleToLocation Sample.moveToLocation() SampleWasMovedToLocation
NotifySampleAboutPickList Sample.notifyAboutPickList() SampleWasNotifiedAboutPickList
PickSample Sample.pick() SampleWasPicked
ProducePickList PickList::produce() PickListWasProduced
ResortPickList PickList.resort() PickListWasResorted
TickOffSample PickList.tickOff() SampleWasTickedOffFromPickList
NotifyAboutSamplePickedOnOtherList PickList.tryToSubstitute() SampleWasSubstituted/SampleWasNotSubstituted

ProcessManagers:

Event Command Target Command
SampleWasMovedToLocation ∀ lists ResortPickList
SampleWasPicked picking list TickOffSample
SampleWasPicked ∀ other lists NotifyAboutSamplePickedOnOtherList
PickListWasProduced ∀ samples NotifySampleAboutPicktList
SampleWasSubstituted sample NotifySampleAboutPIckList

The thing I'm worried about: Samples knowing about the pick list that contain them. It does not sound like something, a sample should know. But I don't know how to dispatch commands for all concerned pick lists otherwise. The only thing that would come to my mind are stateful process managers …

codeliner commented 7 years ago

I agree that NotifySampleAboutPickList sounds like a technical command that is not really part of the domain language.

What about using a read model instead of stateful process managers?

$pickLists = $pickListFinder->findBySample($sampleWasMovedToLocation->sampleId())