具有泛化和专业化的聚合顺序

Order of aggregation with generalization and specialization

我在设计 DCD 时遇到了这个 problem/question。 我有一个通用产品和 2 个专业牛奶和披萨。 我怀疑是否应该使用订单和产品或订单和 pizza/milk.

之间的聚合

我简化了 uml 以使我的问题尽可能清楚。

两者在语义上都是正确的,这意味着它们可以被正确地解释。

此外,如果所有聚合中的重数是 1(在菱形一侧)和 *(在另一端)并且还有关于这些关系的其他信息,那么它们甚至具有相同的语义。在这种情况下,由于图表更简单,通常首选对广义 class 使用聚合,但即使在这种情况下,也可能有理由使用第二种表示法。

然而,上面提出的多重性可能并非如此,并且可能有许多其他原因来区分两种不同产品类型之间的聚合。在这些情况下,只有第二种表示法是合适的(但也有其他可能性)。

您可能还想指出聚合到广义 class 很重要的事情,在这种情况下,这是一种更好的简单表示需求的方式。

举几个例子。

如果你想表明你需要在订单中有任何东西,不管是什么类型,第一个符号会更好。

如果你需要订购最小数量的披萨,但牛奶是可选的,第二个更好。

如果您对可以订购多少比萨饼和多少牛奶有限制(每个单独),那么第二个更好。

如果您的订单有重量限制,无论数量多少,那么第一个可能会更好(有各自的限制)。

你明白了。

此外,有时您实际上将两者组合在一个图表上(以及相同的 classes)。

示例:假设您不能订购超过 10 个元素,但同时您需要为每种类型至少订购一件。您将显示两种类型的聚合,添加 /subsets 约束以指示它们实际上涉及相同的元素。

要获得更详细的答案,您必须提供更详细的问题;-)

两个图都正确,但含义截然不同:

  • 第一个图说订单是产品的集合,这些产品可以更专业化(例如牛奶和披萨)。这种设计解耦特定产品的订单:因此您可以很容易地想象其他产品专业化,例如Cake,而不会改变订单的含义(据说是“open for扩展”).
  • 第二张图说订单是比萨饼和牛奶的集合,顺便说一句,比萨饼和牛奶是产品的专业化。这更具限制性:订单与特定产品耦合,因此每次您的订单都应该处理一种既不是某种牛奶也不是某种比萨饼的新产品(例如 Cake),您的订单定义必须修改。

考虑到Open-Closed Principle第一张图绝对是首选。第二个太麻烦了

备注:顺便说一下,虽然聚合由于历史原因仍然很流行,但 UML 规范没有定义它的语义。因此,您可以删除白色菱形并表达完全相同的含义。