How to model an action that involves more than one model?
https://softwareengineering.stackexchange.com/questions/420289
-
20-03-2021 - |
Question
I'd like to start by saying that I'm new to DDD and I'm creating a hobby system to practice some concepts, so this question might be trivial, but not so much for me.
I have the following scenario:
I have a given user that should be able to add exercise to the system, so I have two models User
and Exercise
, and I have a method addExercise
which should create a new exercise and save it to database by using a repository. This method would mostly validate Exercise
data before saving to database, but there would be some validations regarding the user (such as verify if exercise wasn't previously created by this user)
I have thought about three ways to do that:
Add an
addExercise
method to User model. Problems I see in this approach:a)
User
model would need to know aboutExercise
in order to implementaddExercise
.b)
User
model would need a repository to save theExercise
in database.Add an
addExercise
method toUserService
, since adding exercise is an operation from user, this seems ok, but when I start thinking about implementation, I would haveUserService
to know aboutExercise
andExerciseRepository
.Add an
addExercise
method toExerciseService
, which I believe it is fine, but I'm afraid I might be missing something.
So, in my opinion, from a business point of view, addExercise
should be a method in User
model, but when I think about implementation details, it seems to make more sense option 3), but I want to know if this is in fact the correct option.
Also, I have some other questions:
I) Is it normal for a given model A to be able to create another model B or have a repository from a model B inside of it ? Or could a model A receive a repository that work with model A ?
II) Is it ok for a service A to receive repositories that work with model B ?
Solution
You want to use your third option. In systems with users basically everything is user focused, but putting that functionality in a user model doesn't make sense in most cases. If exercise is a domain model you want, then the ability to add one 100% belongs to the exercise domain/service. The reason for this is because a domain model should be responsible for creating/updating itself. If exercise requires a reference to user that's fine, DDD allows for models to reference other models. The best practice is basically using the same concept as foreign keys in a database.