【问题标题】:Should there be an association for the base class when it's implied?隐含的基类是否应该有关联?
【发布时间】:2020-05-08 11:10:38
【问题描述】:

我正在尝试为一个非常简单的场景制作 UML 类图。考虑以下代码:List<Food> foods = {new Tomato(), new Pizza()}; 作为类 A 的字段。显然,类 A 具有番茄和比萨之间的关联,但它是否也应该具有食物之间的关联?

当然,番茄和比萨是从食物延伸出来的 :)

【问题讨论】:

  • 不要使用类图中的答案中建议的关联或依赖关系,否则您将获得 boodle 盘。如果您想突出显示更好地使用对象图

标签: class generics uml associations


【解决方案1】:

使用诸如List<Food> 之类的泛型在UML 中始终是一个挑战,因为泛型的语义在各种编程语言中并不相同。

这里,A 类的字段foods 表示存在从AFoodnavigable 关联。而TomatoPizzaFood 中的specializations(基于您对术语“扩展”的使用):

补充说明:

  • associationFood 是一起的,因为类型是List<Food>,并且ATomatoPizza 之间没有直接耦合。

  • 请记住,类图显示的是一般情况,而不是特定场景与单个对象(这是前一个 object diagram 的目的)。

  • 列表的使用表明关联可以是0 or moreFood。但是我们不知道一个Food 对象是否可以被多个A 使用(如果Food 是一个引用类型,理论上是可能的):因此,在A 侧未指定多重性。

  • 根据语义,您可以考虑将关联设为compositionaggregation。但是在任何情况下,简单的关联都是正确的。

  • 根据您想在A-to-Food 关联中强调您的设计的内容:

    • 你可能更喜欢dot notationFood结尾,如果你想强调关联(又名列表)是由A拥有的
    • 你可以只使用navigability notation,就像我的图表一样,如果不太关心当前的实现,只是想表达从 A 访问 Food 应该很容易。
    • 如果您想让这些主题保持开放,您可以不显示以上任何内容。

【讨论】:

  • A 类的属性foods 不代表可导航 关联端,而是由A“拥有”的关联端,可视化为类图中的所有权点。当然,这种拥有的关联端意味着可导航性。如果您在回答中更正这一点,则值得 +1。
  • @GerdWagner 点符号应该是新标准。但是工具(如 EA)使创建变得困难或不可能。
  • @GerdWagner 感谢您的有趣评论。我真的必须对点符号进行更深入的研究。但我在这里的主张是,无法根据我们掌握的信息确定所有权。如果 Food 是一个引用类型,它的后续生命周期独立于 A。此外,初始化只是一个场景:没有任何东西告诉我们一个现有的 Food 以后可能不会被添加到列表中,也没有任何东西告诉我们 Food 没有构造函数或 setter 可以允许建立关联并启用反向导航(这就是我未决定且未禁用反向导航的原因)。
  • @Christophe :“关联端所有权”的 UML 术语与您所指的生命周期依赖意义上的组合/组件被“拥有”的(令人困惑的)辩论无关.请看stackoverflow.com/questions/47773220/…
  • @GerdWagner 我明白你的意思:该列表归 A 所有,因此您建议在图表中显示所有权。这确实是一个更接近当前实施的有效选择。不管关联是如何拥有/实现的,我选择将重点放在可导航性上也是有效的(UML 引用说:“所有权可以用图形表示”,而不是“必须”)。 UML 规范还告诉我们“聚合类型、可导航性和最终所有权是独立的概念,每个都有自己的明确表示法”。我已经编辑给 OP 的全貌。感谢您的建议
【解决方案2】:

我会说你的ClassAFood 有结构关系(关联)。

因为它还调用了TomatoPizza 的构造函数,所以它依赖于这些类。

【讨论】:

  • 除非目标是制作面条(留在烹饪领域),否则这些依赖项毫无用处
  • @bruno 想解释一下为什么这些依赖没有用?我没有得到对面条菜的引用
  • 当一个模型/图表中有很多关系来制作面条菜(每个关系就像一个boodle,而图表就是一个菜),你永远不会使用它比利时的表达?您可能更喜欢一盘薯条 吗? ;-)
  • 不,我们在比利时不使用“面条”:)。我不一定要谈论将所有这些关系放在图表上。但是依赖关系就在那里,无论你是否在图表上显示它们。如果要删除类Tomato,它将直接影响ClassA。 FrenchFries 类不是这种情况,尽管它也应该是 Food
【解决方案3】:

没有看到更多细节是很困难的。

您的food 是一个0..n 多重关联。

TomatoPizza 在该代码中都没有明确的关联。所以这只是一个依赖。

关联是一种更强的依赖形式(即草率的定义)。实际上你可以创建一个关联。这取决于未知的细节。如果您的注意力集中在列表上并且您想要其中的任何子类食物,则您不会将关联与这些子类中的每一个关联,而只会与父类Food 关联。

如前所述:这一切都取决于设计模板,模板中的细节需要更加强大

【讨论】:

  • 嗯。我认为每当它作为属性存储时,它都会与另一个类相关联。既然List<Food> foods = {new Tomato(), new Pizza()};作为一个属性就相当于构造函数中的foods.add(new Tomato()); foods.add(new Pizza()),那为什么是依赖呢?我是不是误会了什么?
  • 您没有番茄和比萨饼的命名关联。他们只生活在一个列表中。如果您有一个Tomato myTomato = new Tomato()(或任何语法),那么您就有一个与角色名称相关的关联。关联是一种更强的依赖形式。
猜你喜欢
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-17
  • 1970-01-01
相关资源
最近更新 更多