你如何在同一个 UML 类图中表示同一个实体类型类的不同版本?

问题描述

我正在尝试弄清楚如何使用以下属性对情况进行建模:

  • 域中有一组实体类型 Ei...Ej 和一组实体类型 Ri...Rj 之间的关系类型;
  • 可以同时区分对系统不同部分重要的实体和关系类型的至少两个不同版本

在最简单的情况下,这些不同的版本可能是“实时数据”版本和“最后批准的快照”版本。在这种情况下,对系统的不同部分很重要可能会转化为以下内容

  • 特权较少的参与者和用例只能与“最后批准的快照”版本一起使用;
  • 同时有更多具有相同或不同用例集的特权参与者,可以使用“实时数据”版本;
  • 实体类型 Ex...Ey 与实体 ei...ej 形成关系来自“上次批准的快照”版本或其约束引用实体 ei...ej 的属性值来自“上次批准的快照”版本;
  • 同时存在不同的实体类型 Ea...Eb,它们要么与来自“实时数据”版本的实体 ei...ej 形成关系,要么其约束引用实体 ei...ej 的属性值来自“实时数据”版本。

如果我想在同一个图表上显示上述示例中的所有实体类型 Ei...Ej、Ex...Ey 和 Ea...Eb,以及它们之间的约束和关系,我该怎么做?

我曾考虑为同一实体类型使用两个不同的类:一个类表示该实体类型的“上次批准的快照”版本,另一个类表示该类型的“实时数据”版本。

但我不太喜欢这种方法

  • 这似乎是多余的;
  • 我实际上不确定代表同一实体类型的两个不同版本的两个类之间存在什么样的关系以及如何在图表中表示该关系(也许从标准配置文件中“派生”构造型在这里是合适的,但是我不确定)。

编辑

不幸的是,我无法使用我工作中的例子,所以我想出了这个完全虚构的例子,但它也部分模仿了我最近试图解决的问题。我将使用流行的“WorksInUsing”协会来表达敬意。这将使问题更加具体。

另外,需要明确的是,我正在尝试创建概念模型,而不是 OOP/关系设计/实现模型。

让我们假设一个实体类型 Employee。

假设有一个名为“SkillAdministrator”的角色管理以下实体和关系类型:

让我们假设,上述所有实体和关系类型的更改很少发生,但是当它们发生时,它们会以非常大的批量发生,我们的技能管理员需要相当长的时间来处理每个此类更改。

在完成更改处理后,他运行 PublishChange 用例,该用例创建实体和关系类型 Skill 和 KNownSkill 的快照,并使该快照可供系统的其他用户使用。

现在让我们假设一个名为 Manager 的角色管理以下实体和关系类型:

只有上次运行 PublishChange 用例时存在的技能才能在 WorksInUsing 关联中发挥作用。此外,KNownSkill 对是三元组 WorksInUsing 的先决条件,但同样仅限于上次运行 PublishChange 用例时存在的已知技能对。

在 Manager 管理 WorksInUsing 关联的同时,SkillAdministrator 可以开始处理他管理的实体和关系类型的下一个重大变化。经理不会看到这些更改,直到再次运行 PublishChange 用例。

(根据域,有多种不同的方法可以处理系统管理员删除特定技能或已知技能关联,然后应用这些更改 - 在最简单的情况下,两种类型都可以假定为永久,因此新实例可以添加但不能删除现有实例,例如法律以这种方式工作)

解决方法

其实没有太多选择。要么你必须区分继承 enter image description here 或通过旗帜 enter image description here

这两种解决方案各有利弊,具体取决于域/上下文。在这种情况下,我只会倾向于使用标志变体。仅仅是因为它代表了一种可以改变的状态(另请参阅 here 所建议的 @Christophe)。选择继承会使未经批准的快照成为批准的快照变得复杂(您需要创建一个新实例并复制内容)。

在任何情况下,您都需要一些约束来描述访问是如何受到限制的,以便某些参与者可以处理一个或其他变体。只需应用奥卡姆剃刀,不要试图找到过于复杂的模型,而简单的模型也可以。出于爱好目的或迷惑/眩晕他人,这很好。但实际上呢?

,

我正在考虑为相同的实体类型使用两个不同的类

这可能意味着类在实体批准历史之后出现和消失!

假设还没有批准的版本,所以只是一个实时版本随着时间的推移而演变,当该版本被批准时,仍然只有一个版本是最后批准的和实时版本,也许你可以使用相同的类现在被批准。然后必须完成第一个更改,因此最后批准的版本仍然存在并被克隆以创建实时版本的类。当该实时版本被批准时,必须删除已经存在的最后批准的类。等

参与者(在非 UML 用例意义上)必须访问正确的类以尝试与之交互。

我不确定您是否希望在元模型级别工作。


第二种方法是让一个类始终管理最后批准的版本,另一个类管理实时版本,在给定时间每个类有零个或一个实例,但当实体存在时至少有一个实例存在。

假设还没有一个被批准的版本,所以没有最后一个被批准的版本类的实例,所以只有一个实时版本类的实例随着时间的推移而演变。当该版本被批准时,必须从实时类实例中创建已批准版本类的实例,然后必须删除最少的实例。然后必须进行第一个更改,因此最后一个批准版本的实例仍然存在并被克隆以创建实时版本的类实例。当该实时版本被批准时,必须更新或删除上次批准的类的现有实例,并创建另一个实例,并删除实时类的实例。等

actor 必须访问正确的类实例才能尝试与之交互。


第三种方式不是使用不同的类,而是使用同一类的不同实例。在实体批准历史期间,以与第一种方式相同的方式创建/删除实例。但关卡不是元模型。

就像之前的方式一样,actor 必须访问类的正确实例才能尝试与之交互。


第四种方法是对同时存在的实体的所有版本使用相同的实例,该实例能够以正确的方式做出反应,具体取决于参与者使用的视图 ,还要检查演员是否被授权。无论版本和批准历史如何,每个实例都会为给定实体创建一次。

因为只有一个实例,actor 不必在多个实例/类之间进行选择。如果您在实体之间建立关联,则它们始终相同,不必根据实体的版本进行创建/删除。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...