英文:
can UML association classes restrictions be enforced statically?
问题
阅读 "UML @ Classroom" (2015):
总的来说,您不能用一个“普通”类来替代关联类,该普通类本身与原始的两个关联类相关联,如下面的示例所示。假设我们想要建模一个学生至少报名一个学习项目,并且为每个选择的学习项目恰好有一个注册的情况。反过来,任意数量(≥ 0)的学生都可以报名一个特定的学习项目。这种情况在图4.19(a)中显示。
图4.19(b) 显示了尝试只使用“普通”类来建模这种情况的情况。一个注册与恰好一个学生和恰好一个学习项目相关联,而一个学习项目与任意数量的注册对象相关联。一个学生至少有一个注册。
到目前为止,要求都得到满足。然而,如果我们仔细检查图表,我们会发现在图4.19(b)中,一个学生可以为同一个学习项目拥有多个注册,这不是我们的意图。相比之下,在图4.19(a)中,一个学生只能为特定的学习项目注册一次。
这在建模角度上是很好的,但是:我们真的可以在任何面向对象的编程语言的实际实现中静态地强制执行这个规则吗?还是我们需要添加代码来验证运行时的添加和更改?
英文:
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.
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?
答案1
得分: 1
4.19(a)的信仰会防止重复注册在具有ERD背景和Martin Fowler的《UML精要》读者中很受欢迎。然而,这种信仰并没有根据 - 至少根据UML 2.5:
- 在图4.19(a)中,一个学生完全可以多次在同一个培训计划中注册。有关更多解释和基于UML规范的详细理由,请参见此处。
- 更糟糕的是:即使关联在每一端都有
{unique}
,关联类仍然允许重复,尽管听起来很奇怪。
要限制多次注册,您需要在类图中添加一个约束,例如模糊的{同一学生和培训计划不能有重复注册}
或更正式的OCL约束。然后,同样的约束必须在任何适用于实现的面向对象编程语言中进行翻译。
如果您使用关系表来实现设计,关联类将使用关联表来实现。如果不允许重复,您可以通过适当定义复合主键轻松强制执行约束,例如在SQL中使用PRIMARY KEY (student_id, training_id)
。
在其他面向对象编程语言中实现约束的简单方法是使用元组的映射/字典来实现关联(例如,一对学生ID和培训ID的元组)到关联类实例。
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论