本文随便转载,请保留出处:http://blog.csdn.net/dylgsy/
UML的类图关系分为: 关联、聚合/组合、依赖、泛化(继承)。而其中关联又分为双向关联、单向关联、自身关联;下面就让我们一起来看看这些关系究竟是什么,以及它们的区别在哪里。
1、关联
双向关联:
C1-C2:指双方都知道对方的存在,都可以调用对方的公共属性和方法。
在GOF的设计模式书上是这样描述的:虽然在分析阶段这种关系是适用的,但我们觉得它对于描述设计模式内的类关系来说显得太抽象了,因为在设计阶段关联关系必须被映射为对象引用或指针。对象引用本身就是有向的,更适合表达我们所讨论的那种关系。所以这种关系在设计的时候比较少用到,关联一般都是有向的。
使用ROSE 生成的代码是这样的:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
双向关联在代码的表现为双方都拥有对方的一个指针,当然也可以是引用或者是值。
单向关联:
C3->C4:表示相识关系,指C3知道C4,C3可以调用C4的公共属性和方法。没有生命期的依赖。一般是表示为一种引用。
生成代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
单向关联的代码就表现为C3有C4的指针,而C4对C3一无所知。
自身关联(反身关联):
自己引用自己,带着一个自己的引用。
代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
就是在自己的内部有着一个自身的引用。
2、聚合/组合
当类之间有整体-部分关系的时候,我们就可以使用组合或者聚合。
聚合:表示C9聚合C10,但是C10可以离开C9而独立存在(独立存在的意思是在某个应用的问题域中这个类的存在有意义。这句话怎么解,请看下面组合里的解释)。
代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
组合(也有人称为包容):一般是实心菱形加实线箭头表示,如上图所示,表示的是C8被C7包容,而且C8不能离开C7而独立存在。但这是视问题域而定的,例如在关心汽车的领域里,轮胎是一定要组合在汽车类中的,因为它离开了汽车就没有意义了。但是在卖轮胎的店铺业务里,就算轮胎离开了汽车,它也是有意义的,这就可以用聚合了。在《敏捷开发》中还说到,A组合B,则A需要知道B的生存周期,即可能A负责生成或者释放B,或者A通过某种途径知道B的生成和释放。
他们的代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
可以看到,代码和聚合是一样的。具体如何区别,可能就只能用语义来区分了。
3、依赖
依赖:
指C5可能要用到C6的一些方法,也可以这样说,要完成C5里的所有功能,一定要有C6的方法协助才行。C5依赖于C6的定义,一般是在C5类的头文件中包含了C6的头文件。ROSE对依赖关系不产生属性。
注意,要避免双向依赖。一般来说,不应该存在双向依赖。
ROSE生成的代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
虽然ROSE不生成属性,但在形式上一般是A中的某个方法把B的对象作为参数使用(假设A依赖于B)。如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
那依赖和聚合/组合、关联等有什么不同呢?
关联是类之间的一种关系,例如老师教学生,老公和老婆,水壶装水等就是一种关系。这种关系是非常明显的,在问题领域中通过分析直接就能得出。
依赖是一种弱关联,只要一个类用到另一个类,但是和另一个类的关系不是太明显的时候(可以说是“uses”了那个类),就可以把这种关系看成是依赖,依赖也可说是一种偶然的关系,而不是必然的关系,就是“我在某个方法中偶然用到了它,但在现实中我和它并没多大关系”。例如我和锤子,我和锤子本来是没关系的,但在有一次要钉钉子的时候,我用到了它,这就是一种依赖,依赖锤子完成钉钉子这件事情。
组合是一种整体-部分的关系,在问题域中这种关系很明显,直接分析就可以得出的。例如轮胎是车的一部分,树叶是树的一部分,手脚是身体的一部分这种的关系,非常明显的整体-部分关系。
上述的几种关系(关联、聚合/组合、依赖)在代码中可能以指针、引用、值等的方式在另一个类中出现,不拘于形式,但在逻辑上他们就有以上的区别。
这里还要说明一下,所谓的这些关系只是在某个问题域才有效,离开了这个问题域,可能这些关系就不成立了,例如可能在某个问题域中,我是一个木匠,需要拿着锤子去干活,可能整个问题的描述就是我拿着锤子怎么钉桌子,钉椅子,钉柜子;既然整个问题就是描述这个,我和锤子就不仅是偶然的依赖关系了,我和锤子的关系变得非常的紧密,可能就上升为组合关系(让我突然想起武侠小说的剑不离身,剑亡人亡...)。这个例子可能有点荒谬,但也是为了说明一个道理,就是关系和类一样,它们都是在一个问题领域中才成立的,离开了这个问题域,他们可能就不复存在了。
4、泛化(继承)
泛化关系:如果两个类存在泛化的关系时就使用,例如父和子,动物和老虎,植物和花等。
ROSE生成的代码很简单,如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
5、这里顺便提一下模板
上面的图对应的代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
这里再说一下重复度,其实看完了上面的描述之后,我们应该清楚了各个关系间的关系以及具体对应到代码是怎么样的,所谓的重复度,也只不过是上面的扩展,例如A和B有着“1对多”的重复度,那在A中就有一个列表,保存着B对象的N个引用,就是这样而已。
好了,到这里,已经把上面的类图关系说完了,希望你能有所收获了,我也费了不少工夫啊(画图、生成代码、截图、写到BLOG上,唉,一头大汗)。不过如果能让你彻底理解UML类图的这些关系,也值得了。:)
-
87楼
xiao_feng_ge 2012-02-06 13:06发表
-
- 顶,辛苦了
-
86楼
seawt 2012-01-18 10:05发表
-
- 真的超赞了!!!真是做到了简洁而直观啊
-
85楼
frostbum 2012-01-06 13:57发表
-
- 不错啊,很清楚!
-
84楼
bln13fb 2011-12-21 10:19发表
-
- 简单易懂,实似教材之内容也。
-
83楼
sx811125 2011-11-21 13:50发表
-
- 好文章,易懂
-
82楼
fang_2004 2011-11-13 09:26发表
-
- 好文章,支持。
-
81楼
huangyongxin1986 2011-11-02 16:14发表
-
- DDDDDD
-
80楼
andyqee 2011-10-22 15:40发表
-
- 很幸运看到这篇文章,正好做项目要用到!
-
79楼
yang105 2011-10-17 10:02发表
-
- 谢谢楼主
-
78楼
zo1010 2011-09-27 14:49发表
-
- 很清晰,赞!
-
77楼
liuzongyao82 2011-08-28 17:00发表
-
- 缺少了执行接口关系, 很泛化关系类似, 不过接口中没有属性, 图就是泛化关系中实线变成虚线
-
76楼
jiajia_07 2011-08-06 20:39发表
-
- 谢谢啊,楼主真是个好人啊啊啊啊啊啊啊啊啊 啊啊 啊啊啊啊
-
75楼
lab17 2011-07-26 09:25发表
-
- 这种扫盲的文章,以后要多多支持,,
-
74楼
zhaoyuan7511 2011-07-19 16:22发表
-
- 0.0
-
73楼
omic32 2011-07-12 16:48发表
-
- 简单易懂,学习了,谢谢
-
72楼
fj_mh 2011-07-04 11:18发表
-
- 谢谢,辛苦了!正在学习中。有大收获。
-
71楼
JerryCong1995 2011-06-25 01:17发表
-
-
-
70楼
DiDaDeepWater 2011-05-21 17:37发表
-
- 还有更深厚点的东西,也吃出来吧。让大家观摩。
-
69楼
bianjie008 2011-04-21 22:03发表
-
- 顶楼主一个,写得很好
-
68楼
mengheidou 2011-04-20 20:02发表
-
-
写的很清晰 顶一下
-
67楼
wy721 2011-03-04 14:32发表
-
- 写的很好,学习了,非常感谢....
-
66楼
FG2006 2011-02-24 16:29发表
-
-
学习了,谢谢
-
65楼
suzhou2007 2011-01-17 08:55发表
-
-
非常好啊!通俗易懂!!!
-
64楼
perfectfp 2010-12-15 10:55发表
-
- 学习了
-
63楼
hj490134273 2010-11-29 10:15发表
-
-
几种常见的关系讲的非常清楚,受教!
-
62楼
py_1984 2010-11-25 10:06发表
-
-
-
61楼
panfengsoftware 2010-10-07 20:00发表
-
- 不错,有实际的例子!
-
60楼
dreamsfly 2010-09-03 10:32发表
-
-
醍醐灌顶!
-
59楼
javadu 2010-07-03 15:45发表
-
-
强
-
58楼
匿名用户 2010-07-03 15:44发表
-
-
-
57楼
wangmogang 2009-03-11 01:56发表
-
- 顶
-
56楼
zlotus 2009-02-24 13:26发表
-
- 挺好的 顶你
-
55楼
chofer 2009-01-11 00:51发表
-
-
非常感谢!很好理解~也很清晰~~
>.<
-
54楼
yangguoyk 2009-01-05 13:09发表
-
- 感谢分享!
-
53楼
111 2008-12-18 13:51发表
-
- 真心感谢,写的非常的好.比起一些乱吹一阵的垃圾书好多了.
-
52楼
temp 2008-12-01 17:33发表
-
- 很好
-
51楼
ljjyyy 2008-11-28 22:57发表
-
-
相当实用
活文档
-
50楼
good 2008-11-19 17:12发表
-
- very good
-
49楼
mycowcn 2008-11-11 15:26发表
-
- 支持sunnyboycao的说法,在<<大话设计模式>>一书中也有一些这样的简洁的介绍.
-
48楼
sunnyboycao 2008-11-03 16:40发表
-
-
是我见过的最简洁,最实用,最清晰的UML类关系解析!
太感谢指路人了!醍醐灌顶
-
47楼
yinshanhua 2008-10-23 20:17发表
-
- 支持
-
46楼
niravna 2008-10-21 13:14发表
-
- Cool, very explicit, clear, and easy to understanding.
-
45楼
wudaiwen1022 2008-10-08 17:01发表
-
- 哥们,真是太感谢了。你真是一个古道热肠的好人啊。祝你心想事成。前途无量哦。
-
44楼
wudaiwen1022 2008-10-08 17:00发表
-
- 哥们,真是太感谢了。你真是一个古道热肠的好人啊。祝你心想事成。前途无量哦。
-
43楼
wudaiwen1022 2008-10-08 17:00发表
-
- 哥们,真是太感谢了。你真是一个古道热肠的好人啊。祝你心想事成。前途无量哦。
-
42楼
zww 2008-09-08 15:12发表
-
-
清楚。。希望某天我也能这样~~
:)
-
41楼
wzh81930 2008-07-28 16:25发表
-
-
支持大家说得都很清晰!
南京朋友可以相互交流!
QQ:7122861
-
40楼
xiaoyvr 2008-06-19 02:12发表
-
-
不错的总结,思路很清晰。
引用类型该在这里面能扮演什么角色呢?
-
39楼
Jammy 2008-06-12 17:47发表
-
- good
-
38楼
ddd 2008-05-26 15:36发表
-
- 写的非常不错 不顶不行啊
-
37楼
thebye85 2008-05-20 11:11发表
-
- 写的太好了。通俗易懂。
-
36楼
GUEST 2008-05-01 16:12发表
-
- VERY GOOD!
-
35楼
haha 2008-04-03 16:25发表
-
- 写的很好
-
34楼
fly 2008-01-12 11:18发表
-
- 写的好 比晦涩的书强多了
-
33楼
天下无双 2008-01-05 15:56发表
-
-
聚合/组合 的区分:
两者都表示 整体-部分 的关系。
但 聚合 的 整体-部分 是可分离的, 如 停车场-汽车
代码如下:
class Park
{
public:
Car MyFerraris [];//这里考虑到停车场可能有多辆车,所以用数组来表示,当然私人车库只能停放一辆法拉利也可以这样表示 Car MyFerrari
};
class Car
{
};
而 组合 的 整体-部分 是不可分离的,两者的生命周期相同,唇齿相依,唇亡齿寒
代码如下:
class Car
{
public:
Tyre tyre1;
Car()
{
tyre1=new Tyre(); //Car的构造函数中创建轮胎tyre1,因为两者共生
}
};
class Tyre // tyre 之意为 轮胎
{
};
对于UML中的类间关系 有时候 两种 不同的关系 所产生的代码是相同的,这就可能从 具体的应用环境 上去区分了。