I have also found the answer I was looking for in a link posted by Johanna ( https://groups.google.com/d/msg/dddcqrs/toU9nBeXWkQ/hyVX8QjS6gIJ) about loading the same stream into a different aggregate when the original aggregate transitions to a new state. Previously I was trying to do this by creating another aggregate out of the first one but now I can see how it could be done differently. Only need to solve snapshotting problem when taking this road.
this is perfectly ok a stream can be modeled by many aggregates and in many cases changed by many!
--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
can even be different bcs at times but yes if they dont understand skip
to be fair i have only used the strategy twice... however it fits in well with the event sourcing mental model.
Time might be a natural boundary to split up stream's along (e.g. New stream for each quarterly period, ...).
Given the requirement “When the system is asked to DoSomethingActive on an Account, if the Account is Active then SomethingActive should be Done. If the Account is Closed, then it should record that SomethingActiveWasNotDoneBecauseTheAccountIsClosed.”
To implement this we need to:
-Select and hydrate the object that will fulfill the DoSomethingActive command.
-If the Account is Open, publish SomethingActiveDone.
-If the Account is Closed, publish SomethingActiveNotDoneBecauseAccountIsClosed.
Whoever selects the object would use the event stream to determine the current state of the aggregate (open or closed). If we use multiple aggregates, and the selector were to make the wrong choice, then we end up with a broken invariant. So the selector needs to be responsible for protecting the aggregate’s invariant. Does that make the selector the aggregate root for both aggregates? What about the DDD guideline that all access to the aggregate should go through the aggregate root? Does that mean all access to either aggregate would need to go through the selector? Could we argue that aggregate root is a role whose implementation could be shared by multiple classes?
Once the object is selected, it must be asked to do something active. This is where we meet Greg's state pattern article, which concludes:
"Do some of the data/behavior only make sense in certain states? If so use three separate classes. Going along with this, if we find “throws” in our state implementors we should realize through LSP that we are doing something bad."
The way that I wrote the requirement, I would say all of the states do have behavior for all of the commands and none of them throw. ClosedAccount publishes a different event than OpenAccount, but both publish an event.
If, instead, I write the requirement as "If the Account is Closed, then it should do nothing." then as Greg pointed out, state pattern would be an LSP violation.
Looking forward to all of your thoughts,
Johanna
- You might want to rephrase this because the ubiquitous language seems fractured.
- Here's something to ponder on: What if I were to make the state an object is in part of my invariant definition?
- As for putting invariant checking in an object other than the Aggregate's root, reread p. 144 of The Blue Book.
Still, I get the impression we're discussing two things, not one. One is about making sure invariants that are applicable across time and aggregate representations (e.g. using different classes) get adhered to. The other is about invariants not being applicable if you're in a different state of the lifecycle machine.