对象之间的关系
# 依赖

依赖是类之间最基础的、也是最微弱的关系类型。如果修改一个类的定义可能会造成另一个类的变化,那么这两个类之
间就存在依赖关系。当你在代码中使用具体类的名称时,通
常意味着存在依赖关系。例如在指定方法签名类型时,或是
通过调用构造函数对对象进行初始化时等。通过让代码依赖
接口或抽象类(而不是具体类),你可以降低其依赖程度。
通常情况下,UML 图不会展示所有依赖——它们在真实代码
中的数量太多了。为了不让依赖关系破坏 UML 图,你必须
对其进行精心选择,仅展示那些对于沟通你的想法来说重要
的依赖关系。
# 关联

关联是一个对象使用另一对象或与另一对象进行交互的关系。在 UML 图中,关联关系用起始于一个对象并指向其所使用
的对象的简单箭头来表示。顺带一提,双向关联也是完全正
常的,这种情况就用双向箭头来表示。关联可视为一种特殊
类型的依赖,即一个对象总是拥有访问与其交互的对象的权
限,而简单的依赖关系并不会在对象间建立永久性的联系。
一般来说,你可以使用关联关系来表示类似于类成员变量的
东西。这个关系将一直存在,因此你总能通过“订单”来获
取其“顾客”。但是它并非一定是成员变量。如果你根据接
口来创建类,它也可以表示为一个可返回“订单”的“顾客”
的方法。
为了巩固你对关联和依赖之间区别的理解, 下面让我们
来看一个两者结合的示例。 假设我们有一个名为 教授
(Professor)的类:

`让我们来看看 teach (教授知识)方法,它将接收一个来
自 课程 (Course)类的参数。如果有人修改了 课程 类的
getKnowledge (获取知识)方法(修改方法名或添加一些
必须的参数等),代码将会崩溃。这就是依赖关系。
现在,让我们来看看名为 student (学生)的成员变量,以
及如何在 teach 方法中使用该变量。我们可以肯定 学生
(Student)类是 教授 类的依赖:如果 remember (记住)
方法被修改, 教授 的代码也将崩溃。但由于 教授 的所有
方法总能访问 student 成员变量,所以 学生 类就不仅是依
赖,而也是关联了
# 聚合

聚合是一种特殊类型的关联,用于表示多个对象之间的“一
对多”、“多对多”或“整体对部分”的关系。通常在聚合关
系中,一个对象“拥有”一组其他对象,并扮演着容器或集
合的角色。组件可以独立于容器存在,也可以同时连接多个
容器。在 UML 图中,聚合关系使用一端是空心菱形,另一
端指向组件的箭头来表示。
尽管我们在此讨论的是对象之间的关系,但请记住 UML 图表
示的是类之间的关系。这意味着大学对象可能是由多个院系
构成的,即便图中的每个实体只用一个“方框”来表示。你
可以使用 UML 符号在关系两端标明数量,但如果可从上下
文明确数量的话,则可以省略此类标注。
# 组合

组合是一种特殊类型的聚合,其中一个对象由一个或多个其
他对象实例构成。组合与其他关系的区别在于组件仅能作为
容器的一部分存在。在 UML 图中,组合与聚合关系的符号
相同,但箭头起始处的菱形是实心的。
注意,许多人常常在实际想说聚合和组合时使用“组合”这
个术语。其中最恶名昭彰的例子是著名的“组合优于继承”
原则。这并不是因为人们不清楚它们之间的差别,而是因为
“组合(例如‘对象组合’)”说起来更顺口。