In trying to learn DDD by applying it to a new project, I've run into an obstacle.
Here's a simplified structure of my very real domain: a project has many components which have many objectives which have many contracts for carrying out said objectives.
Project A
|_Component A
|_Component B
|_Objective A
|_Contract A
|_Contract B
Rule: Each project and contract is allocated some amount of money. Invariant: The sum of all the contracts' funds in a project shouldn't exceed the project's funds.
This suggests that adding new contracts to an objective should be done through the project since it's the only entity that knows how much money it has. In DDD words, to enforce consistency, projects and objectives should be part of the same aggregate, with the project as its root.
However, intuitively, this doesn't make sense. It is objectives that contracts belong to, not projects. They exist first and foremost to help complete objectives and only indirectly projects. "Add a contract to an objective," sounds more natural than, "Add a contract to a project," too, and the code would reflect that: objective.add_contract(new_contract)
vs project.add_contract_to_objective(objective, new_contract)
.
I'm also worried that this design might turn the project into a kind of god object.
Am I conflating aggregates with the has/belongs to relationship, or is my gut feeling onto something? Should I, perhaps, create a service—though I don't know what I'd call it, and I think that's a red flag—that copies the project's funds and passes it to the objective, like objective.add_contract(new_contract, project_funding)
?
(On second thought, that sounds like a ticket to the anemic domain model I've heard so much about.)