A common definition of an aggregate is by a consistency boundary. In
memory, that implies that there must be no direct references (i.e.
pointers) between two aggregates.
If you use a RDBMS 3nf storage for your domain model state, it follows
that you can only use ID storage to reference other aggregates'
entities, not FKs.
Once your system grows beyond a single server, that other aggregate is
possibly not even persisted on the same DB server.
Further down that road:
Once you get rid of DB table relationships, the question arises why to
use a 3nf model in the first place.
So you start using 1NF/key-value stores. Then you ask yourself why to
use a RDBMS is the first place.
Then you start using document DBs :)
Cheers
Phil
Well what about reports? What if I want to get an aggregate of sales across customers? Well, that's what the read model is for. But the Command Model should only deal with orders through the Customer.
Cheers
Phil
-----Original Message-----
From: ddd...@googlegroups.com [mailto:ddd...@googlegroups.com] On Behalf Of Philip Jander
Sent: Wednesday, October 26, 2011 10:57 AM
To: ddd...@googlegroups.com
Subject: Re: [DDD/CQRS] Re: Aggreate Root holding reference to another Aggregate,how do i set up the dependencies ?
Phil
This is what Peter Coad's book Java Modeling in Color in UML boils down to. Break your system down into entities (party, place, or thing), transactions, and the roles entities play within those transactions. Now that you've identified those objects, you can apply the concepts of DDD to further refine your model.
For every transaction there is an initiator, an entity who starts the transaction. They act as the Aggregate Root for the transaction. So John Doe is the Aggregate Root for a Visit. Jack Sprat is the Aggregate Root for Treating the Patient. The Clinic is the Aggregate Root for Employing Jack Sprat, and Billing the Patient.
The Doctor and Patient aren't aggregate roots...they are roles in the Treatment aggregate. Jack Sprat as the initiator of the Treatment serves as the Aggregate Root (you could argue that his Role as Doctor is the root, but you get to a Party's role through the Party). In short, the Role (Doctor, Patient) is not the Aggregate Root. The Party that plays the Role should be the AR. And the Aggregate boundary forms around the Transaction.
A bit of further analysis might uncover that we don't care about the Patient and his Visit...but rather about the Clinic Admitting a Patient. So now rather than looking at a specific patient and looking at his visits, we can look at the clinic as a whole and look at all Admissions. And if we need to we can filter it down to a specific patient and the times he was Admitted to the Clinic.
There is another object type that we aren't discussing here, and those are what Coad calls Descriptions and Evans calls Value Objects. An example would be during John Doe's Treatment, Jack Sprat Prescribes (another event) a dosage of Aspirin. Aspirin is a Value Object, it describes the Drug the patient is supposed to take with the Prescription. When John Doe takes the Prescription to the Pharmacist, it doesn't matter specifically which pills are given to John, just that they are Aspirin.
Note how there is a flow to this story, one transaction is usually followed by another. A Visit is followed by a Treatment followed by a Billing and eventually a Payment. Looks a lot like a Value Stream right? That's what you should hone in on when modeling a system, how does your application result in value being provided to the stakeholder. If you get that right, you'll have happy stakeholders.
This model would be totally different if we were creating a Personal HealthCare Management System (like Microsoft HealthVault) where the "stakeholder" is an individual tracking his health and doctor visits, medication, exercise, fitness, etc.
Udi Dahan gives a talk about making roles explicit and how it impacts domain discovery and simplifying a model. Although he doesn't mention Color Modeling specifically, it's the same idea. I can attest to how I've become a better modeler by following this approach. Hopefully this helps you on your path as well.
Sent from my iPhone