前言
在学习代码优化和架构设计方面经常会看到UML类图,所以还是有必要花时间去学习,但是学习过程中经常忘记和搞混各种图和各种线的关系,特此抽出时间对此进行整理。
UML介绍
UML通过图形化的表示机制从多个方面对系统的分析和设计模型进行刻画描述,总共分为4大类,共定义了10种视图。
用例图
用例图是作为需求分析阶段和用户进行沟通的工具。通过用例图展示系统的功能范围和系统边界,提供对功能需求更直观的方法,用来描述一个业务场景的具体功能,包括系统的输入、输出。
用例图也是UML中重要的一部分,功能用例做的好,后续的类图、交互图才能做的更精细准确。
用例图包括以下元素参与者
、用例之间的关系
、用例图
、用例描述
- 参与者(actor)
参与者指需要使用系统或与系统交互的东西,包括人、设备、外部系统等,参与者属于系统以外的部分。
通常情况用该图表示
- 用力之间的关系
用例之间的关系有关联(association)、泛化(generalization)、包含(include)、扩展(extend)
-
关联:参与者与用例之间的关系
-
泛化:参与者之间或用例之间的关系,可以理解为继承
-
包含:用例与用例之间的关系,一个用例包含另一个用例,也可以理解为一个用例依赖另一个用例
-
扩展:类似于包含,但是又区别于包含,属于对用例进行了行为上的扩展,比如用户浏览网站,订单加入库存对于购物属于包含关系,属于普通关系,但是购物对于浏览网站属于增加了额外的行为,扩展关系同时又包含了订单加入库存,所以购物属于扩展了浏览网站。
-
用例图
用例图是显示一组用例与参与者关系的图,通常对一个系统功能针对某个环境进行描述参与者与用例之间的关系
-
用例描述
对用例图的自然语言描述,意在将用例图中参与者和用例之间的关系和行为交互时双方的行为描述清楚
静态图
类图
类图主要展示系统中的类与类之间的关系、包括属性、方法,通常用于需求调研后期和设计阶段,用于帮助开发人员理解系统的结构、属性和方法之间的关系。侧重点在于类之间的关系。
类图中主要包含类(Class)
、属性(Attributes)
、方法(Methods)
、关系(Relationships)
、接口(Interfaces)
- 类:类是对具有相似特征和行为的对象的抽象。在类图中,类通常用矩形框表示,框中包含类的名称
- 属性:属性是类的特征,描述了类的状态。属性通常位于类的顶部,,使用名称和类型来表示
- 方法:方法是类的行为,描述了类能够执行的操作。方法通常位于类的中间部分,使用名称、参数和返回类型来表示
- 接口:接口定义了类必须实现的方法,通常用特殊的矩形框表示,并在框中列出接口的方法
- 关系:类之间的关系有
关联
、聚合
、组合
、泛化
、依赖
,用于描述类与类之间的关系
- 关联:表示两个类之间的逻辑关系,从一个类得知另一个类的信息,逻辑关系有
1:1
,1:n
,n:n
。
- 聚合:聚合表示整体与部分之间的关系,即一个类是另一个类的一部分,是一种弱的关联关系,表示部分可以存在独立于整体的情况
在代码中可以这样理解,汽车销毁而轮胎依旧可以独立存在
/*
* 轮胎类
*/
public class Tyre {
/*
* 构造方法
*/
public Tyre() {}
}
/*
* 汽车类
*/
public class Car{
/*
* 轮胎属性
*/
private Tyre tyre;
/*
* 构造方法
*/
public Car(Tyre tyre) {
this.tyre = tyre;
}
}
- 组合:组合也表示整体与部分之间的关系,但是部分不能独立存在于整体之外。是一种强的关联关系,表示整体对象负责创建和管理部分对象的生命周期
在代码中可以这样理解,轮胎随着汽车销毁而销毁,无法独立存在
/*
* 班级类
*/
public class Department{
/*
* 构造方法
*/
public Department() {}
}
/*
* 学校类
*/
public class School{
/*
* 班级属性
*/
private Department department;
/*
* 构造方法
*/
public School(Department department) {
this.department= new Department();
}
}
- 泛化:通俗理解为继承,
- 依赖:依赖有点类似于组合和聚合,但是又不太一样,区别在于,依赖的声明周期比组合和聚合都要端,上面解释了聚合和组合都是在类创建的时候就已经被初始化,但是依赖是在Person类调用某一个方法时,依赖于Car类的某个方法。
代码中可以这样理解,只有在调用Person的回家方法时,才创建所依赖的Car对象并调用方法,且在Person生命周期结束被销毁时,Car也随着Person销毁。
/*
* 人类
*/
public class Person{
/*
* 车辆属性
*/
private Car car;
/*
* 构造方法
*/
public Person() {}
/*
* 回家方法
*/
public goHome() {
this.car = new Car();
car.goHome("家");
}
}
/*
* 汽车类
*/
public class Car{
/*
* 构造方法
*/
public Car(){}
/*
* 回家方法
*/
public goHome(String target) {
system.out.println("前往" + target);
}
}
一个完整的类图一般为这样
对象图
对象图区别于类图侧重于类之间的关系,对象图侧重于某一个特性情况下对象与对象之间的交互关联,常用与测试时展示某一时间内对象的状态和行为
如何画对象图参考链接: UML画图之对象图
包图
包图描述系统的分解结构,表示包与包之间的关系,包由子包和类组成
如何画宝图参考链接: 面向对象——UML包图
行为图
时序图 / 顺序图
时序图用于描述对象之间的传递消息的时间顺序, 即用例中的行为顺序。强调一系列操作在时间上的顺序,描述系统/对象间的交互过程
-
激活:表示参与者在这一段是被激活状态
-
同步消息
-
异步消息
-
返回
-
片段
完整时序图参考支付宝支付时序图,支付宝的支付时序图还是非常标准和清晰的,值得参考学习
协作图
协作图是用于描述行为如何用系统中的成分协作实现的。它们展示了对象之间的消息传递和执行顺序,以及它们如何协同工作以实现系统的功能。协作图中包括参与者
、对象
、消息
、链
-
参与者:
-
对象:对象是所属类的直接或者间接实例
-
消息:分为
同步消息
异步消息
返回消息
简单消息
-
链:可以理解为两个对象相互关联
一个完整的协作图,此图从https://zhuanlan.zhihu.com/p/149269481转
状态图
状态图描述对象在其生命周期内所有可能状态及其转换的图形化表示方法,引起状态变化的事件,以及状态转变的伴随的动作
分为起始
、终态
、状态
、事件
- 起始:状态的起始
- 终态:状态的结束
- 状态:对象在生命周期内的状态
- 事件:印发状态变更的事件,一般用箭头表示
一个完整的状态图
活动图
活动图用来描述系统工作流程和并发行为,主要强调不同操作之间的触发机制和操作内容,描述操作间的逻辑关系。
活动图包含几个基本概念活动
、泳道
、分支
、分叉
、汇合
、对象流
-
活动:活动表示流程中任务的执行,分为活动状态和动作状态
-
泳道:活动图内的区域划分,根据活动职责进行划分,一个泳道可能由一个类实现,也有可能是多个类实现
-
分支:对于一个事件可能触发不同的条件转向不同的活动
-
分叉:表示系统或对象中的并发行为,表示两个或多个控制流经过分叉后并发执行
-
汇合:表示两个或多个控制流并发执行后汇合到一起
-
对象流:是动作状态或者活动状态与对象之间的依赖关系,可以看做活动的输入或输出,表示动作使用对象或动作对对象的影响
最终一个完整的活动图就是这样
实现图
构件图
构件图是一组构建以及之间的关系,构件是物理的、可替换的部分,构件图用于描述软件系统中各个组件之间的静态结构和依赖关系。可以理解为库、模块、类、文件等。通俗表达两个构件之间的依赖关系,包括编译、执行时的链接关系。
在构件图中,通常会包含构件
、接口
、依赖关系
、关联关系
:
-
构件:表示软件系统中的各个组成部分,例如库、模块、类、文件等。
-
接口:表示构件之间的接口或依赖关系,描述了一个构件如何与其他构件进行通信或交互。
-
依赖关系:表示一个构件依赖于另一个构件的情况,通常以箭头表示。
-
关联关系:表示两个构件之间的关联关系,通常用于描述它们之间的协作或交互方式。
部署图
部署图用于描述系统的物理部署结构,用来显示系统计算节点的拓扑结构和通信路径与节点上运行的软构件,即软件系统的组件如何被部署到硬件节点上。它显示了软件系统的各个组件(如类、模块、库等)以及它们在物理节点上的部署情况和关系。
-
节点:表示系统的物理节点,例如服务器、计算机、设备等。每个节点可以包含若干个组件
-
组件:表示系统的软件组件,例如类、模块、库等。每个组件可以部署在一个或多个节点上
-
关系:表示组件之间的依赖关系和通信方式,例如组件之间的调用、数据传输等
实例图可参考链接: 部署图