在面向对象的软件分析及设计中,UML类图描述了系统中各个组成部分的静态结构关系。


定义

UML类图(Class Diagrams)是一种面向对象分析和设计中,描述被分析系统中各个组成部分之间相互关系的图形。

类图的理解

一直以来,大部分同学对类图存在一些误解。其中最重要的一条是类图中的,与我们指定编程语言中的,并不完全是同一个概念。类图中的,表示一种类别,是对同一类事务的抽象。类图中的,可以表示.NET中的,也可以表示业务场景中的某一个概念单元。 因此,对于类图来说,不仅仅是能够表现类的实现,也能够描述领域模型。

类图中的实体单元

在类图中,有如下几种实体单元:

  • 接口

  • 对象

在UML中,类表示一系列对象的抽象。在类图中,类使用直角矩形表示,中间使用粗体表示类名。

例如在一个餐馆中,顾客可以认为是一个类

1559304620456

当然除了名字以外,类也有一些特征——属性(Attribute)和操作(operation)。

对于需要表现属性和操作的类,需要使用三层的矩形,每层分别为名称,属性,操作。

1559371629112

接口

接口和类的表示方法很类似,也是使用直角矩形表示,不过接口会多一个关键字《interface》。

例如我们可以提取一个Person的接口,它有名字,能吃。

1559372066274

1559372075812

对象

对象是类的实例,也同类的表示方法一样,使用直角矩形。不同的是,在对象的命名上,采用添加下划线的__对象名:类名__

例如一个名叫黄腾霄的顾客。

1559372339092

类图中的关系表示

在类图从,常见的关系使用方法有:实现、泛化、关联、聚合、组合、依赖等。

实现

实现专指类对接口的实现,使用虚线三角表示。从类指向接口。

1559373548522

泛化

泛化专指子类对父类的继承,使用实线三角表示,从子类指向父类

1559373650228

关联

关联是指类图中两个类型的实例之间的联系。这个联系可以是单向或者双向的连接,(即可以通过一定方式从一个实例,找到另一个实例)。也可以是表示为逻辑上或者物理上的组成或者组合(聚合),(例如一个实例是另一个实例的一部分)。

关联由实线表示,可选的是在实线上添加关联名称,以及表示阅读方向的实心三角形

1559374089274

聚合

聚合是关联的子类,表示的是属性和实例之间的弱联系,被聚合部分可以独立存在。

聚合使用空心菱形和实线表示,菱形处于主实例这一边。

:从我的实践上来说,这个标记基本没有什么大用处,完全可以使用普通的关联代替。如果大家发现一些合适的场景,可以联系我

1559374507572

组合

组合是关联的子类,表示的是属性和实例之间的强联系,被组合部分不可以独立存在。

组合使用实心菱形和实线表示,菱形处于主实例这一边。

1559374670304

依赖

依赖表明某一个UML元素需要另一个元素进行说明或者实现。

例如某个类需要进行日志输出,会调用日志工具类的一些方法,那么我们可以认为这个类依赖于日志工具类

依赖使用虚线箭头表示,指向被依赖类

1559375161668

常见问题

如何区分关联、聚合、组合

首先关联是聚合和组合的父类,聚合和组合特指类之间的组成关系,因此通常一端是另一端的某个属性。

聚合和组合的区分是,被聚合或组合的实例,是否能够在逻辑上或者物理上独立存在。这个情况往往需要根据具体场景分析。例如驾驶的场景中,轮胎和汽车是组合关系,它不能独立于汽车存在于这个场景。但是在汽车回收场景中,轮胎可以是聚合关系,因为汽车报废后,轮胎还能够走单独的回收流程。

实践:对于less is more 原则,只对必要的情况进行说明。所以一般情况下,我们可以都使用关联。在特定情况下,再使用组合。至于聚合,我没有发现什么特别的使用场景,所以可以不使用。

如何区分关联和依赖

关联特指实例之间的关系。而依赖的场景就相对广泛,类、包等都可以存在依赖关系。

针对到实例场景,存在依赖通常表示某个类是不完整的,或者不能独立完成某些操作的。

我们可以按照如下问题问自己,确认A类是不是B类的依赖:

  • A类能够作为B类属性存在么
  • 没有A类,B类的所有操作都能独立完成么

如果答案都是不能,那么这个情景下,更推荐使用依赖,而不是关联

实践

这里给出了一个餐厅的类图。

顾客通过菜单进行下单。而订单上记录了菜单中的项目,而这些项目会指向特定的菜肴。订单会交给厨师,厨师做出菜肴。顾客进行食用。

其中菜单中的项目是菜单的组成,因此食用组合。而顾客需要依赖于菜单,才能完成点菜。

1559376104261

参考链接:


本文会经常更新,请阅读原文: https://xinyuehtx.github.io/post/UML%E7%B1%BB%E5%9B%BE.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名黄腾霄(包含链接: https://xinyuehtx.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系