你的位置:首页 > Java教程

[Java教程]我对uml类图关系的理解


 

uml类图的关系:

泛化关系也就是继承。

实现关系就是一个类实现另外一个接口。

依赖关系就是一个类使用了另外一个类,是一种使用关系,在这个类的某个服务中需要另外一个类来协助。

关联关系就是一类拥有另外一个类,是一种拥有关系,这个类在创建的时候需要另外一个类的协助,可以是双向的但是最好依据业务的关注点变成单向的。

聚合关系是整体与部分的关系但是部分可以离开整体而存在。

组合关系也是整体与部分的关系但是两者的生命周期是绑定在一起的,部分不能离开整体而存在。

更喜欢我们大哥的分类:

多态:

泛化关系,实现关系

依赖:

依赖关系

关联:

关联关系,聚合关系,组合关系

详见博客

类图关系的图形表示:

泛化关系(继承)
(带三角箭头的实线,箭头指向父类)

实现关系
(带三角箭头的虚线,箭头指向接口)

依赖关系
(带箭头的虚线,指向被使用者)

关联关系:
(带普通箭头的实心线,指向被拥有者)

聚合关系
(带空心菱形的实心线,菱形指向整体)

组合关系
(带实心菱形的实线,菱形指向整体)

代码层面的表示:

泛化关系
public Class Tigger extends Animal{
实现关系
public Class Course implements Goods{
依赖关系
局部变量、方法的参数或者对静态方法的调用

关联关系,聚合关系,组合关系都是成员变量

实际应用需注意:

要依据真实需求的描述来确定类关系

类与类之间关系的确定必须是依据实际需求,换句话说就是在某个语义下才能确定两个类的关系,客观真实的反应真实需求。
比如:语义环境是:"汽车有四个车轮,有了车轮汽车才可以行驶,车轮本身有自己的特征(颜色,大小)"
那么我们就可以抽取出汽车类和车轮类,那么如何确定他们的关系??
根据uml类关系我们可以排除实现和继承,那么就剩下关联和依赖,依赖强调的是使用关系,关联强调的是拥有关系,“有车轮才可以行驶”这句话就可以
推断出他们不是使用关系,而是拥有关系,汽车必须拥有车轮。所以应该是:

比如:语义环境“卸掉的车轮要放到车库中去”依据这句话我们可以抽取两个类
车轮类和车库类,那么他们之间的关系又是什么呢?
肯定也不是实现和继承,那究竟是依赖还是关联呢,根据"车轮放到车库中"这句话可以得出,车库要提供一个存放车轮的服务,
两者不是拥有关系而是使用关系。所以:

另外一种方式确定类的关系

语义描述"一个学习视频有多个知识点,一个知识点又可以被多个视频拥有"
还有一种方法来确定两个类的关系,使用类关系的代码体现确定类关系:
依赖关系的代码体现是方法参数,局部变量,静态方法调用。
关联关系的代码体现是成员变量。
根据"一个学习视频有多个知识点"的描述我们可以知道,视频类肯定有一个list<知识点类>的成员变量,
根据"一个知识点又可以被多个视频拥有"的描述我们可以知道,知识点类也有一个list<视频类>的成员变量,
所以可以断定视频类和知识点是关联关系。

针对多对多一对多这种关系的指向如何确定以哪一类为起点呢??

还是上面的语义描述"一个学习视频有多个知识点,一个知识点又可以被多个视频拥有"
由上面的分析我们已经可以确定视频类和知识点是关联关系,那我们在做指向的时候做双向箭头的话,理解起来会有问题,如:

所以我们团队的做法是根据你的业务关注程度,比如说你正在做视频有关的业务,那你就应该讲箭头指向知识点类。

确定完类关系为关联关系之后我们创建的类要如何体现类关系呢?比如:关联关系的一对多,多对多?

可能有人觉得前面已经讲过关联关系的代码体现是成员变量吗,直接使用成员变量不就完了吗?
比如:
一对多:
一里面放一个类型为多的集合成员变量。
多对多:
双方都存放彼此类型集合的成员变量。
但是,这样我们在做数据持久的时候非常麻烦。
所以我们的做法是:
如果是一对多就在以里面存放一个多的主键ID,比如:
一个视频一定是属于某个老师的,代码如图:

如果是多对多我们采用的是关系表去做,
比如说视频和知识点的关系我们会创建一个关系表去承载这个多对对关系,在实体类中不做体现。