简介:这份资源是武汉理工大学UML建模技术课程的实验报告,以图书管理系统为案例,面向软件工程、计算机相关专业学生及UML初学者,帮助读者通过完整实验流程掌握用例驱动分析方法与StarUML工具的使用。资源包内含1个PDF文件,大小约563KB,内容涵盖实验分析设计、调试过程与结果分析等完整章节。报告围绕学生管理、书籍管理、系统管理三大功能模块展开,详细记录了识别参与者与用例、编写用例文本、建立用例模型的全过程,并给出借阅图书、归还图书等典型用例的主成功场景与扩展流程,涉及用例图、活动图、类图、序列图、状态图等静态与动态建模技术。目前已有792人学习浏览,适合需要参考实验报告结构、学习UML建模步骤或完成同类课程作业的读者对照使用。
1. 武汉理工UML实验里的图书管理系统:一份 PDF 能拆出多少可复用的建模套路
很多人拿到「武汉理工UML实验——图书管理系统.pdf」的第一反应是找模板抄一遍交差,但真正做过企业级建模的人会反过来看:这份实验其实是一个被压缩到最小的完整建模闭环。它逼你在一个学期内走完用例图、类图、时序图、状态图、活动图的全流程,而图书管理系统恰好是那个「业务规则足够简单、但边界情况足够多」的经典靶子——借书、还书、续借、预约、超期罚款、图书注销,每一条都能牵出一组类之间的关系和状态迁移。
这份实验的价值不在于 PDF 本身,而在于它逼你回答几个真问题:图书和馆藏副本到底是不是一个类?借阅记录该由谁创建、谁销毁?超期罚款是借阅记录的状态还是独立实体?这些问题在 StarUML 里画错一根箭头,到了编码阶段就是一张表拆成三张还是五张的差别。适合正在上 UML 课、准备软考中级、或者第一次接手图书管理类系统需求的人,把这份实验当成一次低成本试错。
2. 从需求到用例图:图书管理系统到底有几个参与者
2.1 先分清参与者与系统边界,再动手画椭圆
图书管理系统的参与者看起来只有读者和管理员,但实验里最容易翻车的地方是把「借阅规则」当成参与者。规则是约束,不是人。我一般会先把所有跟系统交互的角色列出来,再逐个问:这个角色是主动发起动作,还是被动接收结果?
读者:查询图书、借书、还书、续借、预约、查看借阅历史。 管理员:图书入库、图书注销、处理超期、管理读者账户、生成报表。
系统边界画一个矩形,把「图书管理系统」写在顶部,所有用例椭圆放在矩形内,参与者小人放在矩形外。读者和管理员之间不画箭头,他们各自跟用例连线。这里有一个常见错误:把「登录」画成用例。登录是每个用例的前置条件,不是独立业务价值,除非实验明确要求单独建模权限模块。
提示:用例图里不要出现「数据库」「接口」这类技术组件,它们不是参与者。
2.2 用例描述表比图更重要
图只给骨架,真正让后续类图有依据的是用例描述。每个用例至少写清楚:前置条件、主事件流、备选流、后置条件。以「借书」为例:
| 字段 | 内容 |
|---|---|
| 用例名 | 借书 |
| 参与者 | 读者 |
| 前置条件 | 读者已登录,账户状态正常,无超期未还 |
| 主事件流 | 1. 读者输入图书ISBN 2. 系统显示可借副本 3. 读者确认借阅 4. 系统创建借阅记录 5. 系统更新副本状态 |
| 备选流 | 2a. 无可借副本,提示预约 4a. 读者借阅数达上限,拒绝 |
| 后置条件 | 借阅记录状态为「借出」,副本状态为「已借出」 |
这张表里的每一个名词,后面都会变成类图里的类或属性。「借阅记录」「副本状态」「借阅上限」都不是凭空来的。实验里如果跳过这一步直接画类图,最后一定会发现少了一个「预约记录」类,或者把「罚款」硬塞进读者属性里。
2.3 用 StarUML 画用例图的三个参数
StarUML 新建项目后选 UML 2.x,右键 Model 添加 Use Case Diagram。参与者用 Actor,用例用 Use Case,边界用 System Boundary。关联线用 Association,包含关系用 Include,扩展关系用 Extend。
- Include:基础用例一定会执行被包含用例。比如「借书」include「验证读者资格」。
- Extend:基础用例在特定条件下才执行扩展用例。比如「借书」在无库存时 extend「预约」。
- 泛化:参与者之间可以泛化,比如「教师读者」继承「读者」。
画完后右键导出为 PNG,分辨率选 300dpi,实验报告里图才不会糊。StarUML 默认字体偏小,在 Preferences 里把 Diagram Font Size 调到 14 以上。
3. 类图与关系:图书、副本、借阅记录怎么拆才不打架
3.1 图书和馆藏副本必须分成两个类
这是图书管理系统建模的第一个分水岭。很多人把「图书」当成一个类,属性里塞 ISBN、书名、作者、库存数量。但库存数量是动态的,而且每一本实体书有独立的条码、位置、状态。正确做法是:
- Book(图书):ISBN、书名、作者、出版社、分类号。描述的是「一种书」。
- BookCopy(馆藏副本):条码、位置、状态、所属 Book。描述的是「一本具体的书」。
关系是 Book 1 对多 BookCopy。借阅记录关联的是 BookCopy,不是 Book。如果实验里只画一个 Book 类,后面时序图里「借哪一本」就说不清。
3.2 借阅记录是关联类还是独立类
读者和副本之间是多对多关系:一个读者借过多个副本,一个副本被多个读者借过。多对多关系在类图里可以画成一条关联线,但这条线上有借阅日期、应还日期、实还日期、罚款金额这些属性。UML 提供两种表达:
- 关联类:用虚线连到关联线上,类名 BorrowRecord。
- 独立类:直接建 BorrowRecord 类,用两条关联分别连 Reader 和 BookCopy。
我一般选独立类,因为借阅记录有生命周期,会被查询、统计、归档,独立类在后续时序图和状态图里更好引用。关联类适合属性极少且不需要独立操作的场景。
3.3 类图里的箭头含义与代码映射
UML 类图箭头是软考和实验报告的高频扣分点。把常见关系列清楚:
| 关系 | 符号 | 代码映射 | 图书系统例子 |
|---|---|---|---|
| 关联 | 实线 | 成员变量 | Reader 关联 BorrowRecord |
| 聚合 | 空心菱形 | 成员变量,可独立存在 | BookShelf 聚合 BookCopy |
| 组合 | 实心菱形 | 成员变量,同生共死 | BorrowRecord 组合罚款记录 |
| 泛化 | 空心三角实线 | 继承 | 教师读者继承读者 |
| 实现 | 空心三角虚线 | 接口实现 | 罚款计算实现 FineCalculator |
| 依赖 | 虚线箭头 | 方法参数或局部变量 | 借书服务依赖库存查询 |
在 StarUML 里画组合关系时,菱形端在整体一侧。比如 BorrowRecord 组合 FineRecord,菱形在 BorrowRecord 端。画反了语义就变成罚款记录拥有借阅记录。
3.4 用 StarUML 生成类图并导出代码骨架
StarUML 支持从类图生成 Java 或 TypeScript 骨架。操作路径:Tools → Java → Generate Code。生成前先给每个类设好包名,在 Model Explorer 里右键类 → Add → Attribute / Operation。
// 生成的骨架示例,手动补全了关键注释 public class Book { private String isbn; private String title; private String author; // 一对多:一种图书对应多个馆藏副本 private List<BookCopy> copies; } public class BookCopy { private String barcode; private String location; private CopyStatus status; // AVAILABLE, BORROWED, RESERVED, LOST private Book book; } public class BorrowRecord { private Date borrowDate; private Date dueDate; private Date returnDate; private Reader reader; private BookCopy copy; // 组合:罚款记录随借阅记录销毁 private FineRecord fine; }生成代码后不要直接交,StarUML 默认把关联生成成 List,但没处理双向关联的循环引用。如果 Reader 里也有 List ,序列化时会栈溢出。实验阶段可以只保留单向关联,或者手动加 @JsonIgnore。
4. 动态结构图:时序图、状态图、活动图各管什么
4.1 时序图把用例流翻译成对象交互
用例描述里的主事件流,在时序图里变成对象之间的消息。以「借书」为例,参与对象:Reader(Actor)、BorrowController、BookCopy、BorrowRecord、ReaderAccount。
消息顺序:
- Reader → BorrowController: borrow(isbn, readerId)
- BorrowController → ReaderAccount: checkStatus()
- ReaderAccount → BorrowController: ok
- BorrowController → BookCopy: findAvailable(isbn)
- BookCopy → BorrowController: copy
- BorrowController → BorrowRecord: create(reader, copy)
- BorrowController → BookCopy: setStatus(BORROWED)
- BorrowController → Reader: success
StarUML 里画时序图,生命线用 Lifeline,消息用 Message。同步消息实心箭头,异步消息开放箭头,返回消息虚线开放箭头。激活条用 Activation。实验报告里如果只画消息不画激活条,会被扣分。
注意:时序图里不要出现「数据库」生命线,除非实验明确要求三层架构。业务层建模就只画业务对象。
4.2 状态图盯住一个对象的状态迁移
图书管理系统里最适合画状态图的是 BookCopy 和 BorrowRecord。BookCopy 状态:可借、已借出、预约锁定、遗失、注销。迁移事件:借出、归还、预约、取消预约、报失、注销。
BorrowRecord 状态:借出、已归还、超期、超期归还。迁移事件:归还、到期检查。
状态图里要写清楚 guard condition。比如「可借 → 已借出」的守卫条件是「读者账户正常且未达借阅上限」。没有守卫条件的状态图等于没画。
4.3 活动图适合表达跨对象的业务流程
活动图跟时序图的区别:时序图强调对象间消息顺序,活动图强调业务步骤和分支。图书管理系统里「超期处理」适合用活动图:每天定时触发 → 查询未还记录 → 判断是否超期 → 是则计算罚款 → 更新记录状态 → 通知读者。
活动图里用 Decision Node 画分支,用 Merge Node 汇合,用 Fork/Join 表达并行。比如「通知读者」和「更新罚款记录」可以并行。
4.4 动态结构图在 StarUML 里的导出与校验
StarUML 支持把时序图导出为图片,也支持导出 XMI。实验报告一般要求 PNG。导出前检查:
- 消息顺序编号是否连续
- 生命线名称是否和类图一致
- 状态图里的状态名是否和类属性枚举一致
如果类图里 BookCopy 的状态属性叫 status,状态图里的状态名最好也用 AVAILABLE、BORROWED 这种,不要一个写中文一个写英文。
5. 避坑与排查:UML 实验里最容易翻车的五个地方
5.1 类图里把「借阅数量」塞进 Book 属性
现象:Book 类里有 stock 属性,借书时直接 stock--。原因:把「一种书」和「一本具体的书」混为一谈。解决:拆出 BookCopy 类,stock 用 count(copies where status=AVAILABLE) 动态计算,不存冗余字段。
5.2 时序图消息顺序和用例描述对不上
现象:时序图里先创建借阅记录再检查库存。原因:画图时凭感觉,没对照用例描述的主事件流。解决:把用例描述表放在旁边,每画一条消息回去对一行,顺序错就改。
5.3 状态图缺少守卫条件导致状态乱跳
现象:BookCopy 从「已借出」直接跳到「可借」,没有经过「归还」事件。原因:只画了状态和箭头,没写事件和守卫。解决:每条迁移线上标注「事件 [守卫] / 动作」,比如「归还 [无罚款] / 更新状态」。
5.4 StarUML 导出图片模糊或字体乱码
现象:导出的 PNG 放大后看不清,中文变方框。原因:默认导出分辨率低,字体没嵌入。解决:导出时选 300dpi,在 Preferences → Font 里把默认字体改成系统支持中文的字体,比如 Microsoft YaHei 或 Noto Sans CJK。
5.5 类图关系箭头画反导致代码生成错误
现象:生成的代码里 BookCopy 里有 Book 的 List,Book 里也有 BookCopy 的 List,双向循环。原因:关联线两端的导航性没设对。解决:在 StarUML 里选中关联线,在 Properties 里设置 Navigable 端。一对多只让「多」端可导航到「一」端,或者两端都设但手动处理序列化。
6. 把实验 PDF 变成可复用资产:三个进阶技巧
6.1 用 StarUML 的 Model Validation 做一致性检查
StarUML 自带模型校验:Tools → Validate Model。它会检查孤立类、未使用的用例、关系两端类型不匹配等问题。跑一遍校验,把警告当错误改。我一般会在导出报告前跑三次:画完类图跑一次,画完动态图跑一次,最后合并跑一次。
6.2 从类图反向生成数据库 DDL
类图到关系数据库的映射规则:类变表,属性变列,一对多把「一」端主键放到「多」端做外键,多对多拆中间表。BorrowRecord 本身就是中间表,直接建表即可。
-- 从类图映射出的核心表结构 CREATE TABLE book ( isbn VARCHAR(20) PRIMARY KEY, title VARCHAR(200) NOT NULL, author VARCHAR(100), publisher VARCHAR(100) ); CREATE TABLE book_copy ( barcode VARCHAR(30) PRIMARY KEY, isbn VARCHAR(20) REFERENCES book(isbn), location VARCHAR(50), status VARCHAR(20) CHECK (status IN ('AVAILABLE','BORROWED','RESERVED','LOST')) ); CREATE TABLE borrow_record ( id BIGINT PRIMARY KEY, reader_id BIGINT REFERENCES reader(id), barcode VARCHAR(30) REFERENCES book_copy(barcode), borrow_date DATE NOT NULL, due_date DATE NOT NULL, return_date DATE, fine_amount DECIMAL(10,2) DEFAULT 0 );这张 DDL 不是实验要求的,但能帮你验证类图是否完整。如果某张表建不出来,说明类图里少了类或关系。
6.3 把实验报告变成面试项目描述
UML 实验本身不值钱,值钱的是你能讲清楚「为什么这么拆」。面试时如果被问到图书管理系统,不要背用例列表,直接讲:我把 Book 和 BookCopy 拆开,因为库存是动态的;借阅记录用独立类而不是关联类,因为它有生命周期;状态图里加了守卫条件,防止状态乱跳。这三句话比十张图都有说服力。
我自己的习惯是每做完一个 UML 实验,把类图、时序图、状态图各挑一张,用一句话写清楚「这张图解决了什么问题」,存进一个 markdown 文件。攒到五六个实验后,这就是一份能直接改写成简历项目经历的素材库。希望帮到你。
本文还有配套的精品资源,点击获取