本文转自http://blog.csdn.net/dylgsy/article/details/1076044
UML的类图的关系分为:关联、聚合\组合、依赖、泛化(继承),其中关联又分为双向关联、单向关联、自身关联,我们可以通过下面的图列看出其中联系和区别:
关联
双向关联:
C1-C2:指双方都知道对方的存在,都可以调用对方的公共属性和方法。
在GOF的设计模式书上是这样描述的:虽然在分析阶段这种关系是使用的,但我们觉得对于它所描述设计模式内容的类关系来说显得太抽象了,因为在设计阶段关联关系必须被映射成为对象引用或者指针。对象引用本身就是有向的,更适合于表达我们所讨论的关系。
所以这种关系在设计的时候比较少用到,关联一般都是有向的。
使用ROSE生成的代码是这样的:
class
{
public:
};
class
{
public:
};
双向关联在代码的表现为双方都拥有对方的一个指针,当然也可以是引用或者是值。
单向关联
C3->C4:表示相识关系。指C3知道C4,C3可以调用C4的公共属性和方法。没有生命期的依赖,一般是表示为一种引用:
生成代码如下:
class
{
public:
};
class
{
};
单向关联的代码就表现为C3有C4的指针,而C4对于C3一无所知
自身关联(反身关联):
自己引用自己,带着一个自己的引用
代码如下:
class
{
public:
};
就是在自己的内部有着一个自身的引用
2. 聚合\组合
当类之间有整体-部分关系的时候,我们就可以使用组合或者聚合。
聚合:
表示C9聚合C10,但是C10可以离开C9而独立存在(独立存在的意思是在摸个应用的问题域中这个类的存在有意义)
代码如下:
class
{
public:
};
class
{
};
组合(也有人称为包容):
一般是实心菱形加实线箭头,如上图所示,表示的是C8被C7包容,而且C8不能离开C7而独立存在。但是这是是问题域而定的:例如在关心汽车的领域里,轮胎一定要组合在汽车类中,因为它离开了汽车就没有意义了。但是在卖轮胎的店铺业务链,就算轮胎离开了汽车他也是有意义的,这样就可以使用聚合。在《敏捷开发》中还说道,A组合B,则A需要知道B的生存周期,即可能A负责生成或者释放B,或者A通过某种途径知道B的生成和释放。
它们的代码:
class
{
public:
};
class
{
};
可以看到,代码和聚合是一样的,具体如何区别,只能用语义来区分了。
3. 依赖
依赖:
指C5可能要用到C6的一些方法,也可以这样说,要完成C5里所有的功能,一定要有C6的方法协助才行,C5依赖于C6的定义,一般是在C5类的头文件中包含了C6的头文件。ROSE对依赖关系不产生属性。
PS:要避免双向依赖,一般来说,不应该存在双向依赖。
代码如下:
//
#include
class
{
};
//
#include
class
{
};
虽然ROSE不生成属性,但是在形式上一般是A中的某个方法把B的对象作为参数使用(假设A依赖于B),如下:
#include
class
{
}
依赖和聚合\组合、关联等有什么不同 ?
4. 泛化(继承)
泛化关系:
如果两个类存在泛化的关系时候就使用。例如父和子,动物和老虎,植物和花等等。
ROSE生成的代码很简单,如下:
#include
class
{
};
5.模板
上面的图对应的代码如下:
template<int>
class
{
};
这里在说一下重复读,其实看完了上面的描述之后。我们应该清楚了各个关系间的关系以及对应的代码是怎样的,所谓的重复度,也不过是上面的扩展,例如A和B有着“1对多“的重复度,那么在A中就有一个列表,保存着B对象的N个引用,就是这样而已。