天天看点

《软件方法》第8章 分析 之 分析类图(3)

8.2.3 识别关联关系

8.2.3.1 关联的三种形式

UML规定了关联的三种形式:普通关联、聚合(Aggregation)和组合(Composition)。

说到这里,我们有必要归纳类的关系如图8-90。

《软件方法》第8章 分析 之 分析类图(3)

图8-90 类的关系

有些书和文章里提到“泛化和组合”,其实是不合适的,因为泛化和组合不在一个抽象级别上。说“泛化和关联”可以。

在图形表示上,普通关联是一根直线,聚合的整体一端是空心菱形,组合的整体一端是实心菱形。

《软件方法》第8章 分析 之 分析类图(3)

图8-91 三种关联的图示

当然,更重要的是意义不一样。之所以分出聚合/组合这样的特殊关联,考虑的出发点是责任分配。通过建立聚合/组合,使整体把部分封闭起来。在责任分配时,不管外部对象想要发消息给聚合/组合结构里的哪一个对象,都应该先把消息发给整体对象,再由整体对象分解和分配给聚合/组合里的对象,如图8-92所示。

《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)

图8-92 聚合/组合关联影响责任分配

类图上会有很多类,类之间关系的密切程度不一样。有些类相互之间关系更密切,当推断或观察到这些类之间的协作的频率远超过它们和外部其他类的协作频率时,通过聚合/组合来封装它们是合算的,因为这样可以大大减少外部对这些类调用的复杂度。

引入聚合/组合,相当于把类图分区,每个区找一个区长作为责任分配的起点。这是一项十分重要的分析技能。例如图8-93就是一张餐饮领域的类图,可以看出右上角“顾客”分区的领域概念和左上角“餐台”分区的领域概念所受的影响因素应该有较大差别。

聚合/组合和公司的部门划分类似。公司不划分部门,老总一个个员工派任务也能达到目标,只是效率不高,而且不管出现什么改变都要打开老板的“代码”来修改。分了部门之后,老板就爽多了,只需要和部门经理打交道。当然,分部门也不能乱分,否则效果还不如不分。如果公司分了部门之后发现部门内部员工之间交互甚少,反倒是串门的很多,那很可能公司的部门分割是乱点鸳鸯谱了。

《软件方法》第8章 分析 之 分析类图(3)

图8-93 餐饮领域类图分区

上面关于责任分配的描述,对于聚合和组合都是合适的,所以表达时使用的是聚合/组合。那么,聚合和组合的区别是什么?

组合可以看作是更强的聚合,相对于聚合来说,组合还要满足以下要求:

(1)整体对象被销毁,部分对象也要销毁;

(2)部分对象只属于一个整体对象;

(3)整体对象负责部分对象的创建和销毁。

也就是说,部分对象只应该作为整体对象的一部分存在,不应独立存在,所以部分类的命名往往有整体类的味道,如图8-94所示,“订单”和“订单项”之间的关联是组合,但接下来的“订单项”和“商品”之间的关联不是组合;同样,“报告”和“报告审核”之间的关联是组合,但接下来的“报告审核”和“人员”之间的关联不是组合。

《软件方法》第8章 分析 之 分析类图(3)

图8-94 部分类的命名有整体类的味道

如果暂时无法确定聚合还是组合合适,那么可以先通通建模为聚合或组合,后面有足够证据时再修改。

聚合/组合务必慎用。如果没有足够的证据,应该先建模为普通关联。有的建模人员懒得给普通关联想合适的名字,干脆一概以“有”称之,例如“订单有顾客”,然后得到错误的聚合/组合关系,如图8-95所示。

《软件方法》第8章 分析 之 分析类图(3)

图8-95 错误的聚合/组合关系

8.2.3.2 识别关联的思路

之前在审查类和属性时,“属性要直接描述类”和“属性在领域内不可分解”这两种审查已经演变出了一些关联关系。

接下来识别关联也没有什么妙招。和识别泛化一样,严格的做法同样是针对每两个类以及每个类自身思考系统是否要维护类和类之间的关联。如果需要,再思考是否有明显的证据判断其为聚合/组合,然后再考虑多重性、关联名、角色名。

这样做也同样有工作量巨大的问题,所以一般来说只需要凭借对领域的理解,迅速定位最应该建立的关联。如果有遗漏,后面画分析序列图时也会发现。

和泛化不同的是,关联不只是发生在不同的类之间,还可以发生在同一个类上,即自反关联。自反关联对于简化模型很有帮助,后文会专门讲述。为什么没有自反泛化?请读者自行根据前文知识思考。

8.2.3.2.1 关联是系统维护的关系

万事万物之间如果想找关系,总能找到关系的,但所研究系统需要关注的只是千万关系中的一小部分。只有所研究系统负责维护的关系,才有资格变成关联。

“8.1.6.4 切勿照猫画虎”里已经提到这个问题。很多表面上看到的“关联”,其实不是系统要维护的或者重点维护的关联。真正重要的关联往往埋在底下,没有一定的抽象能力很难发现。如图8-96所示,分析时不仅仅要看到生机勃勃的绿叶,更要思考这生机勃勃的根源。

