Search code examples
oopuml

can UML association classes restrictions be enforced statically?


Reading "UML @ Classroom" (2015):

In general, you cannot replace an association class with a “normal” class which is itself associated with the original two associated classes, as shown by the following example. Let us assume that we want to model that a student enrolls for at least one study program and has precisely one enrollment for each chosen study program. In turn, any number (≥ 0) of students can enroll for one specific study program. This situation is shown in Figure 4.19(a).

Figure 4.19(b) shows the attempt to model this situation with only “normal” classes. An enrollment is assigned to precisely one student and precisely one study program, while one study program is related to any number of enrollment objects. A student has at least one enrollment.

So far the requirements are met. However, if we examine the diagram more closely, we see that in Figure 4.19(b), a student can have multiple enrollments for one and the same study program, which is not the intention. In contrast, in Figure 4.19(a), a student can enroll for a specific study program only once.

Association class vs. Three "normal" classes

That is nice from a modeling point of view, but: can we really enforce this statically in an actual implementation in any OOP language or do we need to add code to validate additions and changes in runtime?


Solution

  • The belief that 4.19(a) would prevent duplicate enrolments is popular among people with an ERD background, and readers of Martin Fowler's UML distilled. This belief is however not founded - at least not according to UML 2.5:

    • In figure 4.19(a) a student can very well enroll multiple times in the same training program. For more explanations and a detailed justification based on the UML specs, see here.
    • Worse: even if the association would have {unique} at each end, the association class would still allow for duplicates, as strange as it sounds.

    To restrict multiple enrolments, you would have to add a constraint in the class diagram, e.g. an ambiguous { No duplicate enrolments for the same student and training program } or a more formal OCL constraint. The same constraint would then have to be translated in any OOP language relevant for the implementation.

    If you would implement your design with relational tables, the association class would be implemented with an association table. You could enforce the constraint very easily with the appropriate definition of a composite primary key, e.g. PRIMARY KEY (student_id, training_id) in SQL, if no duplicates should be allowed.

    An easy way to implement the constraint in other OOP languages would be to implement the association with a map/dictionary of tuples (e.g. a pair of suifent id and training id) to association class instances