简介:UML软件建模复习题.pdf 是一份面向软件工程学生及 UML 初学者的复习自测资料,围绕课程考试常见的用例图、类图、状态机、活动图、构件图、部署图等核心建模知识点展开,帮助读者系统巩固面向对象基础与 UML 图形语法。资源共 1 个 PDF 文档,大小 2.79MB,目录按《UML2 软件建模》同步练习题章节组织,涵盖概述、用例与用例图、类与接口、关系建模、交互与交互图、状态机与状态图、活动与活动图、构件与构件图、制品结点与部署图等模块。题目类型包括单选题、填空题、名词解释和简答题,并附有参考答案或答题要点,既可先练后查,也可直接背诵关键术语。目前已有 118 人学习/下载,适合考前集中刷题、课后巩固以及教师作为课堂随练素材。
1. 一份复习题里的UML建模主线
UML软件建模复习题这份资料看起来只是一份考试题库,但把它按章节拆开看,正好是UML2建模体系的一条完整主线:用例图管需求,类图和对象图管静态结构,状态图、活动图、交互图管动态行为,构件图和部署图管物理实现。很多从业五六年的开发回头再看这些概念,经常被“包含和扩展”“抽象类和接口”“聚合和组合”这类辨析题卡住,不是不会画图,而是术语边界模糊。这篇就从题目里挑出高频考点,讲清楚判断依据,再给出可复现的模型文本,方便你用建模软件或PlantUML直接验证,而不是只背答案。
2. 用例图:参与者、用例与三种关系辨析
2.1 从订单处理题看包含与扩展
复习题里有一道很典型的题:在“订单处理系统”中,下新订单和更新订单都要核查用户账号是否正确,问“下新订单”“更新订单”与“核查用户账号”之间的关系,答案是包含。这里的判断核心是:核查账号是下新订单和更新订单都会执行的一段公共行为,它被提取成被包含用例,主用例的执行流程里无条件地包含它。
扩展关系则完全不同。扩展发生在特定条件下,比如“还书”这个用例,在“借书超期”这个扩展点上才插入“罚款”用例,还书本身不依赖罚款也能完成。复习题第2章第11题“还书用例和罚款用例之间是扩展关系”,第14题“一个用例中加入一些新的动作后则构成了另一个用例”考的都是同一件事。判断时先问两个问题:这个行为是否每次必被执行?如果是,那就是包含;如果不一定、只在某个条件或异常点触发,那就是扩展。还有一个更直接的标记:包含关系箭头从主用例指向被包含用例,扩展关系箭头从扩展用例指向被扩展用例,方向不要记反。
| 维度 | 包含(include) | 扩展(extend) | 泛化(generalize) |
|---|---|---|---|
| 箭头方向 | 主用例 → 被包含用例 | 扩展用例 → 被扩展用例 | 子用例 → 父用例 |
| 触发条件 | 无条件,主用例必执行 | 有条件,在扩展点插入 | 概念上的特化 |
| 典型场景 | 登录、校验账号、写日志 | 超期罚款、找回密码 | 购买一罐饮料 / 购买一瓶饮料 |
| 依赖强度 | 强,缺了被包含用例主用例不完整 | 弱,被扩展用例可独立存在 | 是“is-a”关系 |
2.2 泛化与关联:参与者侧的建模约束
除了包含和扩展,用例之间还有泛化关系。泛化表示一个用例是另一个用例的特化,比如“购买饮料”是通用用例,“购买一罐饮料”“购买一瓶饮料”是它的具体化。参与者之间也可以有泛化,复习题人事管理系统案例里,总经理、部门经理、人事部工作人员、员工这四个参与者,需要按角色层级判断是否泛化。实际建模中,泛化很容易被误用成“功能归属”,比如“管理员”泛化“用户”没问题,但“管理员”泛化“删除用户”就不对,因为泛化只能用在用例与用例、参与者与参与者之间,不能跨越到操作层面。
关联网是参与者与用例之间唯一允许的关系,它表示参与者与系统交互的意图。复习题里“顾客和购买饮料的关系是关联”“贷款客户与借款用例之间的关系是关联”都是这类。说明一下,关联在UML图上通常是一条无箭头的实线,有时一端带符号表示导航性,但画参与者对用例的连接时,不要画箭头,避免和依赖关系混淆。
2.3 把复习题转成用例图:PlantUML 复现
复习题的案例分析题只给了文字要点,没有给参考答案图。你完全可以用PlantUML把案例转成可验证的模型,比如图书管理系统的还书与罚款扩展:
@startuml left to right direction actor 借书者 as borrower rectangle 图书管理 { usecase "还书" as ReturnBook usecase "罚款" as Fine usecase "借书" as BorrowBook } borrower --> ReturnBook borrower --> BorrowBook ReturnBook ..> Fine : <<extend>> @enduml代码里..>表示依赖关系,配合<<extend>>构造型表示扩展;left to right direction让参与者位于左侧,符合UML用例图的常规布局。实际使用时,包含关系用..>加<<include>>,参与者之间的泛化用--|>连接两个actor。写完用PlantUML渲染,几乎立刻就能看出箭头方向是否画反、参与者和用例是否连在了正确的位置。
2.4 用例建模的常见误判
有几个高频错误值得单独拿出来说。第一是参与者的范围,参与者只能是系统外部的角色,人、硬件设备、外部系统都可以,但不能是系统内部模块,复习题第2章第4题就专门考了外部Actor的定义。第二是用例命名,一般用动词短语,比如“查询图书”“还书”,不要用名词“图书查询系统”,那成了模块名。第三是关系类型的误判,大多来自把“数据共享”当包含、把“可选功能”当扩展。正确的做法是回到执行流程:主用例执行时,被包含用例是否一定参与;扩展用例是否在某个扩展点按条件插入。把这两个问题想清楚,包含和扩展基本不会选错。
3. 类图与接口:可见性、抽象类与多重性
3.1 可见性符号与静态成员
复习题里Window类那道填空题非常有代表性,它把UML类图最基础的符号全部考了一遍。用Visio画UML类图时,这些符号在属性或操作的前缀位置,很容易被漏掉或选错。
| 符号 | 表示 | 说明 |
|---|---|---|
+ | public | 任何类都可访问 |
# | protected | 子类可访问 |
- | private | 仅类内部访问 |
~ | package | 同一包内可见 |
| 下划线 | static | 静态成员,属于类而不是对象 |
| 斜体 | abstract | 抽象类或抽象操作 |
这里有两个易错点。第一个是protected成员虽然子类能访问,但private成员子类不能直接访问,却仍然会被继承。复习题第2章第6题、第3章第1题反复绕着这个点出题,错误选项经常写成“子类不继承其私有特性”,正确的说法是“子类继承私有特性,但不能直接访问”。第二个是静态操作中没有“当前对象”的概念,所以静态方法不能隐式访问非静态成员,这一条在填空题里出现过,也解释了为什么带下划线的操作只能操作带下划线的属性。
3.2 抽象类、接口与实例化的边界
抽象类不能直接实例化,但它可以有构造器、可以有具体方法和状态;接口则只有行为规范,没有状态,也不能直接被实例化。复习题第3章第5题说“接口是一种抽象类型,可以直接实例化”,答案是错误。接口要通过类实现后,由实现类来实例化。
判断一个类是不是抽象类,看它是否包含未实现的抽象操作。如果一个子类继承了父类的抽象操作,但自己没有提供实现,那么这个子类仍然是抽象类。很多人在这里容易把“继承”和“实现”混在一起。画图时区分也很简单:类继承类用实线空心三角,实线指向父类;类实现接口用虚线空心三角,虚线指向接口。UML类图中接口还可以用圆圈表示,叫棒棒糖表示法,但考试和大多数设计文档里更常用的是矩形加<<interface>>构造型。
3.3 多重性与关联终端
对象图里考了一组多重性判断,比如“对于A类的一个对象,其关联的B类对象的数量允许为0”,答案是“对”,说明A到B的关联多重性下界是0。这种题读图时看的是关联两端标注的基数。常见基数有0..1、1、*、1..*。解析时先确定站在哪个类看对面:0..1表示可零可一,1表示恰好一个,*表示零到多个。
复习题里“对于B类的一个对象,其关联的A类对象的数量最多是1个”,说明A端标注的是0..1或1;“D关联C允许为0是错的”,说明C端基数下界至少是1。这里有一个画图时容易踩的坑:多重性数字写在靠近目标类的那一端。比如Order "1" -- "0..*" OrderLine表示一个订单对应0到多个订单明细,1靠近Order类,描述的是“每个OrderLine属于几个Order”,不要写反。
3.4 从一段需求生成类图
订购货物系统那道案例分析题,要求体现客户、订单、订单明细、产品、支付方式的关系。用PlantUML可以这样描述:
@startuml class Customer { -name : String -address : String } class Order { -date : Date -status : Status +calcTax() : float +calcTotal() : float } class OrderLine { -quantity : int } class Product { -price : float } class Payment { -amount : float } Customer "1" -- "0..*" Order : 创建 Order "1" -- "1..*" OrderLine OrderLine "1" -- "1" Product : 关联 Order "0..*" -- "0..1" Payment : 支付 @enduml代码中"1" -- "0..*"表示订单端是1,订单明细端是0到多个;关联名称用冒号写在连接线上。Payment作为抽象超类,信用卡、支票、现金可以建模成它的子类,用--|>实现泛化。这个案例也说明了一个建模顺序:先找名词,客户、订单、明细、产品、支付方式都是候选类;再找动词,创建、支付、计算税额是关联或操作;最后补多重性和角色。
4. 状态图、活动图、构件图与部署图:动态和物理视图
4.1 状态图与活动图的定位差异
状态图描述单个对象在事件驱动下的状态变迁,活动图描述业务流程或算法步骤。复习题第1章第11题问“下面哪个不是UML中的静态视图”,答案是状态图。在复习题的语境里,用例图被归入静态视图,因为它描述系统对外功能的结构;而类图、对象图属于静态视图,状态图属于动态视图。其实在UML规范中,用例图通常被归入行为图,但以本课程教材的划分为准,这里不展开争论,考试按参考答案来。
状态图的核心元素是状态、事件、转换和动作。状态代表对象生命周期中的一个稳定阶段,事件触发转换,转换上可以附着动作。活动图则更接近流程图,有初始节点、活动节点、决策节点、合并、分叉和汇合。要注意的是,UML图的标准集合里没有“流程图”,那是通用流程图,不属于UML标准图。复习题第1章第14题里“不属于程序三种基本控制结构的是嵌套”,也从侧面说明结构化和面向对象建模的思维方式是两套体系,画图前先分清用哪个。
4.2 部署图与构件图:制品和结点的关系
构件图建模系统的可替换模块,比如jar包、DLL、数据库文件;部署图建模这些制品运行在哪些物理结点上。结点是计算机或设备,制品是物理文件或可执行单元。复习题第10章把制品、结点和部署图放在一起,考点就是区分逻辑组件与物理设备。
举例来说,一个网上书店系统里,OrderService构件通过接口与Database构件交互,这是构件图关心的内容;而order.war部署在应用服务器结点上,Database部署在数据库服务器结点上,两个结点之间用通信路径连接,这是部署图关心的内容。部署图是UML中与硬件环境最近的一种图,在做系统架构评审、压测方案设计、运维交付文档时经常用到。画部署图时,结点用立方体表示,制品用矩形加<<artifact>>构造型,结点之间的连接用实线,表示通信路径。
4.3 用状态表转状态图
实际工作中如果不想一开始就打开建模软件,可以先用状态表把逻辑理清,再转成状态图。以订单状态机为例:
| 当前状态 | 事件 | 动作 | 下一状态 |
|---|---|---|---|
| 新建 | 提交 | 校验库存 | 待支付 |
| 待支付 | 支付成功 | 扣库存 | 已支付 |
| 待支付 | 取消 | 释放库存 | 已取消 |
| 已支付 | 发货 | 通知物流 | 已发货 |
有了这张表,画状态图只需要把每个“当前状态”画成圆角矩形,事件标在转换箭头上,动作放在斜杠/之后即可。用PlantUML表达是这样的:
@startuml [*] --> 新建 新建 --> 待支付 : 提交/校验库存 待支付 --> 已支付 : 支付成功/扣库存 待支付 --> 已取消 : 取消/释放库存 已支付 --> 已发货 : 发货/通知物流 @enduml这里的冒号左边是触发事件,右边是伴随动作。状态图的价值在于把对象生命周期内的非法状态转换暴露出来,比如“已取消”不能再回到“待支付”,“已发货”不能再撤销。复习题里关于状态机的简答题,核心就是问这个建模视角能避免什么,答案是避免业务规则散落在流程代码里,无法统一校验。
5. 用复习题反推考点:一套可复现的备考与验证方法
5.1 把选择题错因整理成规则表
统计这份复习题里的错误选项,可以发现高频干扰项集中在几个地方:把包含说成泛化、把扩展方向画反、把接口实例化、把子类继承私有成员当成不继承。我习惯把错因做成一张规则表,考前只看表即可:
| 判定问题 | 正确规则 | 常见干扰项 |
|---|---|---|
| 用例间关系 | 包含=必做行为提取;扩展=条件可选的插入;泛化=特化 | 关联、聚集 |
| 继承可见性 | private成员被继承但不可直接访问 | 不继承、互不依赖 |
| 抽象类 | 有未实现操作即为抽象类,不能实例化 | 有父类即具体类 |
| 多重性 | 数字标识靠近目标类一侧 | 方向反读 |
| 静态成员 | 静态操作无当前对象 | 静态可随意访问实例成员 |
这张表基本覆盖了这份复习题80%的单选题考点。不要只背答案,要背“为什么排除那个干扰项”,因为考试换一个说法,干扰项还是同一批。
5.2 用空白建模题做自测
复习题的案例分析题都只给了文字需求,正好用来做闭卷画图训练。做法是:先不看参考答案的要点,自己在纸上或建模软件里画,再对照要点检查三件事——参与者是否遗漏外部系统或角色、用例是否都是动词短语、关系是否有方向错误。
比如远程网络教学系统,至少要有学生、登录、浏览课件、查找课件、下载课件、观看教学视频、找回密码这些用例。这里“登录”与“找回密码”是扩展关系,因为找回密码只在忘记密码这个条件点触发;“浏览课件”“下载课件”等与登录,就要看建模粒度。如果登录是进入系统前的必经校验,应该建模为包含;如果每个功能都要求身份验证,把“登录”作为被包含用例更合适。这就是案例题最常见的辨析点。
5.3 一个具体技巧:五分钟校验用例图完整性
最后给一个可落地的校验方法。用PlantUML渲染用例图后,对照需求文本逐条打勾,重点检查两点。第一,每个动词性需求是否至少被一个用例覆盖,比如“查询已交费注册的学生并打印发票”,应拆成“查询学生信息”和“打印发票”两个用例,不能揉在一个用例里。第二,参与者是否站在系统边界外,如果“工作人员”是系统内部角色,就不应画在边界内。
还有一个快捷检查:把用例名称都列出来,如果某个用例名是名词短语,比如“学生信息”,十有八九是把数据实体当成了用例,应改成“管理学生信息”或“查看学生信息”。做完这一步,用例图的骨架基本不会有大问题,剩下的细节就是调整包含和扩展的方向了。
本文还有配套的精品资源,点击获取