为什么使用 UML 描述相同的设计模式有不同的方法?信任什么?

Why are there different ways to describe same design pattern using UML? What to trust?

我发现很难同时学习设计模式和 UML,因为有不同的方法来描述相同的模式,这让我不确定什么是唯一的真理来源。

迭代器模式为例,这里只是从知名网站上看到的几张图:

1 维基百科

https://en.wikipedia.org/wiki/Iterator_pattern

2 个教程要点

https://www.tutorialspoint.com/design_pattern/iterator_pattern.htm

3 重构大师

https://refactoring.guru/design-patterns/iterator

4 设计

https://www.oodesign.com/iterator-pattern.html

5 HOWTODOINJAVA

https://howtodoinjava.com/design-patterns/behavioral/iterator-design-pattern/

最让我困惑的是如何使用箭头符号来描述这些类之间的关系。有时它们是泛化,有时是接口实现、定向关联或依赖。连作文也用...

我想知道对我来说最好的方法是什么。

一般来说,在查看设计模式的 UML 模型时需要非常小心。原因有以下三个:

  • 设计模式的参考文献是GoF。这本书出版于 1995 年,当时 UML 甚至还不存在,并且使用了 OMT 表示法(UML 的祖先)的变体。如果有疑问,这是值得信赖的来源。
  • Java 语言设计于 1995 年 public,1996 年 1 月 JDK 1.0 发布,该语言尚未广为人知。作者将他们的设计和代码示例基于 C++ class 模型,即仅基于 classes 和继承,而没有考虑多重继承。大多数现代语言不支持多重继承。因此,一些原始模式必须适应 Java、C# 或 Swift,以区分 classes、抽象 classes 和接口,以及继承和接口实现之间。有多种方法可以做到这一点。例如,一些系统地将抽象 classes 转换为接口。有些人只有在发生冲突时才转换它们。还有一些是根据接口“灵”转换的。
  • 误解发生了。有些人在网上发布了这样的图,但误解了模式,或者误解了 UML,或者两者兼而有之。另外,Gamma 等人在他们还是博士生的时候就开始写这本书,也犯了一些错误。例如,您会发现他们在使用 OMT 聚合时存在一些不一致之处。
  • 最糟糕的情况是 Builder 模式,您不仅会遇到这些问题,而且还会遇到命名冲突:一本非常受欢迎的 Java 书籍介绍了构建器模式,具有不同的意图和另一种设计,导致完全混乱。

现在以你的具体例子为例,根据你提供的内容:

  • oodesign 最接近原始模式并且完全准确。顺便说一句,当涉及到模式时,我主要使用指向他们页面的链接。
  • 重构大师也是不错的选择。他们选择使用接口而不是抽象 classes,这很好。但是他们重新定义了界面的操作和属性(可能与自己的示例有关)并且需要似乎不合理的双向导航。如果您有兴趣,可以使用“Head First: Design patterns”,它使用类似的映射但保留原始界面。
  • wikipedia 也不错:他们忽略了客户端(GoF 以浅灰色显示,表明它对于此模式不是必需的);它们在依赖性上更加精确和完整;但他们也以不同的方式重新定义了操作和属性。并且他们添加了一个不必要的聚合符号。
  • 如何在 Java 中实现它令人困惑,因为他们保留了一个抽象 class 并为另一个选择了一个接口。他们隐藏了操作和属性。但乍一看并没有什么根本性的错误。
  • 忘记 教程要点,至少对于这个 UML 图。这是完全错误的,正如评论中已经提到的 @qwerty_so

准确性声明仅适用于此模式和内容的当前版本。鉴于我的介绍性评论,这不能推广到所有设计模式。