【问题标题】:UML Classes representationUML 类表示
【发布时间】:2021-02-25 18:06:20
【问题描述】:

我正在学习 UML,想创建一个小型餐厅应用程序,它有一个菜单、菜单中包含的菜肴、菜肴中使用的产品。菜单分为不同的类型,只能包含适当的类型。 我想课程菜单和菜肴应该是抽象的。 这是我的 UML 图。

如何最好地展示抽象类之间的关系?

【问题讨论】:

  • 欢迎。对于刚开始学习的人来说,这是一个令人印象深刻的图表 :-) 如果我很好地理解了您的问题,您会注意到抽象类之间存在组合关系,但您只显示了特定类之间的组合。这是一个相当高级的主题,你可以看看at this answer(它是关于关联类的,但类似的技术可以用于组合。
  • 现在的问题是你是否真的需要这个复杂的结构,具体的类之间有专门的组合,或者你是否可以只使用抽象类之间的组合(它是继承的),并添加一些约束说汤菜单只能由汤菜组成?
  • “抽象类的关系”是什么意思?您的图表在抽象类之间没有关系。只能从抽象类继承到具体类。顺便提一句。抽象类用斜体名称表示,而不是添加单词“Abstract”。
  • 可能我表达了这个想法,因为我是 UML 的初学者。 “关系”一词是指我的应用程序中的类或对象之间的链接,如果我不正确,我很抱歉。我想使用 UML 创建一个应用程序模型。我想在抽象类之间使用组合(这是继承的),并添加一些约束来说明汤菜单只能由汤菜组成。您能否提供有关 UML 的资源或书籍。抱歉回复晚了。
  • @Pirogov 没问题,我们会提供帮助。我注意到你的混凝土菜肴继承了有序的成分,并有自己的成分。这是非法的,正如here 所解释的那样。在我能提供帮助之前有一个问题:菜单是什么?是报价,还是相关项目的目录?还是某种汤的组合(例如汤+主菜+甜点或开胃菜+没有甜点的主菜,或开胃汤-+主汤+甜点汤)?

标签: inheritance uml composition class-diagram


【解决方案1】:

第一次尝试

如果我们看需求,即Orders 大约是Dishes,Dishes 由Products 组成,Menus 就像Dishes 的目录某种意义上,我们会得出这样一个图表:

我们只显示摘要 Dish 和摘要 Menu 之间的“关系”。特色菜和菜单继承了这种关联。只是你必须用评论来表达使用与菜单兼容的菜肴的约束。

进一步的反思

问题是我们是否真的需要Menu 专业化。如果他们有非常不同的行为,这将是合理的。

此外,在您的示例中,您假设菜单专业化是严格分离的。但是如果在稍后阶段你会有重叠的菜单,例如主菜单包括素食、纯素和肉类菜肴,而纯素菜单仅提供纯素菜肴但适用于所有种类的菜肴。

如果所有菜单特化的行为都相同,并且这只是一种任意分类(此外,如果实际上每个类只有一个实例),那么最好使 @ 987654334@ 具体并将其与Category 类相关联。顺便说一句,您还可以将摘要 Dish 与一个或多个 Category 关联,这样可以更轻松地表达您想要的约束。

最后,探索association class 的概念并重新思考OrderDish 之间以及DishProduct 之间的概念是值得的。

【讨论】:

  • Dish 的子类都是 Menu 的。我想这是一个疏忽?避免OrderDish 之间而不是DishProduct 之间的组合是否有意义我认为您应该首先定义这些类的含义。是菜单上的 Dish 项目的一个实例,还是提供给客户的带有食物的实际盘子。我怀疑是第一个,但在这种情况下,您不应该对Product 进行组合(产品 Mashed Potatoes 可能是多个菜肴的一部分)
  • 我不明白为什么类 X Menu 继承 Dish。首先,菜单包含菜但不是菜。其次,在您的提议中,继承 MenuDishX Menu 意味着 X Menu 聚合了 Y菜单 可以是它自己。
  • 很可能您希望 XX Dish 继承 Dish 而不是 XX Menu
  • @bruno 确实如此!在菜肴下应该只有菜肴专业。抱歉,已经很晚了,我在克隆我的菜子类时搞砸了。我会在当天晚些时候更正此问题。
  • @Pirogov 很高兴它有帮助。我已经更正了我的拼写错误图表,并为您添加了更多问题。在进一步的思考中,我添加了关于引入类别类作为子类的替代方案的唯一想法。最后,如果您正在寻找更多的阅读材料,我会推荐 Martin Fowler 非常实用且全面的“UML 精炼”书。在网络上,有uml-diagrams.org(这是关于该主题的最佳资源恕我直言)。我现在更喜欢其他来源,因为它们添加了更多令人讨厌的添加,但它们的内容是顶级的。
【解决方案2】:

我在@Christophe 之后给出了答案,因为在(第一版)他的提案中存在异常的一些问题。

一份订单至少包含一道菜。但是订单不是由菜组成的,所以没有组成,对我来说甚至也没有聚合。

一道菜由至少一种产品制成,使用一定数量的产品。根据产品的不同,数量是体积(例如液体),重量(例如黄油)或数字(例如鸡蛋)等。为此,您可以使用类关系。该关系不能是组合,因为给定的产品可以用于多种菜肴。

一个菜单至少包含一道菜,但一个给定的菜可以在多个菜单中使用,因此不能使用组合。在我的图表中,我使用了聚合,但也许这不是一个好主意。

假设你总是需要有专门的MenuDish类你可以有:

但我不确定你是否总是需要这些特化,所以 DishMenu 即使它们可以有特化也不是抽象的,你可以拥有:

(我想一道菜总是至少是一个菜单的一部分,这是一种选择,所以厨师做的但不属于菜单的“准备”不是一道菜)

正如@Christophe 在评论中所说,客户可以要求一些具体的说明(肉类的中等与血腥等),可以通过类关系来支持:

【讨论】:

  • 你好@bruno 谢谢你的回答。如果我将按照您的第一个图表进行编码,我将创建抽象类MenuDish?第二个图不包含抽象类,对吧?在你回答之后我还有一个问题:为什么DishMenu 不应该是抽象的?我没听懂。
  • @Pirogov 是的,第二张图中没有抽象类,因为拥有它是没有用的。根据定义,抽象类不能被实例化,所以如果 Dish 是一个抽象类,那么所有的菜都是另一个专门(直接或不直接)Dish 的类的实例。一个非抽象类可以被特化,所以问题不是为什么classX不是抽象的而是为什么ClassX需要是抽象的。不要寻找复杂的解决方案,而要寻找简单的解决方案。
  • 很好的补充。您还可以在订单和菜肴之间添加关联类。与这里的简单关联相比,聚合有什么好处?最后,我没有质疑抽象菜肴,因为我每天晚上都能观察到汤与主菜的行为不同;-)
  • @Christophe 我没有在订单和菜肴之间放置类关系,因为在这种情况下,数量只是一个数字,并且已经由多重性管理(当然没有约束 独一无二的)。当然,使用总是有问题的聚合,我在菜单和菜之间使用的聚合可能不是一个好主意
  • @bruno 很好的论据!但结果是,顾客不能要求少盐、多胡椒、中等和血腥、不要太热,或者任何其他可能想给服务员的具体指示? ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多