字典很重要!
起初我想的像qwerty_so,但是:
- 与
UserProfiles
有一个合格的关联:它用IDictionary
实现,其中使用string
来限定User
。
- 这种关联是单向导航的,因为你可以轻松地从
User
到UserProfile
,但是反过来就更困难了(虽然可以,但必须遍历所有的用户)。
因此,图表可能如下所示:
关于这张图,还有一些额外的注释:
- 对于 C# 属性,不存在 UML 标准,它们是 UML 属性和操作(通过隐式 getter 和 setter)的混合体。通常做法是使用定义了 stereotype 为
«property»
的 UML 剖面。我的首选选项是将其保留在类的属性中(例如 here 或 here),因为这是 C# 属性的语义。然而,一些人认为这个构造应该被视为 UML 操作的特殊化(例如 here 和 qwerty 的回答),这也是一个有效的论点,特别是如果您定义了自定义 getter 和 setter。
- 在限定关联中要注意多重性,因为它适用于以字符串为限定符的
User
。所以 0..1 UserProfile 是针对一个特定的 User 和字符串组合。如果考虑未限定的 User
,实际上是 0..*。
模型转换
我们必须记住,一个给定的实现可能对应不同的设计。实现是指你写代码的方式,而设计是指你看待事物的方式。
因此,我们可以将这个反向工程模型转换为符合您的思维模型。只有您能告诉我们您想要如何看待导致当前实现的事物。
例如,您可能对可导航性不太感兴趣,而将重点放在未经资格认证的“用户”和“用户配置文件”之间的多对多关联上。采用这种方法,被用作限定符的字符串将变成
关联类的属性:
![enter image description here](https://istack.dev59.com/CB2Vc.webp)
请注意,这是一种转型。合格的关联和一对多不是同一件事,两种模型并不完全相同。
接下来是n元关联!
现在关键问题是该关联类中的字符串属性的目的。我强烈怀疑它实际上是您的应用程序的id(请在评论中确认)。
如果是这种情况,我们将有一个关联类与应用程序之间的关联。并且我们可以从关联类中删除字符串属性,因为它将变得多余。
但是,一个与其他类相关联的关联类表明实际上存在
n-ary associaton(这里是三元)。因此,我们可以明确这一点:
![enter image description here](https://istack.dev59.com/DnQVZ.webp)
现在你有一个n元关联。如果每个三元组(用户、应用程序、用户配置文件)需要关联的其他属性,则甚至可以在其后面拥有一个关联类。
但要注意,这张图不太精确。例如,在n元关联中更难指示可导航性约束。它也不再完全对应于您的实现:该模型表明您可以从应用程序中找到用户,而在您的实现中,这更困难。
结论/建议:
个人而言,我发现n元关联很难处理,我更喜欢将它们分解为一组类和二元关联(必要时使用关联类):这可以消除许多歧义并提供更严格的控制。我只能向您推荐同样的方法。
还要考虑您的实现:如果实现代表您对世界的看法,请使用限定关联,因为它是UML与字典的等效项。
但是,如果三元关联是您对世界的看法,则您可能迟早需要重新审视当前的实现。您可能会提取配置文件以创建自己的类。
profiles
是一个<Application,UserProfile>
字典而不是<string,UserProfile>
,这两个类将如何相关? - paradiseApplication
绘制依赖关系。 - qwerty_soUser
和Application
之间的关系作为一个关联(类)来捕捉。此外,在C#实现模型中,复制类矩形中的属性是一种非常丑陋/嘈杂的方法。可以使用<<get/set>>属性构造型更好地表达这一点,请参见https://dev59.com/0l4c5IYBdhLWcg3wQYSC#28141950。 - Gerd Wagner