跳转到内容

UML 简介

统一建模语言(UML)是业界标准,用于绘制可视化类层次结构、子系统交互、时序图等图表。本书在类图中使用 UML。完整讲解整个 UML 标准本身就足以写成一本书,因此本附录仅对本书中使用到的那些方面做简要介绍。UML 标准有不同版本,本书使用的是 UML 2。

UML 定义了以下类型的图表:

  • 结构型 UML 图
    • 类图
    • 对象图
    • 包图
    • 组合结构图
    • 组件图
    • 部署图
    • Profile 图
  • 行为型 UML 图
    • 用例图
    • 活动图
    • 状态机图
    • 交互图
      • 时序图
      • 通信图
      • 时间图
      • 交互概览图

由于本书只使用类图和时序图,因此本附录只进一步讨论这两种图。

类图用于可视化单个类,并且可以包含数据成员和成员函数。它们也用于展示不同类之间的关系。

在 UML 中,类表示为一个最多包含三个分区的方框,内容如下:

  • 类名
  • 数据成员
  • 成员函数

图 D.1 展示了一个示例。MyClass 有两个数据成员——一个类型为 string,另一个类型为 float——并且它有两个成员函数。每个成员前面的加号和减号表示其可见性。下表列出了最常用的可见性:

一张一列三行的表格。标题为 MyClass。第一行包括 string 和 float。第二行涉及 float 和 void。

[^FIGURE D.1]

VISIBILITYMEANING
+公有成员
-私有成员
#受保护成员

根据类图的目标,有时会省略成员细节,此时类会表示为一个方框,如图 D.2所示。例如,如果你只关心不同类之间关系的可视化,就可以采用这种方式。

一个只有表头的表格。标题为 MyClass。

[^FIGURE D.2]

UML 2 支持六种类之间的关系:继承、实现、聚合、组合、关联和依赖。下面的小节将介绍这些关系。

继承用一条从派生类指向基类的线来表示。该线在基类一侧以空心三角形结束,用于表示 is-a 关系。图 D.3 展示了一个示例。

一个基类的流程图。更派生的选项通向 derived two 和 derived one,形成一个网络。

[^FIGURE D.3]

实现某个接口的类本质上是在继承该接口(is-a 关系)。不过,为了区分一般继承和接口实现,后者的表示方式与继承相似,但使用虚线而不是实线,如图 D.4所示。ListBox 类派生自 UIElement,并实现了 IClickableIScrollable 接口。

一个 listbox 的流程图。List box 连接到 U I Berest、Clickable 和 Scrollable,形成一个网络。

[^FIGURE D.4]

聚合表示 has-a 关系。它用一条线来表示,并在包含另一个类实例或多个实例的类一侧使用空心菱形。在聚合关系中,你还可以选择指定关系中各参与者的多重性。多重性的放置位置,也就是应写在线的哪一侧,起初可能会让人感到困惑。例如,在图 D.5中,一个 Class 可以包含/聚合一个或多个 Student,而每个 Student 可以参加零个或多个 Class。聚合关系意味着,被聚合的对象在聚合者被销毁后仍然可以继续存在。例如,如果一个 Class 被销毁,其 Student 并不会被销毁。

一个网络示意图。它有两个方框。1. Class。2. Student。数值是一个上标加号和一个上标加号。

[^FIGURE D.5]

下表列出了一些可能的多重性示例:

MULTIPLICITYMEANING
N恰好 N 个实例
0..1零个或一个实例
0..*零个或多个实例
N..*N 个或更多实例

组合与聚合类似,视觉表示方式也几乎相同,不同之处在于它使用实心菱形而不是空心菱形。与聚合不同,在组合关系中,如果包含其他类实例的类被销毁,那么这些被包含的实例也会随之销毁。图 D.6 展示了一个示例。一个 Window 可以包含零个或多个 Button,并且每个 Button 必须恰好被一个 Window 包含。如果 Window 被销毁,它所包含的所有 Button 也会被销毁。

一个网络示意图。它有两个方框。1. Window。2. Button。数值是 one 和 zero 上标加号。

[^FIGURE D.6]

关联是聚合的一种泛化。它表示类之间的二元链接,而聚合是单向链接。二元链接可以沿两个方向遍历。图 D.7 展示了一个示例。每本 Book 都知道它的作者是谁,而每位 Author 都知道她写过哪些书。

一个网络示意图。它有两个方框。1. Author。2. Book。数值是一个上标加号和一个上标加号。

[^FIGURE D.7]

依赖表示一个类依赖于另一个类。它表示为一条虚线,带有一个指向被依赖类的箭头。通常,虚线上会有一些文字来描述这种依赖关系。回到第 33 章“应用设计模式”中的汽车工厂示例,CarFactory 依赖于 Car,因为工厂会创建汽车。这一点在图 D.8中进行了可视化表示。

一个网络示意图。它有两个方框。1. Carfactory。2. Car。存在虚线。

[^FIGURE D.8]

UML 2 支持四种交互图:时序图、通信图、时间图和交互概览图。本书只使用时序图,下面将对此做简要讨论。

时序图以图形方式表示不同对象之间发送了哪些消息,以及这些消息发送的顺序。时序图由以下组成部分构成:

  • 对象: 参与交互的对象实例。
  • 生命线: 以图形方式表示对象的生命周期。
  • 消息: 消息从一个对象发送到另一个对象。
  • 回复: 当一个对象接收到另一个对象发来的消息时,它会发送一个回复。
  • 自消息: 对象发送给自己的消息。
  • 备选: 表示替代流程,类似于 if-then-else 语句中的分支。

图 D.9 展示了一个时序图示例。这是第 4 章“设计专业级 C++ 程序”中的图的简化版本,不过这次图中添加了标签,用于说明图中重要部分的含义。

一个网络展示了 UML 时序图。它包括 gameplay、player、chessboard 和 chess piece。

[^FIGURE D.9]