文章目录
- 1.概述
- 2.时序图的组成元素
- 2.1.角色(Actor)
- 2.2.实体和对象
- 2.3.生命周期线(Lifeline)
- 2.3.1.激活(Activation)
- 2.3.2.消息(Messages)
- 2.3.3.组合片段(Fragments)
- 3.总结
1.概述
时序图,也称为顺序图,是用来展示对象之间交互关系的一种UML图表,它通过描述在不同时间上发生的对象的动作来帮助开发人员更清楚地理解系统的结构和功能,从而达到优化代码、简化设计、提高软件的质量和效率、帮助团队成员沟通协作等目的。
时序图与活动图的区别在于:
- 活动图用于描述系统或软件中的业务流程,强调的是流程步骤。
- 时序图用于描绘多个对象之间的交互行为,强调的是时间顺序。
时序图更加贴近于代码的实现逻辑,如果想描述的是多个对象之间的调用、响应、回调等发生的顺序,就可以使用时序图。
2.时序图的组成元素
我们可以直接通过一个现成的时序图来进行学习,下面是我从微信官方文档上截的一张APP支付的时序图。
上图中有很多各式各样的图形,如果没有接触过时序图的话,这张图乍一看会感觉有点复杂,但是没有关系,接下来我们就将这张图分解开来,一个一个的解释各个图形的含义。
另外,也会对上图中没有使用到又相对比较重要的图形做一定的补充。
2.1.角色(Actor)
角色整个流程的外部参与者,可以是某个人,也可以是某个项目或者服务,与用例图中的执行者(参与者)是一个意思,例如上面的支付时序图中的角色就是实际要执行支付动作的用户。角色通常会使用一个小人来表示:
2.2.实体和对象
实体与角色的意思相近,指的是流程内部的组成部分,可以表示一个服务、一个系统或者一个抽象的业务流程等,实体在时序图中一般使用矩形框或带下划线的圆形来表示。
个人更喜欢使用矩形框来表示,在同一个实体下的对象比较多的情况下,矩形框更方便把宽度拉长。
对象的含义较多,与开发人员关联度最高的一种含义就是指的某个类的对象实例,可以填写在生命周期线上的矩形框内,一般是通过对象名:类名来表示,这里引入了一个生命周期线的概念,我们继续往下看。
2.3.生命周期线(Lifeline)
生命周期线是时序图中的最核心的内容,它通过一个横向的矩形框和一条纵向的虚线组成,接着上面所说的对象的概念,在上图中的商户后台系统中有两个不同的对象共同完成支付流程,则可以表示成下图的格式:
2.3.1.激活(Activation)
激活表示的是在对象的生命周期中在执行操作的时间段,它是在生命周期线上通过一个纵向的矩形框表示的。
2.3.2.消息(Messages)
消息用来表达对象之间的交互关系(即:请求响应的关系),并不是指的消息中间件中的消息,常见的交互关系有以下几种:
- 调用消息(call/invocation message):在不同类的对象间发起的调用,即
request
,用实线+实心三角箭头表示。 - 响应消息(return message):对调用消息的响应,即
response
,用虚线+箭头表示。 - 自调用消息(self message):通常表示同一个对象中的不同方法间的调用。
- 递归消息(recursive message):通常表示同一个对象中的方法自己调用自己。
按照这个规则,修改一下上面的时序图,在下图中使用了上述的前面三种消息,使用红色字体
标注。
可以看到的是在消息的线上面,通过数字描述了调用和响应的时间顺序,通过文字来描述当前流程步骤的含义,同时,还可以加上调用的方法名,以明确与代码的对应关系。
在微信官方的时序图上,使用了递归消息来表达了自调用的含义,这里可能是因为只有实体没有对象信息,想表达的是不同对象中的方法调用(即商户系统后台中有不同的对象),但是在对象比较明确的情况下,虽然递归消息也不是不能用,但不推荐,因为递归消息更常用的含义是用来表示一个方法自己调用自己,用它来表达自调用容器引起歧义。
调用消息出了同步调用以外,还可以异步调用,异步调用的表示方式众说纷纭,有实线+箭头,实线+空心三角形,实线+闪烁箭头等等,当不能明确的表示异步调用时,在调用的实线上明确的标注出是异步调用也不失为一种方式,谁都能看得懂。
2.3.3.组合片段(Fragments)
组合片段表示的是多个操作形成的组合操作,用于表达更加丰富的操作,常见的是循环、判断。片段的图形是一个包裹了多个生命线、消息的大矩形框,再大矩形框左上角还有一个小框,里面填写片段的操作类型,大概是这么一个样子:
上图中的Loop
表示的是循环,而Opt
与Alt
两个都表示条件分支(判断),但两者有一定的区别:
Opt
:只在特性条件下执行,如果不满足则跳过,相当于if
代码块。
Alt
:表示不同的路径会执行不同的操作,相当于if...else
代码块。
现在有一个查询支付订单状态的流程,就可以通过组合片段来表示更为丰富的交互信息,为了方便区分,我给不同块上了不同的颜色。
在原有的微信时序图中统一通过Alt
来表示了一组操作以及if
判断,虽然能大概理解其含义,但实际上没有那么准确,不推荐这么画:
当然,还有更多的组合片段的用法,例如:
- par:支持交互片段的并行运行
- region:临界区,例如
synchronized
块 - ref:用于引入其他的时序图片段
- ……
因为用的频率不高,这里就不详细说明了。
3.总结
总的来说,时序图可以看做是对活动图中交互明细的补充,细节更加丰富,能够指导开发同学进行开放工作。
一个完整流程的时序图中的交互关系可能是非常复杂的,在实际的工作中如果只需要对某一些复杂的逻辑进行建模,像上面的示例那样,只使用其中的一部分也未尝不可。
最后再总结一下本篇的主要内容,即时序图的用法:
- 角色:用来表示实际触发到当前流程的人(系统、服务)是谁。
- 实体和对象:与角色类似,也是表示系统、服务等,区别在于实体与对象在流程内部。
- 生命周期线:时序图中最核心的内容,用于表示对象间的交互操作,包含一个矩形框和一条纵向的虚线。
- 激活:某个对象在整个流程中发生交互操作的时间段,表示为纵向的长矩形框。
- 消息:对象间实际发生的交互,例如同步调用、异步调用、响应、自调用、递归等,使用不同的箭线表示。
- 同步调用:实线 + 实心三角箭头。
- 异步调用:实线 + 空心三角箭头。(最好在实线上标注异步调用)
- 响应:虚线 + 箭头
- 自调用:与同步调用类似,只是同步调用指向其他对象的激活框,自调用指向自己。
- 递归:与自调用类似,只是在指向自己的激活框上,会多出一小块矩形框。
- 组合片段:用来表达多个消息的组合操作,如循环、判断等,通过一个大矩形框将消息包裹起来,左上角还有一个小框填写当前的组合操作类型。
- loop:循环操作
- Alt:判断操作,类似于
if..else
- Opt:也是判断操作,与
Alt
的区别在于,只有if
没有else