总目录
前言
作为一个程序员,我们经常会使用UML来绘制各种图(UML中定义了用例图、类图、时序图、协作图等九种),类图就是其中常用图之一。设计模式中经常会用到的是类图,本文主要是学习UML类图相关资料后的汇总笔记,也是作为设计模式系列文章中“前菜”。
一、基本介绍
1.什么是UML
(1) 基本介绍
- Unified Modeling Language (UML)又称统一建模语言或标准建模语言,是一种用于软件系统分析和设计的语言
- UML是一个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持,包括由需求分析到规格,到构造和配置。
- UML作为一种模型语言,它使开发人员专注于建立产品的模型和结构,而不是选用什么程序语言和算法实现。当模型建立之后,模型可以被UML工具转化成指定的程序语言代码。
UML规范用来描述建模的概念有,类(对象的)、对象、关联、职责、行为、接口、用例、包、顺序、协作,以及状态。
通俗理解: UML本身是一套符号的规定,就像数学符号和化学符号一样,这些符号用于描述软件模型中的各个对象和对象之间的关系,比如类、接口、实现、泛化、依赖、组合、聚合等
(2) UML分类
UML图分类:
- 用例图(use case)
- 静态结构图: 类图、对象图、包图、组件图、部署图
- 动态行为图:交互图(时序图与协作图)、状态图、活动图
- 类图是描述类与类之间的关系的,是UML图中最核心的
2.什么是UML类图
画UML图与写文章差不多,都是把自己的思路描述给别人看。UML类图就是负责描述软件系统中对象以及对象间的关系的架构图,可让我们从更高的角度熟悉系统。
UML类图是一种结构图,用于描述一个系统的静态结构。类图以反映类结构和类之间关系为目的,用以描述软件系统的结构,是一种静态建模方法。类图中的类,与面向对象语言中的类的概念是对应的。
在系统设计阶段,类图直接引导面向对象的编程语言实现类。类图是生成代码的核心要图。如果类图设计得好,整个系统的代码框架可以有类图自动生成,大大简化了系统编码所耗费的时间。因此,我们进一步利用类图,使得代码的编写编程一种自动化工作,而整个信息系统的建设中心都可以集中到分析设计上来。
类图是面向对象系统建模中最常用和最重要的图,是定义其它图的基础。类图主要是用来显示系统中的类、接口以及它们之间的静态结构和关系的一种静态模型。
3.绘制UML工具
网页版:https://www.processon.com/
软件版:PowerDesigner(个人使用)、UMLet、Visio、StartUML
二、类图解析
1. 如何表示一个类
通过UML工具(ProcessOn)拖动一个表示“类”的图形,显示如下:
在类的UML图中,使用长方形描述一个类的主要构成,长方形垂直地分为三层,以此放置类的名称、属性和方法。
行数 | 代表内容 | 格式 |
---|---|---|
第一行 | 表示类的名字 | 仅名字 |
第二行 | 表示类的属性 | 可见性 名称 :类型 [ = 默认值] |
第三行 | 表示类的方法 | 可见性 名称(参数列表) [ : 返回类型] |
注意:属性和方法都要标上可见性:
符号 | 代表内容 |
---|---|
+ | public |
- | private |
# | protected |
~ | default,也就是包权限 |
_ | 下划线表示static |
斜体 | 表示抽象 |
2.如何表示抽象类
其中,一般类的类名用正常字体粗体表示;抽象类名用斜体字粗体
3.如何表示接口
通过UML工具(ProcessOn)拖动一个表示“接口”的图形,显示如下:
行数 | 代表内容 | 格式 |
---|---|---|
第一行 | 表示接口的名字 | 明确写上<<接口>>的标识,然后换行写下接口名 |
第二行 | 表示接口的方法 | 可见性 名称(参数列表) [ : 返回类型] |
4.其他图表示
除了以上图示之外,我们可能会在UML绘制里还能找到以下几种:简单类、多例类、活动类等,这些在类图中并不常用,一般如果一个类只有方法没有属性,则第二行空着即可。
此外,常见的还有一种对象,那就是上图表示的注释。
三、类关系
表示类的关系总共有6种,这6种又可以分为3类。
- 泛化:继承、实现
- 关联:聚合、组合、 关联
- 依赖 :依赖
六种关系的箭头表示如下图所示:
1. 泛化
泛化 表示类与类之间的继承关系,接口与接口之间的继承关系,或类对接口的实现关系。泛化包括继承和实现两种关系
泛化表达了is a的关系模型,当A以某种形式是一个B的时候,就是泛化关系
(1) 继承关系
- 继承关系(也可称泛化关系):用于描述父类(基类)与子类(派生类)之间的关系。 子类继承父类的所有功能,父类所具有的属性、方法,子类应该都有。子类中除了与父类一致的信息以外,还可拥有自己特有的信息。
- 表示方法:使用一个实线+空心三角箭头,从子类指向父类即表示继承
- 示例:鸟类继承抽象动物类
- 代码实现
Console.WriteLine("自己动手试试");
(2) 实现关系
-
实现关系:主要用描述接口和实现类的关系。 接口(包括抽象类)是方法的集合,在实现关系中,类实现了接口,类中的方法实现了接口声明的所有方法。
-
表示方法:使用一个虚线+空心三角箭头,从实例指向接口即表示一个实现
-
示例:大雁实现了飞翔接口。
-
代码实现
Console.WriteLine("自己动手试试");
2. 关联
对于两个相对独立的对象,当一个对象的实例与另一个对象的一些特定实例存在固定的对应关系时,这两个对象之间为关联关系。关联包含3种关系:聚合、组合、关联。
关联表达了has a的关系模型,当A拥有一个B的时候,就是关联关系
(1) 聚合关系
-
聚合关系:描述整体和部分的关系,整体与部分可以分开。
- 表示一种弱的‘拥有’关系,即has a的关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分。 两个对象具有各自的生命周期。
- 聚合关系也表示类之间整体与部分的关系,成员对象是整体对象的一部分,但是成员对象可以脱离整体对象独立存在。
-
表示方法:使用一个实线+空心菱形箭头,从整体指向局部即表示一个聚合
-
示例:每一只大雁都属于一个大雁群,一个大雁群可以有多只大雁。当大雁死去后大雁群并不会消失,两个对象生命周期不同。
注意:聚合关系只是将一些对象聚集在一起,但他们的关联是相对较弱的,也就是说,局部对象是可以脱离整体对象而单独存在的 -
代码实现
Console.WriteLine("自己动手试试");
(2) 组合关系
-
组合关系:描述整体与部分的关系,但是整体与部分不可以分开。
- 组合是一种强的‘拥有’关系,是一种contains-a的关系,体现了严格的部分和整体关系,部分和整体的生命周期一样。
- 组合关系表示类之间整体与部分的关系,整体和部分有一致的生存期。一旦整体对象不存在,部分对象也将不存在,是同生共死的关系。
-
表示方法:使用一个实线+实心菱形箭头,从整体指向局部即表示一个组合
-
示例:鸟和翅膀就是组合关系,因为它们是部分和整体的关系,并且翅膀和鸟的生命周期是相同的。
注意:组合又叫合成,顾名思义是有局部合起来才成为了一个整体,他们是密不可分的,他们是强关联关系,局部脱离了整体就不存在了 -
代码实现
Console.WriteLine("自己动手试试");
(3) 关联关系
- 关联关系:表示一个类的属性保存了对另一个类的一个实例(或多个实例)的引用。
- 对于两个相对独立的对象,当一个对象的实例与另一个对象的一些特定实例存在固定的对应关系时,这两个对象之间为关联关系。
- 关联关系是类与类之间最常用的一种关系,表示一类对象与另一类对象之间有联系。
- 关联关系有四种:双向关联、单向关联、自关联、多重数关联。
- 在UML图中,双向的关联可以有两个箭头或者没有箭头,单向的关联或自关联有一个箭头。
- 表示方法:使用一个实线箭头,从拥有者指向被拥有者。
- 示例:企鹅需要‘知道’气候的变化,需要‘了解’气候规律。当一个类‘知道’另一个类时,可以用关联。
当一个关系明显是has a的拥有关系,但不像聚合也不像组合那样来描述整体与局部的时候,就应该考虑使用关联关系来描述。组合、聚合也属于关联关系,只是关联关系的类间关系比其他两种要弱。
- 代码实现
Console.WriteLine("自己动手试试");
3. 依赖
对于两个相对独立的对象,当一个对象负责构造另一个对象的实例,或者依赖另一个对象的服务时,这两个对象之间主要体现为依赖关系。依赖包含了1种关系:依赖。
依赖表达了use a的关系模型,当A使用了一个B的时候,就是依赖关系
(1) 依赖关系
-
依赖关系:假设A类的变化引起了B类的变化,则说名B类依赖于A类。
- 大多数情况下,依赖关系体现在某个类的方法使用另一个类的对象作为参数。
- 依赖关系是一种“使用”关系,特定事物的改变有可能会影响到使用该事物的其他事物,在需要表示一个事物使用另一个事物时使用依赖关系。
-
表示方法:使用一个虚线箭头,从使用者指向被使用者。
-
示例:动物依赖氧气和水。调用新陈代谢方法需要氧气类与水类的实例作为参数(表达了一个物体需要通过另一个物体来完成工作,但他们之间没有包含的关系)
这里的动物,有一个新陈代谢的功能,要工作则必须有空气和水,因此构成了他们之间的依赖关系。特别的,这里的依赖不同于我们上面关联的概念,在企鹅与气候的关系中,企鹅的生存方式依赖于气候的变化,但他们不是依赖关系,因为企鹅不需要气候作为参数进行某项工作,如果企鹅有一个功能是迁徙,需要传入一个气候,此时就是依赖关系了。 -
代码实现
Console.WriteLine("自己动手试试");
4. 小结
- 从关系角度总结:
- 继承(泛化)、实现(实现)这两种关系比较简单,它们体现的是一种基类与实现类、或者接口与实现类之间的纵向关系。
- 聚合、组合、关联、依赖四种关系则体现的是类与类、或者类与接口之间的引用/横向关系。这四种关系所表现的强弱程度来看,从强到弱依次为:组合>聚合>关联>依赖。
- 组合、聚合、关联这三种类关系的代码结构一样,都是用属性来保存另一个类的引用,所以要通过内容间的关系来区别。
- 从图示角度总结:
- 继承、实现都是空心三角箭头,指向class是实线、指向interface则是虚线
- 通过上面聚合,组合,关联三种关系图示对比,所有的关联关系都是实线箭头,只是聚合(相对组合关系弱)用了一个空心菱形,而组合(强)用了一个实心菱形。
- 只有依赖是虚线箭头
- 从代码角度总结:
- 继承和实现,只是通过:(冒号)进行一个继承或实现
- 聚合,组合,关联主要体现为成员变量,A类作为B类的一个成员变量存在
- 依赖主要表现为某个类的方法使用另一个类的对象作为参数。
四、类图绘制实操
五、扩展
总结
以上就是今天要讲的内容,本文介绍了UML图,希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。
参考资料
UML详解(1):类的关系与如何绘制类图
UML类图详解及类图设计
UML类图介绍以及关系详解
UML类图详解
VisualStudio 如何使用UML呢
UML一一 类图关系 (泛化、实现、依赖、关联、聚合、组合)