顺序图(Sequence Diagram),又称时序图、序列图,是统一建模语言 UML 中交互图的一种,用来刻画一组对象之间如何通过消息的发送与接收来完成一次协作。它最核心的价值在于强调消息在时间维度上的先后顺序,因此它属于行为图,而不是结构图。类图回答的是"系统里有哪些类、它们之间是什么关系"这样的静态结构问题,而顺序图回答的是"在一次特定场景下,这些对象按照什么先后次序交互"这样的动态行为问题。二者一个描述空间结构,一个描述时间过程,是面向对象建模中互补的两面。
从 UML 官方的图形分类体系来看,UML 的图可以分为两大类:结构图和行为图。结构图包括类图、对象图、构件图、部署图、包图等,描述系统的静态组成;行为图包括用例图、活动图、状态图以及各种交互图,描述系统的动态演化。交互图是行为图下的一个子类,专门刻画对象之间的消息交互,而顺序图正是交互图家族中最常用、考试中出现频率最高的一员。在 UML 2.0 之前,交互图主要由顺序图和协作图构成;UML 2.0 之后又扩充了交互概览图和定时图等成员。这里需提醒一个易混淆的术语问题:中文语境里"时序图"存在歧义,既可指 Sequence Diagram(顺序图),也可指 Timing Diagram(定时图)。软考命题中若无特别说明,"时序图"通常指顺序图。
顺序图的适用对象是"一次具体的交互场景",即一个用例的某一条执行路径,例如"用户成功登录系统"这个用例的主成功场景。把这个场景用顺序图表达出来,就是从参与者到系统各对象之间一连串有先有后的消息。因此顺序图天然和用例图配合使用:用例图划定功能边界和参与者,顺序图则把某个用例内部的对象协作过程细化出来。这也解释了为什么系统分析师考试中顺序图常和用例模型、需求分析放在一起考。
理解顺序图,必须抓住"对象之间通过消息通信"这个根本前提。对象之间不能直接操纵对方的数据,只能通过发送消息来请求对方完成操作。顺序图把这个"谁在什么时候给谁发了什么消息"的过程显式画出来,是面向对象思想从静态类模型走向动态运行模型的关键桥梁——它把代码里一个个方法调用,还原成建模图上一条条带箭头的消息线。
顺序图看似只是一堆方框和箭头,但其背后的建模语法非常严谨。要真正读懂和画出顺序图,必须掌握四大构成要素:生命线、消息、激活期和组合片段。这四者构成了顺序图的骨架,任何一张规范的顺序图,都是这四类元素按照确定规则的组合。
生命线(Lifeline)是顺序图中最基础的要素,表示一个交互参与者在整段交互过程中的存在轨迹。图上它表现为一条从顶部垂直向下延伸的虚线,顶部方框内写出对象命名,既可以是具体对象,也可以是参与者(Actor)甚至某个类。当生命线代表命名对象时,通常写作"对象名:类名",例如"userLogin:UserController";只关心类时也可只写类名。这条虚线本身有语义,表示时间的流逝方向——越往下,时间越靠后。因此生命线不仅是对象的符号,更是顺序图时间轴的载体。
生命线有一个关键特征:它表示的是"对象存在并可被寻址"的那段时间。当对象在交互过程中被创建,它的生命线从创建点才开始出现;当对象被销毁,生命线在销毁点终止。UML 规范里,销毁后的生命线末端画一个"X"形符号,表示该对象不再参与后续交互。这一细节偶尔作为图形判断题出现,命题人可能画一条贯穿始终的生命线,然后问"这个对象中途已被销毁,为什么还能接收消息",正确答案就是该图违反了生命线的存在性约束。
消息(Message)是连接两条生命线之间带箭头的线段,表示一个交互点,即发送方请求接收方执行某项操作。消息是顺序图的主角,顺序图的全部意义就在于精确表达消息的发送顺序和收发关系。消息箭头的方向表示流向,从发送方生命线指向接收方生命线;垂直位置则编码时间——位置越靠下的消息,发生得越晚。
消息的命名通常写在箭头旁边,采用和操作签名类似的格式,例如"validate(account, password)"或者"getUserInfo()"。命名规范上,消息名应当是一个动词或动词短语,清晰地表达请求接收方做的事情。消息可以分为若干类型,其中最根本的区分是同步消息与异步消息。同步消息用实心箭头表示,意味着发送方在发出消息后会阻塞等待接收方处理完毕并返回,这对应程序里的一次普通方法调用;异步消息用开放箭头(线形箭头)表示,意味着发送方发出消息后立即继续自己的执行,不等待接收方,这对应程序里的线程启动、消息队列投递或者信号量发送。这个区分是软考命题的高频点,后文会专门展开。
除了同步与异步之分,消息还涉及返回消息、创建消息、销毁消息、自消息等特殊类型:返回消息用虚线箭头从被调用方指回调用方,表示返回结果;创建消息指向对象方框本身,表示该对象在此交互点被实例化;销毁消息箭头末端指向生命线终止标记,表示对象被销毁;自消息从一条生命线出发又回到同一条生命线,表示对象给自己发消息,即递归或内部方法调用。这几种特殊消息在图形辨析题中常作为干扰项出现,需能准确识别。
激活期(Activation),又称执行规格(Execution Specification),是生命线上叠加的细长矩形条,表示对象在某段时间内正在执行某个操作。当对象接收消息并开始处理方法时,它的生命线上出现激活条;处理结束返回时,激活条也随之结束。激活期解决了顺序图的核心表达难题:仅画消息箭头只能说明"消息发出去了",却无法说明"接收方在处理期间是否又向别的对象发送了消息"。激活条把对象的执行时间范围显式标出,从而能表达嵌套调用和递归调用这类复杂时序关系。
激活期在考试中是一个容易被忽视却十分重要的细节。命题人常常通过激活条的有无和长短来考察考生是否真正理解顺序图的语义。一个典型场景是:对象 A 给对象 B 发送同步消息,B 在处理过程中又给对象 C 发送同步消息,那么 B 的生命线上应当有一个从接收 A 的消息开始、到返回 A 为止的激活条,而 B 发给 C 的那条消息应当从这个激活条的范围内发出。如果图上 B 的生命线没有激活条,或者 C 的消息箭头不在 B 的激活条范围内,就说明这张图在表达嵌套调用时是含糊甚至错误的。理解激活期,本质上是在理解程序调用栈的图形化表达——激活条就是栈帧在时间轴上的展开。
组合片段(Combined Fragment)是 UML 2.0 为顺序图引入的机制,用于表达循环、分支、并行等复杂控制结构。早期顺序图只能表达一条线性消息序列,遇到"循环十次"或"登录失败则重试"这类逻辑就无能为力。组合片段用一个矩形框把若干消息框起来,在左上角标注交互运算符,说明这段消息序列的控制语义。
常见的交互运算符包括:alt 条件分支、opt 可选执行、loop 循环、par 并行、break 中断跳出、seq 弱顺序、strict 严格顺序、ref 引用另一交互片段,其中 alt、opt、loop、par 最常考。alt 片段内部用虚线分割成多个分区,每个分区对应一个分支;loop 片段标注循环上下界;opt 表示满足条件才执行。考试中组合片段常作为填空或选择题考点出现,例如问"顺序图中表示循环的交互运算符是什么",答案就是 loop。
顺序图的应用价值,很大程度上体现在它能够通过不同消息类型的组合,精确表达各种真实的交互模式。掌握消息的分类,是读懂和绘制顺序图的关键,也是软考命题人最偏爱的出题角度之一。
同步消息和异步消息的区分,是整个顺序图知识体系里最重要、考频最高的一个点。二者的本质区别在于发送方是否等待接收方完成。同步消息发出后,发送方进入阻塞状态,直到接收方处理完毕并返回结果,发送方才继续执行;异步消息发出后,发送方立即继续自己的后续动作,不等待接收方的处理结果。用编程语言来对应,同步消息就是一次普通的、带返回值的方法调用,例如 Java 里的"result = service.query()";异步消息则对应线程的启动、消息队列的入队或者回调的注册,例如"thread.start()"或者"queue.offer(task)"。
这种区别在顺序图上有明确的图形约定:同步消息用实心三角箭头表示,异步消息用开放箭头(也就是普通线条箭头,箭头是开口的 V 形)表示。很多考生记不住哪个是实心哪个是空心,这里有一个记忆技巧——实心箭头表示"等待填满",发送方必须等接收方把结果"填"回来,所以是实心;开放箭头表示"一放就走",发送方把消息一放就继续跑,所以是开口的。这个图形约定在选择题里反复出现,属于必须拿下的送分点。此外,返回消息用虚线箭头表示,它和异步消息的开放箭头容易混淆,需要记住:返回消息一定是虚线,异步消息是实线开放箭头。
返回消息(Return Message)表
本篇完!