I am modeling my project, which I will subsequently implement in Java, using UML. My project involves managing a gym. More specifically, I am currently modeling a class diagram that allows me to organize workout routines (see classes in yellow):
I have interpreted workout routines as a list of lists: a workout routine is a list of 'WorkoutDay' classes (from 1 to 7), which in turn are a list of 'ExercisesForTheWorkoutRoutine' classes. However, the 'ExercisesForTheWorkoutRoutine' in the workoutRoutines differ from the 'Exercise' class (which only have a name of type String, and a status of type enumeration) because they additionally have a recovery time, a number of repetitions, and a number of sets.
My doubt is about how to connect the two classes 'ExercisesForTheWorkoutRoutine' and 'Exercise'. Because I need that when an exercise is removed from the 'exercises' list (for example, the gym no longer has a certain piece of equipment), all instances of 'exercisesForTheWorkoutRoutine' with the same name as the removed exercise are also eliminated.
I don't know if it's a generalization, a simple association (in this case, I think of a cardinality of 1..1), or an aggregation.
When in doubt, prefer composition over inheritance. "Composition" in this popular advice refers to OOP object composition, that is in UML expressed as an association, a shared aggregation or a composite aggregation.
Indeed the Exercise
seems to be a kind of template or reference that might very well have other attributes (e.g. status) and completely different behaviors than ExerciseForWorkout
. You could for example imagine that Exercise
could later be enriched with links to videos or be associated to an author for digital right management whereas these informations might not be relevant in the ExerciseForWorkout
. So the generalisation would not be suitable.
You should consider inheritance only if an ExerciseForWorkout
object could always replace an Exercise
object. And this does not seem to be the case here.
Nevertheless from a modeling perspective you could wonder if the ExerciseForWorkout
is always related to an Exercise
, which your 1..1 multiplicity (in UML this is not called "cardinality") suggests. In this case you should ask yourself if it really needs to duplicate the name of the reference
exercise. Two other alternatives would be 1) to use composition, since the deletion of the Exercise
(composite) would cause delation of the ExerciseForWorkout
; 2) to consider ExerciseForWorkout
as an association class between Exercise
and WorkoutDay
.
Some unrelated remarks: