简介:一份面向软件工程与UML课程设计的文档资料,以学生成绩管理系统为完整案例,系统呈现从可行性研究、需求规格说明、系统设计到数据库设计的全流程UML建模过程。文档先分析开发背景与技术、经济、实施可行性,再明确成绩录入、信息查询、信息更新、用户修改四大功能模块,并给出对应的用例图、顺序图、协作图、状态图、活动图、组件图和部署图等可视化模型。数据库部分设计了student、grade、teacher三张核心数据表,并说明了主键设置与逻辑关系,帮助读者理解面向对象分析与建模方法。资源包共1个doc文件,整体大小102KB,内容紧凑、目录结构清晰。目前已有3151人学习下载,适合高校软件工程专业学生、UML课程设计者及相关开发人员参考,可用于快速掌握UML各类图表的绘制规范,梳理财绩管理系统需求分析与数据库设计的完整思路,辅助完成课程设计报告或毕业设计文档撰写。
1. 这一份 UML 课程设计,先把「建模」和「画图」分开
「学生成绩管理系统UML课程设计.doc」这类题目,难点从来不是UML图的数量,而是需求到模型的一站式映射。很多人在Visio或ProcessOn里画了七八张图,但用例图里的每个用例到了时序图完全找不到对应场景,类图里的考试成绩类在部署图里没有落点,答辩一追问就断片。真正的做法是先定用例图界定系统边界,再用品类图固定静态结构,接着用时序图、活动图、状态图描述行为,最后用组件图与部署图把逻辑映射到物理环境。下面这套顺序既适合正在做课程设计的学生,也适合刚接手UML建模的工程师,可以让文档在20页内讲明白,也让每张图经得起追问。
2. 用例图先行:学生成绩管理系统的需求边界与角色梳理
2.1 角色与用例的划分标准
用例图是整份UML课程设计的起点,它回答两个问题:谁在使用这个系统,系统为用户完成什么可观测的目标。学生成绩管理系统的Actor通常只有三类:学生、教师、教务管理员。教务管理员负责的基础数据维护(课程、学期、用户)和学生成绩的复核发布,教师只负责所授课程的成绩录入与修改申请,学生只能查询成绩并发起申诉,边界划分依据是职责而不是部门。
用例划分最容易犯的错误是把「登录」当作唯一用例,然后全体Actor都连上去。登录验证更适合作为被包含用例,被成绩查询、成绩录入等核心业务用例复用,而不是独立存在。划分用例的检验标准是:用例名必须是一个动词短语,完成后必须产生对某个Actor可见的结果,例如「查询本学期成绩」「录入课程成绩」,而不是「数据库操作」「数据处理」这类实现层面的描述。按这个标准,成绩申诉、成绩统计分析和教师复核是三个独立用例,课程管理是教务管理员的用例,学生不能直接触发。
2.2 include、extend 与泛化的用法边界
用例关系是课程设计扣分的重灾区。include表示基础用例在执行时必然调用被包含用例,例如「查询成绩」必然先做「登录验证」,箭头从基础用例指向被包含用例,使用虚线箭头加<<include>>标注。extend表示扩展用例在满足特定条件时才插入到基础用例的扩展点,例如「成绩申诉」只有在学生对已发布成绩有异议时才触发,箭头从扩展用例指向基础用例,这是很多教材里容易画反的方向。泛化用于角色或用例之间的继承,比如「任课教师」可以泛化为「教师」,但一个系统里很少把多个角色画成泛化树,三类Actor功能不重叠时直接用三条Actor生命线即可。
不要在满页上堆满include和extend。一个用例图有一到两处include是正常的,超过三处就该反思基础用例拆分粒度。比如「录入成绩」和「修改成绩」可以都include「验证教师身份」,但不必让「成绩复核」再include「修改成绩」,把复核作为独立用例放在教务管理员下更清晰。判定标准是:被包含用例是否一定执行,扩展用例是否能独立描述一个完整业务目标。
2.3 用 PlantUML 快速生成用例图并导出
手绘或用Visio直接拖拽用例图容易在关系线上反复修改,常见做法是用文本化方式生成初稿。下面是可直接复制改用的PlantUML脚本,生成效果和Visio手动画出的图在答辩识读上没有区别,但修改成本低很多。
@startuml left to right direction actor 学生 as S actor 教师 as T actor 教务管理员 as M rectangle 学生成绩管理系统 { usecase "登录验证" as UC1 usecase "成绩查询" as UC2 usecase "成绩申诉" as UC3 usecase "成绩录入" as UC4 usecase "成绩修改申请" as UC6 usecase "成绩复核" as UC5 usecase "课程管理" as UC7 } S --> UC2 S --> UC1 T --> UC4 T --> UC6 M --> UC5 M --> UC7 UC2 ..> UC1 : <<include>> UC3 .> UC2 : <<extend>> UC5 ..> UC4 : <<include>> @enduml脚本中的rectangle定义系统边界,边界之外的Actor是外部角色,边界之内是系统用例。include方向指从基础用例指向被包含用例,所以成绩查询指向登录验证,成绩复核指向成绩录入,表达「复核必然依赖录入链路已经存在」。extend方向是成绩申诉指向成绩查询,说明申诉是查询在特定条件下的补充流程。生成时用PlantUML命令行或在线服务导出PNG,插入doc后建议把svg源文件一并归档,导出的图片在Word里缩放或重排时不会发虚。
2.4 用例文档模板:让每张图有据可查
光有用例图不能满足UML课程设计文档的完整度要求,需要配套一张用例规约表。答辩时老师通常不会逐条看图,而是随机抽一个用例让你讲前置条件和基本流程。
| 编号 | UC-02 | 用例名 | 查询本学期成绩 |
|---|---|---|---|
| 主参与者 | 学生 | 触发条件 | 学生进入成绩查询页面 |
| 前置条件 | 学生已通过登录验证,当前学期成绩已发布 | 后置条件 | 页面显示当前学期各课程成绩与学分 |
| 基本流程 | 1. 学生选择学期范围 2. 系统校验查询权限 3. 系统查询成绩数据 4. 页面返回成绩列表 | 扩展点 | 成绩有异议时触发UC-03成绩申诉 |
写规约表时注意前置条件与后置条件必须对应用例图中的include关系,如果UC-02 include了UC-01,那么UC-02的前置条件里就要有「已完成登录验证」。每张用例图配2到3个核心用例的规约表即可,不必所有用例全部写表,否则文档重心会从建模偏移到需求说明,后续第5章的模型一致性检查也失去了对照基准。
3. 类图与包图:把成绩、课程、学生的静态结构定下来
3.1 从用例名词到类:候选类与职责分配
用例图里的名词是生成候选类的原材料。常见的候选类有学生、教师、教务管理员、课程、成绩、学期、班级。把所有候选类列出来后先做一次筛选:登录信息属于User类而不是学生类,成绩不是学生的一个属性而是一个独立对象,因为成绩与课程、学期、教师都有关联。这里的关键决策是把「选课记录」建模成关联类,学生和课程之间是多对多关系,多对多必须在UML中拆出中间类,否则无法表达同一学生同一课程在不同学期的成绩,也无法挂接平时成绩和期末成绩。
候选类的属性分配遵循一个原则:属性只放在直接相关的类中。userId、password、role放在User基类中,学号与专业放在Student类中,工号放在Teacher类中,学分与课时放在Course类中。不要在每个类里重复出现创建时间、备注这类字段,这些在系统实现时属于审计字段,在课程设计的类图里出现过多杂属性会掩盖核心关系。
3.2 关联多重性、聚合组合与依赖的绘制规则
UML类图的关联多重性表达业务规则。一个学生可以有多条选课记录,所以Student到Enrollment是1到0..*。一个教师可以教授多门课程,Teacher到Course是1到0..*。一条选课记录至少有一个总评成绩,所以Enrollment到Score是1到1..*。多重性必须写在关联两端,不能只在连线中间写个*,这是Visio画UML类图时新手常常漏掉的地方。
Visio的画法是打开UML类图模板,把两个类形状拖到画布,用「关联」连接线连接两端,然后双击关联线打开UML关联属性对话框,分别在「起始多重性」和「目标多重性」中填入1和0..*。Visio默认的关联线没有箭头表示导航方向,右键连线,在「设置形状格式」里的「线条」中找到「箭头设置」,末端箭头选择实心箭头表示可导航方向,如果业务上需要双向导航就画成无箭头实线并标注多重性。聚合与组合的区别在于生命周期:课程与选课记录之间是聚合关系,选课记录可以与课程分离存在;成绩与选课记录之间是组合关系,选课记录删除时成绩必须一并删除。用空心菱形表示聚合,实心菱形表示组合,菱形端指向整体一侧。
3.3 包图分包原则:按层分包还是按功能分包
学生成绩管理系统规模不大,包图通常和类图配套出现,用来展示逻辑分层。常见的分包方案有两种:按功能分包,分为user包、course包、score包,包内各自放实体类与业务类;按层分包,分为domain包、dao包、service包、controller包。课程设计文档建议选按层分包,理由是和后端开发技术栈更容易对应上,答辩时解释包依赖也直接。包图的核心约束是依赖不能成环,表现成图的规则就是service层依赖domain层,controller层依赖service层,dao层依赖domain层。
依赖方向画出来后要检查一个细节:domain包不能反向依赖service包,否则就形成环依赖,运行时会出现类加载的循环引用,建模阶段就能暴露这个问题是包图最大的价值。另外包图不是文件目录结构图的UML替代品,包是对模型元素的逻辑分组,包与包之间的依赖线表示「一个包中的元素使用另一个包中的元素」,所以在doc里不要用文件夹图充当包图,两者概念级别不同。
3.4 一张可以直接改用的类图脚本
@startuml class User { - userId : String - password : String - role : String + login() : Boolean } class Student { - studentNo : String - major : String } class Teacher { - teacherNo : String - title : String } class Course { - courseNo : String - courseName : String - credit : Integer } class Enrollment { - semester : String - regularScore : Float - finalScore : Float + calcTotalScore() : Float } class Score { - scoreType : String - scoreValue : Float } User <|-- Student User <|-- Teacher Student "1" -- "0..*" Enrollment Course "1" -- "0..*" Enrollment Enrollment "1" -- "1..*" Score TicketTeacher "1" -- "0..*" Course : 讲授 Teacher "1" -- "0..*" Course : 讲授 @enduml脚本里的直接继承关系是User泛化出Student与Teacher,公共属性集中放在父类中。Enrollment作为关联类拆解了学生与课程的多对多关系,同时携带平时成绩和期末成绩,calcTotalScore()负责计算总评。Score单独建模是为了支持成绩类型扩展,比如补考成绩、重修成绩,如果没有这个扩展需求,可以把scoreType和scoreValue直接放入Enrollment,减少一层实体。
注意:UML 类图中的多重性是从对端角度书写的。Student 与 Enrollment 连线中,Student 这一端写 1,表示一条选课记录只能对应当前一个学生,而不是一个学生只有一条选课记录。方向写反或漏写是课程设计中最常见的扣分点。
4. 时序图、活动图与状态图:把流程和行为状态讲清楚
4.1 时序图:选一个主场景,画透比画全更重要
时序图不要覆盖所有业务流程,选2到3个代表场景画透即可。既然题目是学生成绩管理系统,最稳妥的选择是「学生查询成绩」和「教师录入成绩」两个主场景。下面脚本展示学生查询成绩时边界类、控制类、实体类三层如何协作。
@startuml actor 学生 boundary ScoreQueryUI control ScoreQueryController entity ScoreService database ScoreDB 学生 -> ScoreQueryUI : 查询成绩() ScoreQueryUI -> ScoreQueryController : queryScore(studentId) ScoreQueryController -> ScoreService : getScores(studentId) ScoreService -> ScoreDB : SELECT * FROM score WHERE student_id=? ScoreDB --> ScoreService : resultSet ScoreService --> ScoreQueryController : List<Score> ScoreQueryController --> ScoreQueryUI : 页面数据 ScoreQueryUI --> 学生 : 渲染成绩列表 @enduml时序图上的消息分为同步消息、返回消息和创建消息。同步消息用实心箭头,表示调用方发出后必须等待处理结果,对应上图中的查询与数据库操作。返回消息用虚线箭头,不表示新的控制流,而是把数据回传给上层。这里的actor「学生」不需要反向发消息,界面层向actor画虚线返回的是渲染结果。激活条表示对象处理消息的持续时间,一个消息从发出到返回覆盖的纵向范围就是该对象生命周期中的活跃段,组合片段可以用来表达循环和条件,查询多条成绩时用loop框住消息即可,不必每一条都展开成独立消息。
画时序图前先确认场景的对象是否都在类图中出现过。如果时序图的生命线里出现了类图中不存在的类,要么补到类图里,要么把类图里的类删掉保证模型一致,这一步直接决定了第5章的一致性检查是否通过。
4.2 活动图:用泳道约束职责,用分岔匹配汇合
活动图适合描述跨角色协作的业务流程。以「教师录入成绩并提交审核」为例:教师启动成绩录入,系统校验分数范围,教师提交成绩单,教务管理员进行复核,复核通过后成绩发布,不通过则退回教师修改。这个流程要画成带泳道的活动图,泳道从上到下依次是教师、系统、教务管理员,每个活动归属于一个明确的执行者。
活动图的三个高坑点需要格外注意。第一是决策节点只能有一个输入判断条件,比如「分数在0到100之间」是合法分支,跳出范围的错误分支直接汇入提示信息,不要在同一个决策节点上堆两个条件。第二是分岔与汇合必须成对出现,成绩录入和成绩复核可以并行时用分岔把控制流拆成两条道,后面必须用汇合合并恢复成一条控制流,只分不合并违反UML活动图的语义。第三是泳道不是摆设,教师看不到「成绩发布」这个活动,教务管理员也不直接操作「保存分数」,活动对应到角色上,图才真正表达了业务流程而不是一堆功能说明。
画活动图的工具如果是ProcessOn,可以在模板库中直接检索「成绩录入活动图」,找到基础模板后替换泳道和节点文字;如果是Visio,使用UML活动图模板,泳道用「垂直泳道」形状。课程设计中活动图一张即可,不需要为每个用例都画,挑有分支和协同判定的流程最能体现建模能力。
4.3 状态图:只画状态多的跨用例对象
状态图不是每个类都要画。学生成绩管理系统中真正有丰富状态的对象是成绩单(Enrollment),它的状态集合可以在一个状态图里完整表达:已选课、在修、成绩已录入、已发布、已申诉、成绩已确认。从已选课到在修由开课事件触发,在修到成绩已录入由教师录入成绩触发,成绩已录入到已发布由教务管理员复核发布触发。已发布状态下学生如果对成绩有异议,系统进入已申诉状态,处理完成回到成绩已确认终态。
状态图的价值在于触发事件与守卫条件,这些条件来自用例规约的前置条件。比如「已选课」到「在修」的转移上可以标注[选课名单确认且学期已开始],这个守卫条件和用例UC-04的选课边界一致。如果状态图里的某个转移条件在用例规约中找不到对应描述,说明需求分析存在缺口,返回第2章补充用例规约。状态图画法上,初始状态用实心圆,终态用实心圆外套空心圆,转移线用带箭头的实线,每一条转移线上至少写清事件名,守卫条件放在方括号内。
5. 组件图、部署图与模型一致性检查:交 doc 前的最后一步
5.1 组件图与部署图合并出图的思路
小规模课程设计不需要单独画两张物理图。常见做法是把组件图和部署图合并成一张B/S架构部署图,同时表达软件组件和硬件节点。节点从上到下画成浏览器节点、Web应用服务器节点、数据库服务器节点。Web应用服务器中驻留成绩管理组件、用户认证组件,数据库服务器中驻留成绩数据库组件与用户数据库组件,节点之间用通信路径连接并标注HTTP或JDBC协议。如果是Java技术栈,可以在Web服务器节点内部用组件形状表示controller包与service包的部署映射,一张图同时满足组件图和部署图的考察点。
5.2 模型一致性检查清单
| 检查项 | 核对内容 | 修正方法 |
|---|---|---|
| 用例规约与用例图 | 每个用例在规约表中有对应条目 | 补充规约或合并删除用例 |
| 用例与动态图 | 至少2个用例在时序图或活动图中出现 | 补画对应场景的动态图 |
| 类图与时序图 | 时序图生命线对象均在类图中存在 | 增加缺失类或调整生命线 |
| 状态图与用例图 | 状态转移事件来源于用例规约 | 改写状态事件或补用例扩展点 |
| 包依赖方向 | service包无反向依赖domain包 | 调整依赖线方向或拆包 |
检查时把五种UML图铺开对照,先用3分钟把每个用例的主流程口头讲一遍,讲不通的地方就是要修改的地方。UML课程设计的评分权重大多在模型一致性与答辩表述上,而不是图形的美观程度,能用图支撑起一条完整流程的论述,这份doc的完成度就已经足够。
5.3 用文本化建模让UML可版本管理
当图的数量超过5张时,推荐使用PlantUML或类似的文本化建模方式维护源文件,按usecase.puml、class.puml、sequence_query.puml命名,生成PNG后插入doc。相比直接改Visio图形文件,文本化方案的最大收益是可以纳入Git管理,每张图的版本变化在diff里一目了然,答辩前调整类图关系也不用担心拖动连线导致图形崩坏。导出命令如下。
plantuml -tsvg class.puml sequence_query.puml -o output/-tsvg生成矢量图格式,Word插入SVG后放大不糊,-o output/指定导出目录。如果要保持文档目录整洁,可以一条命令把所有puml文件批量导出。Visio仍然可以用于最终润色,把PlantUML生成的SVG导入Visio后微调连线,两种工具互补使用。最后一步是把生成的每张图按章节顺序排列,确保第2章的用例图编号和第5章一致性检查表格的用例编号一致,这样整份doc才能形成闭环。
本文还有配套的精品资源,点击获取