十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

深入浅出用例图:需求分析、包含扩展与软考真题全解析

深入浅出用例图:需求分析、包含扩展与软考真题全解析 画用例图的时候最常听到的一句评价就是这不就是画几个椭圆加几个小人吗——说这话的人要么还没真正为需求挠过头要么就是把用例图当成了交差的图形作业。我在这个系列前面几篇里聊过类图、包图这些偏设计阶段的图它们解决的是系统内部怎么组织的问题而用例图是另一条线上的东西它解决的是系统到底为谁、做什么事的问题——这个谁和做什么事恰恰是很多项目烂尾的根源。这个系列走到第4篇该好好把这个最简单也最难的图拆开讲一讲了。不管你是正在画课程设计、准备软考中级软件设计师还是真在项目里做需求分析用例图画得好不好直接决定了后边类图、时序图画得顺不顺。今天这篇不打算只堆语法规则我想从根上讲清楚用例图的底层逻辑再拿一个完整的案例带你走一遍最后聊聊软考里那些看似刁钻、其实有套路的真题。1. 用例图到底在解决什么问题需求边界不清才是项目最大的坑很多人一上来就问用例图怎么画但更值得先问的是为什么要画用例图。我在实际项目里见过太多这样的情况需求文档写了一堆功能点开发说这个功能到底给谁用产品说都有用结果上线的功能一半没人点另一半真正高频的却做得稀烂。背后的根因就是需求从来没有被结构性地梳理过。1.1 用例图是分析阶段的合同不是设计阶段的图纸先把这个系列前面的内容串一下类图、包图、对象图这些属于静态结构视图回答的是系统由什么组成时序图、活动图、状态图属于动态行为视图回答的是系统内部怎么协作。而用例图既不关心内部结构也不关心内部逻辑它只关心一件事——系统外部的参与者期望系统能够提供什么价值。你可以把用例图理解成一份需求合同客户说我要这套系统用例图就是把这套系统能让谁干成什么事一条条写清楚。它不承诺怎么实现只承诺能做到。正因为这样用例图是业务人员、需求分析师、开发人员三方之间唯一没有技术门槛的沟通语言。业务方看不懂类图但绝对看得懂读者可以借书管理员可以上架新书这种用例。这也是为什么我说它难画好用例图不需要懂技术但需要对业务有足够深的理解。你能不能在杂乱无章的原始需求里精准地识别出到底有几个参与者、每个参与者真正关心的目标是什么——这考验的是分析能力不是画图能力。1.2 用例图、类图、包图的分工别再混为一谈搜索相关关键词的时候我发现uml类图uml包图常常和uml用例图同时出现说明很多初学者把这三种图当成同一层面的东西去学。实际上它们的定位差异非常大我用一张表就能说明白图类型所属阶段回答的问题使用场景用例图需求分析阶段系统为谁提供什么价值与业务方确认需求范围类图概要设计阶段系统有哪些对象及其关系指导编码实现定数据结构包图概要设计阶段类如何分组、模块如何划分架构分层、模块解耦拿图书管理系统来举例用例图里画的是读者-借书图书管理员-处理借阅请求这种业务层面的东西类图里才会出现Book类有id、title、isbn字段和BorrowRecord是一对多关联这种实现层面的设计包图则把BookController、BookService、BookRepository这些类按层分包。三者是递进关系用例图先框定干什么类图再定义内部长什么样包图最后划分怎么组织。不少软考真题就爱在这个地方设陷阱给你一张图让你判断它属于哪个阶段、回答什么问题理解了这三者的本质区别这些题就是送分题。2. 用例图的核心元素参与者、用例和关系的正确打开方式讲清楚用例图的定位之后就该落到具体元素上了。用例图一共就那么几种图形符号小人参与者、椭圆用例、方框系统边界、连线各种关系。符号本身十分钟就能记住难的是怎么用这些符号正确地表达业务。2.1 参与者不只是人识别参与者的三条硬标准初学者最容易犯的一个错误就是把参与者等同于用户。其实参与者是与系统交互、并从系统中获得价值的外部角色它可以是人也可以是外部系统、硬件设备甚至时钟。判断一个角色算不算参与者我一般用三条标准第一它是否独立于系统之外。参与者必须位于系统边界之外系统管不到它的内部逻辑。比如图书管理系统里读者在边界外因为你的系统不负责管理读者内部的状态但图书管理员虽然也是人他的权限和操作由系统管理所以他依然是参与者与读者区分的是角色不是是不是人。第二它是否有明确的目标需要系统配合完成。参与者不是功能列表的读者而是带着目标来的人。读者走进系统是想查书、借书、续借、预约每一项都是明确目标如果你发现某个角色在系统里无事可做那它大概率不是参与者。第三角色与角色之间是否真的需要区分。管理员也是人读者也是人为什么是两个参与者因为他们在系统中追求的目标集合完全不同权限边界也不一样。反过来如果两个角色在系统里能做的事完全一样那就合并成一个参与者不要为了身份好听而拆成多个。按照这套标准去看很多系统你会发现所谓游客用户普通用户会员用户如果它们在用例图上能做的事没差异就该合并如果会员能比普通用户多一个积分兑换用例那就必须分开。这个判断贯穿着整个过程也是后边做题和做项目时反复要用到的。2.2 用例是完整目标不是功能点用例Use Case的定义是系统外部参与者可观察到的、系统为其完成的一个完整目标。关键词是完整目标和可观察。什么叫完整目标从参与者的角度看这件事做完之后应该得到一个有价值的结果。对读者来说查询图书是一个完整目标——输入关键词、看到结果得到信息但输入关键词不是完整目标因为它只是查询的中间步骤把查询结果按出版年份排序也不是完整目标它只是查询功能的一个细节需求。这些中间步骤和细节需求应该在用例描述里写清楚而不是拆成用例。什么叫可观察就是这个目标完成的结果必须对参与者可见。系统内部的数据清洗、缓存更新、日志记录参与者看不到也不关心这些就不该作为用例出现。我审过不少新人画的用例图动不动就出现系统自动清理过期借阅记录这种用例——这确实是系统要干的事但它不是参与者可观察的完整目标它是系统内部的定时任务。这个用例应该被描述为管理员-查看逾期列表或者干脆写进时序图而不是画在用例图里。以图书管理系统为例合理的用例应该是一批这样的东西读者-查询图书、读者-借阅图书、读者-归还图书、管理员-处理图书借出、管理员-处理图书归还、管理员-维护图书信息、管理员-处理罚款。每一个都是读者或管理者能够感知到结果的完整事件。2.3 五种关系里最考人的是include和extend用例图里的关系分为五种关联Association、包含include、扩展extend、泛化Generalization、依赖Dependency。其中关联是参与者与用例之间的实线无需多说泛化用在参与者或用例之间的继承依赖用法比较少见早期UML版本里还会出现在用例之间现在基本被包含/扩展取代了。最让人头疼的是include包含和extend扩展之间的区别。我直接用最朴素的方式来解释包含关系虚线箭头指向被包含的公共用例箭头上标《include》代表的是一定会做的公共步骤。比如借阅图书这个用例在执行过程中验证读者身份这一步无论如何都跑不掉而且预约图书可能也需要验证读者身份。把这个公共步骤抽出来作为一个独立的读者身份验证用例再让借阅图书和预约图书都包含它这就是include。关键特征是基用例在执行时被包含用例必须被执行。扩展关系虚线箭头指向基用例箭头上标《extend》代表的是可选发生的附加行为。比如借阅图书这个主流程完成后如果读者的借阅数量达到了上限系统要额外执行借阅超限处理但大多数时候借阅是正常的这个处理根本不会发生。扩展用例只有在满足特定条件的时候才会插入到基用例的扩展点。关键特征是基用例独立存在且完整扩展用例是锦上添花、条件触发的。一句话记住这两者的差别include是每次都得干的公共步骤extend是特定条件下才插入的额外流程。软考真题里最常见的陷阱就是给你一个场景问应该选include还是extend。判断方法很简单——把这段额外逻辑抽掉基用例还完不完整如果完整那就是extend如果基用例缺少它就运行不下去那就是include。3. 用例粒度怎么把握从业务用例到系统用例的层次感如果说关系是语法那么粒度就是用例图的灵魂。很多用例图画出来不是错而是没劲——要么一个椭圆塞下整个系统要么把用例图画成了功能列表。我见过最极端的用例图整个系统就一个用例叫管理系统旁边坐着一个管理员看完不知道该说什么。3.1 粒度太粗等于没分析粒度太细等于没设计用例粒度本质上取决于你画这张图的目的是什么。如果是给高层做项目立项汇报你可能只需要到业务用例级别把整个系统拆成五六大块就够了但如果你是要指导后续的类图和开发就必须细化到系统用例级别也就是能清晰对应到具体的交互流程。这里说的业务用例和系统用例不是两种不同的图形而是同一张图上的不同抽象层次。我给团队定过一个非常实用的判断标准把用例的名字念出来如果你觉得这件事做完了用户的问题解决了吗的回答是解决了那么这个粒度就是合适的如果回答是可能是吧还要再做点什么那就太粗了如果回答是这只是其中一步那就太细了。拿图书管理来说太粗的用例图书管理——这不是一个用例这是一个功能模块里面塞了上架、下架、改价格、查库存一堆事参与者无法通过这一个步骤完成任何明确目标。合适的用例管理员上架新书读者预约图书——每个用例都表达了一个参与者可以感知的完整目标。太细的用例读者选择借阅数量管理员点击确认按钮——这是操作步骤是用户界面层面的交互不是用例。3.2 我用的四步粒度校验法具体操作的时候我一般用四个问题逐一校验每个用例这个用例有没有明确的主语参与者和谓语目标动作没有主语的用例一定有问题。这个用例的完成结果对参与者是否可见、是否有业务价值系统发送通知这种对参与者来说算可见系统更新数据库字段这种就不算。这个用例能否独立执行、独立验收如果一个用例依赖另一个用例执行完才能开始那通常意味着两者的边界没划对或者存在真正的include/extend关系。整个用例图去掉某个用例之后参与者是不是还有其他途径达成类似目标如果有说明两个用例之间可能存在泛化或包含关系需要重新组织。我自己画用例图的时候从第一阶段到定稿通常会经历三轮删减。第一轮把操作步骤删掉第二轮把系统内部动作删掉第三轮把相互重复的用例合并。每一次删除都要能说出理由说不出理由的先留着等想明白了再决定去留。这个过程看似浪费其实是需求分析最值钱的部分。3.3 为什么粒度问题在软考里也很重要软考中级软件设计师的案例分析题有时会直接给出一段需求描述让你根据需求画出用例图或者指出图中存在的错误。这种题表面考画图实际上就是考粒度判断。我曾经见过一道真题参考答案里明确把用户注册作为用例但很多人在它下面又拆出了填写注册信息验证手机号设置密码三个用例——后者就是典型的太细了它们是注册流程里的步骤应该写进用例描述不是独立用例。还有一类真题会故意把查询图书和高级查询画成包含关系问你错在哪里。实际上高级查询是查询图书的可选条件分支应该用extend而不是include。这类题做错的人非常多原因就是前面说的那一点没有抓住抽掉后基用例是否完整这个判断核心。4. 实战推演从一段杂乱需求到一张合格的图书管理系统用例图理论讲再多不如完整走一遍。下面我用一个非常经典的图书管理系统需求来做全流程推演。这个场景在软考题目和学生项目里出现频率极高搜索引擎里图书管理系统用例图能排到热词榜说明它的代表性确实强。4.1 原始需求长什么样怎么找到参与者假设我们现在拿到的原始需求描述是这样的我特意保留了它零散、口语化的样子这个系统需要支持图书的查询和借阅。读者进入系统可以登录可以查询图书信息如果有库存就能借书到期前可以续借超过期限要交罚款。管理员负责图书的入库和出库还要管理读者的信息和处理罚款。系统在图书到期前要给读者发提醒。面对这样一段文字第一步不是急着画椭圆而是先圈出名词性角色。这段需求里出现了读者管理员两个明确角色还有一个隐藏角色值得考虑系统自动发提醒这件事是人触发的还是系统定时触发的如果是系统自动在到期前发那就意味着有一个时钟/定时器参与者——这在很多系统里都会被漏掉。我按前面说的三条标准一一过读者在系统外部、目标是查询/借阅/续借/还书是参与者。管理员在系统外部、目标不单是借书而是管理整个图书流程是参与者。定时器虽然它不是人但它独立于系统外部定期触发发送到期提醒这个目标是参与者的一个合法变体。不过要注意如果你们的项目里把提醒功能看作管理员操作的子步骤那也可以不单列参与者和用例毕竟分析阶段可以根据项目规模灵活取舍。4.2 从角色目标推出用例清单确定参与者之后逐个问他为什么要用这个系统。这个过程我会用一张简单的表格来整理表里记录参与者、目标描述、是否核心。这个习惯推荐大家保留它是一个过渡到用例清单很顺畅的中间产物参与者目标描述是否核心读者查询图书信息是读者借阅可借图书是读者续借即将到期图书是读者归还已借图书是读者查询个人借阅记录和罚款情况否但推荐管理员管理图书基本信息上架、下架、改信息是管理员处理图书借出和归还是管理员管理读者账户注册审核、停用等是管理员处理罚款是这些就是初始用例。注意几个细节登录我没有放进核心清单因为登录通常是所有业务流程的公共前置步骤更适合抽成被包含的公共用例而不是每个参与者都反复关联的独立用例。当然如果系统中游客也能访问一部分功能登录就得慎重处理——这种情况下一般会引入游客这个参与者而登录作为独立用例让游客变成读者。发送到期提醒我暂时留着后面考虑是作为定时器参与者的独立用例还是基于读者的某个用例的扩展点。查询个人借阅记录和罚款情况虽然不是原始需求明文但从业务完整性上讲读者总得知道自己在系统里有几本没还、欠了多少罚款否则整个借阅闭环是不成立的。这是需求分析里最常见的隐含需求你把它补出来业务方通常都会认可。4.3 梳理关系包含、扩展还是泛化用例清单列出来以后就可以开始连线了。这一步最容易出错的不是连不连而是用哪种方式连。先处理公共步骤。读者要借书必须首先登录并验证身份管理员处理借出也必须验证自己的权限。这时候把身份验证/登錄抽成一个独立用例然后让借阅图书处理图书借出续借图书等所有需要合法身份才能执行的用例都include它。这个抽法在正规项目里非常常见也是考题里频繁出现的考点。注意这里是用例之间的虚线箭头箭头指向身份验证箭头上标《include》。再处理可选分支。续借有一个典型场景读者借的书可以续借但如果这本书已经被其他读者预约了就不能续借或者读者有逾期未还的图书也不能续借。这个不能续借的流程不是每次续借都会发生而是在特定条件下触发所以它应该作为续借图书的extend扩展用例触发条件就是存在未还逾期图书或图书被预约。同理处理罚款也可以用extend的方式挂在归还图书上正常归还流程就结束了如果归还时发现逾期才进入罚款处理环节。这个扩展关系特别能体现业务分支放在用例图上一眼就能看懂什么情况下会发生什么。至于参与者之间的泛化最典型的就是游客与读者游客能够查询图书读者继承游客的功能并且还能借书、续借、预约。在用例图上游客和读者两个小人之间画一条带空心三角箭头的泛化线箭头指向游客意思就是读者是一种游客的扩展。如果需求里没有游客能使用的功能那就不用画泛化保持读者管理员两个独立参与者即可。4.4 最终用例图的完整信息结构把所有信息组合起来一张图书管理系统的用例图大概包含这些内容系统边界一个大的方框框内是系统的所有用例框外站着参与者。边界这个名字一般是图书管理系统。参与者读者、管理员如果做扩展还有游客、定时器视需求规模而定。核心用例查询图书、借阅图书、归还图书、续借图书、预约图书、管理图书信息、管理读者账户、处理罚款。公共用例身份验证登录。扩展用例借阅超限处理、续借失败处理、逾期罚款处理。我不敢说这张图满足所有教材的苛刻规范但在实际项目里做到这个程度已经足够让开发人员和测试人员各自去拆任务、写用例了。如果你打算在软考答题里画图还需要额外注意三角形的方向、箭头的虚实——这些细节我就放到下一节一起说因为它们往往就是扣分点。5. 软考中级软件设计师里用例图真题是怎么考的之所以要把软考单独拿出来讲是因为题库数据里软考中级软件设计师用例图真题是一个大热搜索词。在考试语境下用例图的考法跟项目实战里画一张图的考法很不一样前者更多是给图找错和补全缺失后者才是从零画图。做题技巧和画图技能有重叠但需要额外练一套判断方法。5.1 真题常见的三种命题角度第一种是识图辨析。题目给出一张某系统的用例图让你判断哪些地方画错了常见错误包括include箭头方向反了、extend箭头方向反了、参与者放在了系统边界内部、用例与参与者连成了用例对用例的关系、泛化箭头方向错了等等。此类题属于概念判断题难度不高但它检验的是最基础UML规范是否牢固。第二种是补全用例。给你一段需求描述给出一张不完整的用例图让你补几个缺失的用例或参与者。这种题考的是需求理解能力做题时的核心思路就是我前面讲的三条参与者识别标准和四步粒度校验法。从需求文本里圈定语干再判断谁是参与者、谁是目标答案自然就出来了。第三种是概念辨义。不直接考图而是用文字描述一个场景问你应该用include还是extend或者问某段描述属于用例图的哪个元素。这种题有时候比看图还容易错因为文字描述往往故意说得模棱两可比如管理员可以查看统计报表如果报表导出失败则记录日志——后一句记录日志应该被描述成扩展用例还是系统内部动作答案是如果导出统计报表是核心目标记录日志是导出失败时才执行的附加行为画成extend没问题但如果这个日志只为系统自身排错服务、对参与者不可见它压根不该出现在用例图里。考试时这种要不要出现比用哪种关系更常考。5.2 做题的三步定位法主语、目标、完整性我自己参加考试和辅导同事时总结了一套三步定位法遇到任何用例图判断或补全题都先用这三步过一遍正确率很稳定。第一步找主语。图上出现或者题干中出现的每一个动作先问谁在做这件事。找不到主语的动作、主语不是参与者、或者主语是系统但动作对参与者不可见——那么它是一个可疑的用例大概率不成立。第二步找目标。确认这个动作完成后参与者是不是得到了一个可感知的完成结果。得到的就是用例得不到的可能是操作步骤、系统内部逻辑或者前置条件需要从用例清单里剔除或降级为用例描述。第三步验完整性。把剩下的候选用例代入include/extend判断框架这个用例抽掉公共步骤后是否完整如果某个候选用例总依赖另一个用例考虑它们是不是本来就是包含关系如果某段说明是在特定条件下发生考虑它是不是扩展关系。三步走完答案基本就浮出水面了。5.3 一个高频失分点边界用对了图却忽略了箭头方向很多人实际画图或者做题时栽在include和extend的箭头方向上。UML规范是include的虚线箭头从基用例指向被包含用例也就是借阅图书指向身份验证方向extend的虚线箭头从扩展用例指向基用例也就是借阅超限处理指向借阅图书方向。两个箭头的指向完全相反。记法上有个口诀include是依赖——基用例依赖被包含用例所以箭头跟着依赖走extend是扩展——扩展用例去扩展基用例所以箭头从扩展者指向被扩展者。刚开始的时候容易搞混我自己早期的办法是在脑子里把include理解为我要带上它把extend理解为它来插入我。多练几道真题方向基本就形成条件反射了。另外箭头是虚线别画成实线边上要标注《include》或《extend》的版型。软考阅卷对这类形式化细节是有扣分标准的细节决定过不过。6. 最后再顺手补充几个实操经验工具、命名和画图时最容易犯的错写完前面这些关于用例图这个主题的核心内容就差不多了。最后用我平时在实际项目中积累的几条实操经验来收个尾当作给看完这篇、准备自己动手的读者一点加速度。工具方面画用例图不需要专门的复杂建模工具StarUML、draw.io、ProcessOn、Visio都能胜任。如果你要输出规范的、带UML版型标注的关系线StarUML和draw.io比ProcessOn更顺手因为后者在控制版型标注的细节上偶尔不够严谨。如果在软考纸笔答题阶段那就更简单草稿纸上画清楚小人、椭圆、方框、虚线箭头、版型字样这几个要素就够了画功好不好不影响拿分规范性才影响。命名方面我强烈建议用例名称统一用动词名词短语比如查询图书处理罚款生成统计报表不要用图书查询功能图书信息维护模块这种半功能半用例的名字也不要用纯名词图书查询这种动词缺失的写法。一个用例名念出来应该是一个能让人听懂的动作目标。参与者的命名统一用名词短语读者就是读者不要出现读者用户角色这种叠床架屋的说法。还有一个我见过无数次、属于隐蔽低级错误的问题把系统边界画得太小以至于一些后续迭代中新增的功能只能往边界外外挂。系统边界其实不是一个固定不变的硬壳它是随着需求范围实时调整的。推荐的做法是先把参与者和用例的关系连线画清楚最后再框系统边界。如果你一开始就画了一个框然后拼命往里塞很容易为了装进去而强行合并或裁剪用例。最后说一个很多人忽略的点用例图是读者和开发沟通的起点不是终点。一张好的用例图后面往往还要配一个用例描述文档把每个用例的主流程、备选流程、前置条件、后置条件写清楚类图和时序图才能有据可依。这也是为什么我每次带项目都要求用例图先评审再进入设计阶段——因为用例图一旦错了后面全是在错误的地基上盖楼。把用例图画清楚这件事花的时间永远值得。
返回列表