UML用例图、顺序图、协作图辨析:从需求到交互建模 简介这是一份面向高校软件工程课程学习者与UML考前复习人群的试题合集围绕用例图、顺序图与协作图等核心图形组织知识点帮助读者在较短时间内梳理统一建模语言的静态与动态建模要点。压缩包内为1个doc文档约62KB内容以简答题、选择题和知识点问答为主便于打印或按题型检索。已有11276人学习说明其作为课程复习与自测材料的参考价值较稳定。文档涉及顺序图与协作图的时间/空间组织差异、高内聚度、对象间可见性、领域模型概念类识别、统一过程四阶段与核心工作流、增量开发及用况描述方式等读者可据此形成答题框架对照检查概念盲区并用于课堂作业、期末考试或面试前的快速回顾。1. 从一道 UML 题说起用例图和顺序图到底在画什么UML 这个词很多人的第一印象不是来自项目而是来自考卷——一道选择题问下面哪个不是 UML 中的静态视图选项里躺着状态图、用例图、对象图、类图。四个词都眼熟选起来心里发虚。问题不在记性在于没弄清这些图各自管哪一段。打个比方盖一栋楼有用来看房间格局的户型图有标注管线走向的水电图还有写清早上八点工人进场、九点材料到场的施工排期表。画的都是同一栋楼回答的问题完全不同。UML 的用例图、顺序图、协作图就是这层关系——用例图回答谁要用这个系统做什么顺序图回答事情按什么先后发生协作图回答哪几个对象凑在一起把它办成。把这层分工捋顺那些看起来互不相干的题目其实是同一套逻辑的不同切面。2. 用例图为什么它总是第一个被画出来需求评审会上经常出现这一幕业务方说我要一个下单功能开发在文档里记下下单两个字等到交付时才发现漏了库存不足怎么提示优惠券过期怎么算。争执的根源往往不是谁不负责而是大家嘴里的下单颗粒度根本不是同一个东西。用例图就是在这一步顶上去的它干的活很朴素把谁和要系统做什么这两件事逼着双方在同一张纸上讲清楚。2.1 用例图回答的只有一件事谁要系统做什么一张用例图里只有四样东西参与者、用例、系统边界、关系线。没有时间顺序没有判断分支没有数据流向——这些统统不属于用例图的地盘。参与者是一类角色不是某个具体的人。医院挂号窗口的例子最直观参与者是病人医生收费员而不是张三李四。外部系统、定时器也可以是参与者只要它和你的系统之间有交互就算一个。用例的定义值得逐字读一遍用例是一个描述性的文档用来描述一个参与者使用系统完成某个业务过程时的事件发生顺序。它描述的是系统的使用过程反映系统的功能需求它不描述系统内部如何工作只定义系统的责任说明系统必须做什么。这句话里藏着一个判断标准。用例是业务过程级别的不是界面操作级别的。餐馆菜单上写宫保鸡丁不会写拿起筷子夹起花生米。所以用户点击登录按钮不是一个用例用户登录系统才是填写收货地址不是一个用例提交订单才是。系统边界是那个方框。框内是用例框外是参与者跨过框的那条线代表一次交互。这条线画错后面的争论全跑偏把库存服务画进框内就等于宣布库存由我们实现可它明明是别人家的系统。初学者最常见的翻车方式是把界面上的每个按钮都翻译成一个用例最后画出来十几个椭圆谁也说不清系统到底提供什么价值。补救办法很简单拿一个用例问一句它能不能让某个参与者完成一件对他有意义的事答不上来就删掉。2.2 包含和扩展最容易在选择题里选错的一对关系用例之间不是孤立的它们有相关性。最典型的一道题是这样的在一个订单输入子系统里创建新订单和更新订单都需要检查用户账号是否正确那么创建新订单更新订单与检查用户账号之间是什么关系正确答案是包含include。理由不是听起来顺而是每次都得走。只要创建订单就必须校验账号只要更新订单也必须校验账号。这个动作不是可选的是被复用的必经步骤。扩展extend反过来。它描述的是在某种条件下才额外发生一段行为。比如借阅系统里的借书正常情况下走完借出流程就结束了但如果读者勾选了到期提醒才额外触发一段提醒设置——这才是扩展。两者的画法也不一样这一点考试爱考、画图也爱错包含的虚线箭头从主用例指向被包含的用例标注«include»扩展的虚线箭头方向相反从扩展用例指向被扩展的用例标注«extend»。箭头指向谁是很多人凭手感画错的地方。记一个口诀就够了把这段行为拿掉主用例还能不能完整走完走不完是包含走得完只是少了点可选内容是扩展。还要提醒一句包含不是函数调用的同义词。有人喜欢把一个用例拆成七八个小的包含用例画出来像蜘蛛网读图的人得拿着线头一路追。用例图的读者是业务方不是编译器拆得太细等于自废武功。2.3 同一个用例有三种写法Brief、Casual、Fully Dressed用例是文档图只是它的索引。同一个用例按场合可以写得详略完全不同常见的有三档Brief、Casual、Fully Dressed。Brief 是一句话比如买家提交购物车中的商品并生成订单。Casual 是几段话把正常流程讲顺。Fully Dressed 是完整模板字段齐全可以拿去评审、可以据此排迭代。用例名提交订单 主参与者买家 辅助参与者库存服务 前置条件购物车非空、买家已登录、收货地址已填写 主成功场景 1. 买家点击提交订单 2. 系统校验商品库存 3. 系统生成订单号并锁定库存 4. 系统跳转到支付页 扩展场景 2a. 库存不足系统列出缺货商品流程结束 2b. 地址为空系统提示补充地址返回步骤 1 后置条件订单状态为待支付对应商品库存已锁定这段模板里每一行都在防一种扯皮。前置条件防的是这个功能在什么状态下才能用避免开发做完才发现入口压根进不去主成功场景是一条顺利路径编号是为了后面能被扩展场景引用扩展场景写的是分支2a表示第 2 步的另一种可能这种编号约定让写的人和读的人不用来回确认后置条件说的是这件事做完之后系统里什么变了它是验收时的对照物。那么什么时候值得写满经验是看两条这个用例会不会跨多个迭代、会不会有多个角色参与。会就老老实实写 Fully Dressed如果只是一个增删改查Brief 足够写满了也没人看。用例模型本身就是需求工作里分量很重的一份制品它的价值不在于格式漂亮而在于写的过程中被迫回答了一堆原本会被跳过的问题。3. 顺序图把时间轴摊开看消息一条条往下走用例图告诉你有人要下单但它戛然而止——下单这一秒钟系统里到底谁先动、谁后动、谁在等谁图上完全看不出来。补上这一段的就是交互图。UML 的内容可以归到五类图、共九种图形里用例图、静态图类图、对象图、包图、行为图状态图、活动图、交互图顺序图、协作图、实现图组件图、部署图。顺序图和协作图同属交互图一个负责把时间摊开一个负责把结构摊开。3.1 顺序图的四件套类角色、生命线、激活期、消息顺序图的构成一句话题目就概括完了顺序图由类角色、生命线、激活期和消息组成。四个词听着抽象换成生活场景立刻好懂——几个人并排站着打电话。类角色就是站在那儿的人头顶上写着名字格式一般是对象名:类名比如订单:Order。生命线是从每个人脚下垂下来的那根虚线越往下时间越晚所以纵轴就是时间轴。激活期是虚线上那段加粗的矩形条表示这个人这会儿正在处理事情条子越长说明处理得越久。消息就是他说的话画成箭头。箭头有几种画法含义差别不小。实线加实心箭头是同步消息意思是我说完你得回我一句我等着实线加开放箭头是异步消息意思是话撂这儿了我先走虚线箭头是返回消息表示刚才那件事的结果回来了。很多图画得乱就是因为把同步和异步混着用读图的人分不清到底谁在阻塞。3.2 为什么顺序图横着排对象、竖着走时间横轴放对象纵轴放时间这个布局是顺序图最大的优势和最大的成本。优势是顺序一眼可见。谁先发消息、谁后响应、哪两条消息并行、哪条消息要等返回才能继续不需要任何编号从上往下读就行。评审的时候业务方也能看懂这是它比类图亲民的地方。成本则是空间。对象一多横向就撑破了屏幕这也是资料里点明的短板顺序图可以清晰地表示消息之间的顺序和时间关系但需要较多的水平方向的空间。十个对象的顺序图打印出来得接三张 A4。落到代码上顺序图的纵轴顺序其实就是调用顺序。下面这段伪代码和上面一张顺序图是一一对应的def submit_order(buyer, cart): order create_order(buyer, cart) # 消息 1买家 - 订单模块同步 ok check_stock(order) # 消息 2订单模块 - 库存服务同步等返回 if not ok: return fail(库存不足) # 消息 2 的返回分支对应扩展场景 lock_stock(order) # 消息 3锁定库存同步 notify(buyer, order) # 消息 4通知买家异步发出去不等结果 return success(order)对照着看几个参数create_order是同步调用所以画实心箭头调用方一直等到它返回check_stock也是同步但它的返回值决定了后面走不走得下去所以顺序图上要画一条返回虚线回来之后再决定分支notify是异步画开放箭头调用方发完就往下走不等回执。如果顺序图上把notify画成了同步读图的人会以为下单接口要等通知发完才返回这就是典型的图画错了导致实现跟着错。3.3 SSD把系统当黑匣子故意不画内部有一类顺序图专门用来划边界叫系统顺序图SSD。它的画法很克制把整个系统画成一个黑匣子只画外部参与者发进来的消息以及系统给出的响应。一道题问得很直接画 SSD 图时应该如何对待所涉及的系统选项里有一个说详细描述其内部结构及功能有一个说简单描述内部结构但罗列所有功能还有一个说不对系统的内部结构与功能进行描述。答案是最后一个。道理不难。SSD 出现的时间点通常是需求还没定稿的时候。这个阶段你要是把内部的 Service、Repository、缓存层都画上去等于替设计做了决定而设计是会变的图画得越细改起来越疼。更麻烦的是一旦图上出现了内部结构评审时大家的注意力就从这个交互对不对滑到这个类名起得好不好跑题跑得悄无声息。去餐厅点菜是个好类比你看菜单、点菜、等上菜全程不需要知道后厨有几口锅、几个厨师。菜单是你的接口后厨是实现。SSD 就是那张菜单。3.4 顺序图的短板分支一多就撑不住顺序图不是万能的。当一段交互里塞满条件判断和循环图上就得挂一排组合片段——条件分支画一个框循环画一个框可选画一个框。框套框箭头来回折最后整张图变成一张电路板。更麻烦的是消息数量。二十条消息、五个对象横向排不下纵向拉得老长读者得用手指头点着屏幕找第 7 条消息对应哪个返回。这个时候换一种画法反而更清楚。4. 协作图换个视角看对象是怎么凑成一伙的同一段交互可以按时间画也可以按关系画。就像一次多人协作的搬家你可以按分钟记录八点整小王搬箱子、八点零五小李开门也可以拍一张所有人站在屋子里的合影标清楚谁把箱子递给谁。前者是顺序图后者是协作图。4.1 对象、链和带编号的消息协作图可视化地表示了对象之间随时间发生的交互它除了展示对象之间的关联还显示出对象之间的消息传递。和顺序图一样它展示的也是对象之间的交互关系只是排布逻辑换了。图上的三样东西对象是方框和顺序图里一样写对象名:类名链是对象之间的连线代表它们之间存在关联消息只能沿着链走没有连线的两个对象在图上就没法直接说话消息是压在链上的箭头旁边带一个编号。时间顺序全靠编号。一道题问得很精准在协作图中通过什么表示出消息的时间顺序答案是消息编号。编号的写法有讲究同级用1、2、3嵌套调用用小数点往下排1.1、1.22.1表示第 2 条消息内部触发的第一个子动作。一层层读下去就是一棵调用树。这个编号体系是协作图最容易被低估的地方。它看起来只是标号实际上是整套时间信息的唯一载体——位置不表达时间只有编号表达时间。所以编号一旦写乱整张图的顺序就没了而顺序图不会出现这种问题因为它的版面本身就是顺序。4.2 空间组织的好处与代价两种图的核心差别资料里说得很清楚顺序图强调的是交互的时间顺序而协作图强调的是交互的语境和参与交互的对象的整体组织。顺序图按照时间顺序布图协作图按照空间组织布图。把维度摊成一张表更直观对比维度顺序图协作图布图依据时间顺序空间组织时间怎么表达纵轴从上到下消息编号强调什么消息先后的时序对象之间的关联结构和交互语境空间消耗横向消耗大对象多就排不下纵向横向都省对象多也能塞增加对象要重新调整横向布局相对容易找块空地放下即可消息很多时仍然清晰从上往下读编号变长难以表示消息之间的顺序分支情况需要组合片段框分支相对较少这张表里有两行值得单独说。第一行是增加对象比较容易。这不是审美问题是实际操作成本。顺序图插入一个新对象往往要把整张图横向重排箭头全得重画协作图插入一个对象只要它和已有对象有链画个框连条线就行周围不用动。第二行是消息多时难以表示顺序。这是协作图的硬伤。顺序图上二十条消息还是从上往下排读者眼睛跟着走协作图上二十条消息就是二十个编号散在一堆连线中间读者得先找到编号 12 在哪条线上再找 13 在哪条线上来回跳。协作图还有一点是顺序图给不了的它把对象的关联关系摆在明面上。你要评估这次改动会影响哪几个对象看顺序图得自己脑补它们之间的关系看协作图一眼就能顺着链找出去。有一个流传很广的误解协作图是顺序图的一种特例。这个说法是错的。两者是同一层级的两种交互图只是视角不同不存在谁包含谁。之所以有人这么想多半是因为一些建模工具支持在顺序图的基础上按键自动生成协作图——能互相转换不等于一个是另一个的子集就像同一份行程既能排成时间表也能画成路线图路线图不是时间表的特例。4.3 交互图落在统一过程的哪个阶段图画在什么时候比画成什么样更重要。这就绕不开统一过程UP。统一过程把软件的生命周期切成四个阶段初始阶段、细化阶段、构造阶段、提交阶段。每个阶段要交的东西不一样。初始阶段做的是方向性判断编制简要的愿景文档、整理业务案例、确定范围、粗略评估成本。注意粗略两个字——这个阶段不需要精确需要的是这事值不值得做。细化阶段干的是硬活细化愿景文档、迭代地实现核心构架、解决高风险的问题、定义大多数的需求和范围、进一步评估成本。有一道题专门考这个边界定义大多数的需求和范围是在哪个阶段完成的答案是细化阶段。很多人错选初始阶段因为直觉上一开始不就该把需求定下来吗但初始阶段的任务是划定范围、判断可行性真正的需求细化发生在细化阶段。构造阶段是迭代地实现系统的其余部分、准备部署提交阶段是 beta 测试、部署。这四个阶段不是瀑布式的四段流水线内部的执行是有迭代的。和这几个阶段配套的还有几条贯穿始终的核心工作流业务建模、需求分析、设计、实现、测试。用例图主要落在需求分析顺序图和协作图主要落在设计——前提是需求已经通过用例描述清楚了交互图负责把系统要做什么翻译成哪几个对象按什么次序配合。这里还要接上一个概念增量开发。它包含两层意思一是对复杂的用例分多次迭代一部分一部分地实现二是把所有用例按优先级分别安排在不同的迭代中实现。这两层意思解释了为什么早期的交互图不用画全——你在第一个迭代里只需要把优先级最高的那几条用例画透剩下的等需求稳定了再说。把所有交互图一次性画完是一种看起来很勤奋、实际上把返工量翻倍的做派。5. 易混概念辨析五个最容易记串的地方这些概念单独看都懂放在一起就开始打架。下面五条是选择题里翻车率最高的几组。5.1 易混点协作图是顺序图的一种特例为什么混这两张图可以互相转换工具里甚至一键就能生成另一张加上两者画的都是对象之间的消息交互很容易被理解成一个更详细、一个是它的简化版。怎么区分看它们强调什么。顺序图强调的是交互的时间顺序按时间顺序布图协作图强调的是交互的语境和参与交互的对象的整体组织按空间组织布图。两者是并列关系不是从属关系。判断时盯住一句话图上的时间信息是靠版面表达的还是靠编号表达的靠版面的是顺序图靠编号的是协作图。5.2 易混点状态图和活动图是一回事或者状态图是活动图的特例为什么混两张图都在画变化都有一堆圆角矩形和箭头看上去像同一个东西换了套图标。怎么区分抓住建模对象这个关键词。活动图和状态图都是对一个对象的生命周期进行建模描述对象随时间变化的行为这是它们的共同点差别在于状态图更适合对单个反应型对象建模盯的是这个对象在什么条件下从哪个状态迁到哪个状态活动图盯的是一整条流程里各个活动的先后还可以用泳道把活动按负责的类、人或部门分组回答这一步该谁干。顺带纠正两个常见错判状态图不属于静态视图它描述的是动态行为状态图是活动图的一个特例这个说法也不成立两者是并行的行为图不分父子。5.3 易混点领域模型里的概念类就是代码里的类为什么混名字里都有类字画出来都是方框初学者很容易直接把数据库表搬上去。怎么区分领域模型是一组表示真实世界的概念类它不是软件部件的模型。这里的订单指的是业务里那张订单——它有编号、有金额、有下单人但不带方法、不带字段类型、不带主键索引。它存在的目的是启发设计先把业务世界里的名词捋清楚再决定代码里要不要为它建一个类。找概念类有两条现成的路子概念类类别表以及标识名词短语——把需求描述里出现的名词圈出来逐个判断是不是业务概念。这两条方法朴素但比拍脑袋靠谱。5.4 易混点高内聚就是让一个类的职责越少越好为什么混职责少听起来就等于专注而专注听起来就等于内聚。怎么区分高内聚度是对一个类中各个职责之间相关程度和集中程度的度量。注意关键词是相关程度不是数量。它包含两层意思一是不要给一个类分派太多职责履行职责时尽量把部分职责分派给更有能力完成的其它类二是不相关的职责不要塞进同一个类。所以一个类只干一件事但这件事和它的主业八竿子打不着那不叫高内聚那叫职责错位。反过来一个类承担了三件高度相关的事只要工作量不离谱依然算高内聚。判断标准是这些职责是不是围绕同一个中心不是数一数有几条。5.5 易混点对象间的可见性就是 public 和 private为什么混两个词都跟能不能访问有关写代码时又天天和访问修饰符打交道。怎么区分可见性指的是一个对象能够看到或者引用另一个对象的能力它回答的是A 手里有没有 B 的引用。这个引用可能来自属性持有、方法参数传入、局部创建也可能来自一个全局可及的位置。而 public、private 是语言层面的封装规则管的是你拿到了引用之后能不能调用。一个是设计层面的结构问题一个是语法层面的权限问题。设计时可不可见没想清楚语法上写成 public 也救不了——两个对象之间根本没有引用通道公开也没用。6. 什么时候用哪张图一张判断表和几条硬边界真正卡住人的从来不是这张图怎么画而是这个场合到底该画哪张。下面这张表按你想回答的问题来索引比按图形特征记要顺手得多。你想回答的问题用这张图别用这张图的原因谁要系统做什么、系统边界在哪用例图它不含时序和分支硬塞进去只会画成四不像这次交互谁先谁后、谁等谁顺序图协作图的时间信息全靠编号读起来费劲哪几个对象凑在一起完成这件事、它们之间有什么关联协作图顺序图不显式表达对象间的静态关联过程中涉及哪些条件分支和循环顺序图配组合片段协作图分支表达弱编号会乱单个对象的状态怎么迁移状态图活动图表达的是流程不是单对象状态跨角色的流程该谁负责活动图配泳道顺序图按对象排不按责任人排系统对外承诺什么、不暴露内部系统顺序图普通顺序图容易把内部结构画进去有五条判断边界值得记牢。第一需求还没定的时候不要往图里塞设计。画 SSD 时对系统内部结构与功能不做描述不是偷懒是保护——一旦把内部的类和服务画上去评审的注意力就会从这个交互对不对偏到这个类该叫什么。第二消息多、分支多就别硬用协作图。协作图的优势在对象多、结构复杂、消息相对少的时候一旦消息数量上去了编号会变成一串没人愿意追的数字。第三对象经常增删就别硬用顺序图。顺序图加一个对象要横向重排改一次疼一次尤其在迭代早期对象还没定型的时候。第四别指望一张图讲完整个系统。UML 提供一系列图支持面向对象的分析与设计这些图是分工不是重复。用例图给方向交互图给过程类图给结构各管一段。第五粒度对齐读者。给业务方看的图椭圆别超过十个给开发看的图消息可以细到参数。同一件事画两版比画一版让所有人勉强看懂要省事得多。我第一次独立画交互图的时候吃过一次典型的亏。当时为了显得完整把一段下单流程画成了顺序图七八个对象横着排开条件分支套了三层框。评审会上一位前辈看了半分钟问了一句你这张图是想让我看先后还是想让我看这几个对象怎么凑起来的我答不上来因为我两件事都想塞进去。后来重画把时序部分留在顺序图把对象关联拆出来单独画了一张协作图两张图加起来比原来那张还短问题反而当场就定下来了。从那以后我每次落笔画交互图之前都会先强制问自己一遍这张图给谁看他要的是时间还是结构。问完再动笔返工少了很多。这份 UML 试题资料把这些问答和选择题按主题归到了一起用例图、顺序图、协作图的部分尤其密需要的话可以拿去对着过一遍。希望帮到你。本文还有配套的精品资源点击获取