Reputation: 524
It's my first try at DDD and I would like to get advise on modeling issues.
Here is my domain: The management of multiple schools.
2017-2018
for instance)My first doubt is in the modeling of schoolYear.
I already have the school entity as a root aggregate. My first approach was to make the school aggregate handle the addition of schoolYear (so that I can avoid duplicates, or that I can create the next schoolYear, …)
=> schoolYear is part of the school aggregate
But then I had to model classes and student scores… which depend on the schoolYear.
So in my classes aggregate, I have to hold a reference to a schoolYear… which breaks the rule that states
"Cannot hold a reference to an internal entity from an outside aggregate."
In my domain, a lot of entities are depending on a specific schoolYear. Maybe it should be an aggregate…
On the other hand, the schoolYear of a given class is used for searching classes.
Can I get some advice about this modeling issue?
Another depending question is about the identity of schoolYear.
Any advise on this?
Thanks a lot helping me enter the DDD world!
Upvotes: 1
Views: 1713
Reputation: 720
For your question about the identity of SchoolYear
. If you are sure that schoolId
will not change once it has been created then I would suggest to go with schoolId-year
instead of UUID, as it is more descriptive than UUID. But make sure that the combination, i.e schoolId-year
is globally unique if SchoolYear
is an aggregate.
Upvotes: -1
Reputation: 150614
To answer your question I had to make a few assumptions. So maybe my answer doesn't perfectly reflect your actual intentions, but I have tried to follow as closely as possible to what you described. Hence, please take my answer with a grain of salt.
First of all, what caught my eye is that you are thinking about an object model. Domain-driven design is less about the objects, but rather about the processes. So while you have focused on the nouns, I'd suggest to focus more on the verbs: What are the things that can have happened in your domain?
While thinking about this question it became clearer to me that the central thing is the class: Yes, you need to found a school initially, but once it has been founded, there aren't many actions taking place over time. Maybe it gets renamed, but that's it.
The same is true for a schoolYear. My assumption is (I don't know whether this is correct for your concrete scenario) that there is for example only a single school year 2017/2018 which is valid for all schools. Maybe this is different in your scenario, because different schools can have different school years, but I assumed them to be the same overall.
Moreover, there are teachers and students, which are pretty simple things as well.
This leaves us with class. Originally, a class gets setup for a specific school, and for a specific school year. Then you assign a teacher to it (I assume that there is only one teacher per class, and I'm also assuming that a single teacher can be assigned to multiple classes). Students then join the class, or leave. And finally, once in a year, you move the class to the next school year.
This means that class should be an aggregate, which knows to which school and school year it belongs, and which has a teacher, and contains a list of enrolled students. You have commands on this class, such as:
Then, school is just another aggregate, which has commands such as:
Again, schoolYear can be a simply aggregate, which has commands such as:
And for teacher and student - well, they are aggregates as well. I won't list the commands for them here explicitly, but I think you can come up with them on your own.
Finally, I believe that, as said, you should rather focus on the verbs and what can happen, than on the nouns. Once you do this you need to think about which verbs can happen at the same time, because they don't interfere with each other, and which verbs can't happen concurrently. This is what leads you to how to define your aggregates, as aggregates are transactional boundaries that limit which actions can happen at the same time, and which ones need to be run sequentially.
There is a nice description of how to do modeling with your team in the documentation of wolkenkit, a CQRS and event-sourcing framework for JavaScript and Node.js that my colleagues and I are working on. Maybe it is helpful for you.
Hope this helps :-)
Upvotes: 6