《软件方法》第8章 分析 之 分析类图(3)

图8-96 叶和根

“8.1.6.4 切勿照猫画虎”中的图8-52说系统不需要记住哪个顾客查询过哪件商品,所以“顾客”和“商品”之间没有关联。如果系统确实要维护查询的信息,两个类之间的关联当然可以存在,不过未必是直接关联,很可能是像图8-97。常见的电子商务系统中,需要维护的应该是图8-97上部的三个类:顾客、查询和查询条件,这样顾客可以反复使用之前设置过的查询条件。

《软件方法》第8章 分析 之 分析类图(3)

图8-97 顾客和商品之间的查询

8.2.3.2.2 关联名或角色名

如果问一位习惯于数据库建模的建模人员“A和B是什么关联”,可能会得到这样的回答“是一个一对多的关联”,因为他觉得说出关联两端的多重性就足够详细了。

在类建模中,关联的名字和角色的名字是很重要的。除非某个关联的名字已经一目了然,不会造成误解,否则应该尽量加上关联名或角色名,这样模型更能够讲出领域的故事。如图8-98,关联名和角色名串起几个类的概念,生动地展示了领域知识。

《软件方法》第8章 分析 之 分析类图(3)

图8-98 模型要能讲故事

至于采用关联名还是角色名来描述关联,如果角色名更能说明问题,那么角色名优先。因为角色名在实现中往往会映射为变量名。特别是当两个类之间有多种关联的时候,通过角色名区分是必须的。如图8-99所示。

《软件方法》第8章 分析 之 分析类图(3)

图8-99 两个类之间有多种关联

聚合/组合关联经常被认为不需要关联名或角色名,其实也是需要的。如图8-100。

《软件方法》第8章 分析 之 分析类图(3)

图8-100 聚合/组合的角色名

如果是给关联命名,最好给名称添加一个阅读方向,如图8-101所示,方向指示领域知识为“订单产生结汇单”。不过要注意,这个阅读方向只是为了方便理解领域知识,和关联的导航方向没有关系。有的建模工具不支持标注关联方向,可以通过统一偏向某一侧来表达阅读方向。

《软件方法》第8章 分析 之 分析类图(3)

图8-101 关联名称的阅读方向

8.2.3.2.3 导航方向

关联可以是双向的,两端的对象都可以通过关联导航到另一端;关联也可以是单向的,只有其中一端能访问另一端。

注意图形的表达:一个箭头都没有并不是指两端都不可以导航,而是指两端都可以导航,相当于两边都有箭头,如图8-102所示。

《软件方法》第8章 分析 之 分析类图(3)

图8-102 关联导航图示

一开始对模型的内涵把握不到位,可以保留双向关联,但随着对领域内涵的深入理解,应该尽可能把关联改为单向关联。这样可以从根源上防备循环访问和调用。

关于确定关联的方向原则,我们先来看看常被讨论的人和狗的例子。如图8-103,日常生活中我们可以说人养了宠物狗,也可以说狗有主人,假设系统要记住人和狗的关联,哪一个更合适呢?

《软件方法》第8章 分析 之 分析类图(3)

图8-103 人和狗的关联方向

如果人和狗都是哺乳动物,地位差不多不好判断,我们可以把问题往极端推,就可以看得更清楚。如图8-104,人有一个属性姓名,类型为字符串,图中左右两侧是等同的。显然“人”知道“string”是合理的,但是背后的原因不是人比字符串更“复杂”(8.1.6.7已经讲述过这个问题),而是系统很可能更关心人的状态变化。

《软件方法》第8章 分析 之 分析类图(3)

图8-104 人和字符串的关联方向

回到图8-103。是人知道狗还是狗知道人,判断的原则是看系统更关心谁的状态,关心谁,谁就应该知道得越多。不能武断地说系统一定更关心人的状态,所以人应该知道狗。也许系统是一个狗舍管理系统,也许系统是一款狗的游戏——以前还有一款奇葩游戏叫《坏蟑螂(Bad Mojo)》呢,主角就是一只蟑螂。

了解了这一点,我们再来看看图8-105的关联,“单位”和“设备”,谁知道谁?在没有足够上下文信息的情况下很难判断,但如果说系统是一个监测系统,目的是定期了解哪些设备过期未检验,“设备”的状态比“单位”的状态丰富,所以图8-105下部更合适。

《软件方法》第8章 分析 之 分析类图(3)

图8-105 单位和设备的关联方向

这里的判断原则和关系数据库建模有的时候是矛盾的。数据库建模中,哪个表中有另一个表的标识,判断原则是多重性。如图8-106,类图中“订单”知道“订单项”,但映射到关系数据库表,“订单项”表中有“订单ID”。

《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)

图8-106 关联导航方向和关系数据库不一致

当然,有时也不矛盾,图8-105下部的两个类就是一致的。一个单位安装了多台设备,映射到关系数据库,“设备”表中有“单位ID”。

8.2.3.2.4 多重性

多重性表示关联两端允许的对象的数量,可选的表达如图8-107。

表示 含义
1 1
0..1 0到1
* 0到多
1..* 1到多
具体数字如2..8 2到8

图8-107 可选的关联多重性

很多建模人员纠结于“1”还是“0..1”好,“*”还是“1..*”好,过早分散了精力。先统一使用“1”(涵盖“1”和“0..1”)和“*”(涵盖“*”和“1..*”)就可以,等到有更清晰的认识以后再考虑是否改为“0..1”或“1..*”。

对于多重性,建模人员容易出现的问题是把不同时间的对象快照合并成一个。例如,男人和女人可以有夫妻关系,那夫妻关系的多重性是多少?中国是一夫一妻制度,按道理应该1对1,如图8-108左侧。但有的建模人员会想,不对呀,有的人一生结好几次婚,那不是有几个配偶吗?是否应该如图8-108右侧?

《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)

图8-108 夫妻关联的多重性

图8-108左侧是正确的。在任何时间拍摄快照,拍到的应该是一个男人最多和一个女人有夫妻关联。即使有其他女人,当时的夫妻关联应该已经断开了,如果要表达关联,只能叫“前妻”。如图8-109所示。在某个时间拍快照,是有可能拍到一个男人存在多个前妻的。

《软件方法》第8章 分析 之 分析类图(3)

图8-109 一个男人存在多个前妻

8.2.3.2.5 自反关联

当关联的两端是同一个类时,这个关联就是自反关联。

根据多重性的不同,自反关联可以表达不同的形状,如图8-110所示。

多重性 对象图形状 类图例子
*对* 网 
《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)
1对* 树 
《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)
1对0..1 队列 
《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)
1对1 环 
《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)

图8-110 不同多重性的自反关联

自反关联对简化模型很有帮助。在许多分析模式和设计模式中,都可以看到自反关联。例如,当类结构中的泛化层次很深时,就可以通过把泛化结构转为更高级抽象的自反关联,如图8-111所示。

《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)

图8-111 自反关联简化模型

关于自反关联,本书后文关于分析模式的内容中会有更详细的讲述。

《软件方法》第8章 分析 之 分析类图(3)

扫码或访问http://www.umlchina.com/book/quiz8_2_1.htm完成在线测试,做到全对以获得答案。

《软件方法》第8章 分析 之 分析类图(3)

1. 类之间的关系有

A 扩展、包含、泛化

B 泛化、关联、依赖

C 请求、验证、回应

D 连接、聚合、组合

2. 区分泛化和关联的根本要点是

A 泛化是静态关系,关联是动态关系。

B 泛化关注继承,关联关注包含。

C 泛化是集合关系,关联是个体关系。

D 泛化关注销售,关联关注成本。

3. 以下类关系合理的是:

《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)

4. 是否采用"聚合/组合"关联,考虑的出发点是:

A 对责任分配有帮助

B 人类语言表达上"A拥有B"能说得通

C 关联两端的多重性

D 类的属性个数

5. 一台电脑可能是一台台式电脑,也可能不是;一台电脑可能是一台笔记本电脑,也可能不是;一台电脑可能是一台掌上电脑,也可能不是。以下类关系表达正确的是:

 A) 

《软件方法》第8章 分析 之 分析类图(3)
 B) 
《软件方法》第8章 分析 之 分析类图(3)
 C) 
《软件方法》第8章 分析 之 分析类图(3)
 D) 
《软件方法》第8章 分析 之 分析类图(3)

6. 以下说法正确的是:

A) 不需要先识别出所有的类,再识别类之间的关系。

B) 如果A变化,B也需要变化,那么A依赖于B。

C) 自然语言中带有“A有B”的描述,可以判断A和B是关联关系。

D) 从用例规约的各个部分都有可能提炼出分析类。

7. 以下犯了“把泛化当作关联”错误的是:

《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)

8. 关于影评网站“逗瓣”,针对以下概念之间的关系描述最合理的是:

A) 

《软件方法》第8章 分析 之 分析类图(3)
B) 
《软件方法》第8章 分析 之 分析类图(3)
C) 
《软件方法》第8章 分析 之 分析类图(3)
D) 
《软件方法》第8章 分析 之 分析类图(3)
9. 以下对象图如果映射回类图,得到的结果应该是:
《软件方法》第8章 分析 之 分析类图(3)
A) 
《软件方法》第8章 分析 之 分析类图(3)
B) 
《软件方法》第8章 分析 之 分析类图(3)
C) 
《软件方法》第8章 分析 之 分析类图(3)
D) 
《软件方法》第8章 分析 之 分析类图(3)
10. 泛化关系可以画成如下图的树的形状,关联可以吗?为什么?
《软件方法》第8章 分析 之 分析类图(3)
《软件方法》第8章 分析 之 分析类图(3)

继续阅读