
简介软件工程课程中需求分析是决定后续设计与开发质量的奠基性环节。这份实验报告以酒店管理系统为实际案例完整呈现从需求概述到模型构建的分析流程适合软件工程专业学生、课程设计人员以及需要快速掌握UML需求建模方法的开发者。文档基于酒店日常管理场景重点梳理了客房预定与退订、财务管理、员工管理等核心功能模块并分别通过用例图、系统类图、顺序图、状态图等UML工具验证了用例建模、对象建模与动态建模三种主流分析技术在实际项目中的应用方式。压缩包内为单个doc文档共289KB内容涵盖背景说明、部门划分、参与者与用例规格说明、类与属性定义、交互与状态转换等详细建模步骤目录结构清晰便于按模块学习参照。该资源已有78人学习对于正在完成同类课程实验或论文撰写的读者可作为需求分析阶段格式与深度上的有效范本。1. 需求分析不只是写文档一份酒店管理系统实验报告能拆出什么很多软件工程课程的第一次实验作业就是需求分析但不少同学把报告写成了「功能罗列 两张用例图」。这份《软件工程实验报告——需求分析》不一样它把酒店管理系统的需求完整走了一遍从系统需求概述、用例建模、对象建模到动态建模四步都有落地产物。换句话说它不是让你抄一份文档而是让你看完就能照着流程把自己手里的题目也拆成同样的结构。适合两类人一类是正在写课程设计、需要参考需求分析章节怎么组织的人另一类是刚入行、想搞明白「用例图、类图、顺序图之间到底怎么串起来」的初级开发者。接下来我按这个文档的推进顺序逐个环节拆开讲最后落到避坑和验证方法上。2. 从一句话需求到系统边界部门划分与子系统拆分2.1 背景说明里藏着第一道坑部门划分和子系统对不上文档在 1.1 背景说明里写得很清楚酒店管理系统要支持客房预定、退订、退房付款要支持客房状态的查询和修改还要管财务和员工薪水。这些功能听起来都能看懂但到了 1.2 部门划分只给了两个角色——管理者和客房服务部门到 1.3 又突然冒出三个子系统管理者子系统、住宿子系统、财务子系统。这里最容易翻车的地方在于部门划分是组织视角子系统划分是系统视角两者不是一回事。管理者部门既可能操作管理者子系统也可能查看财务统计客房服务部门主要用住宿子系统但退房付款时又和财务子系统有交集。实验报告里没有把这两个视角的映射关系画出来实际交付时评审老师大概率会追问。我一般会补一张映射表把「部门 → 职责 → 对应子系统」三列对齐。拿这份文档来示例部门主要职责对应子系统管理者员工信息录入与删除、客房信息录入管理者子系统客房服务部门旅客信息登记、入住退房时间记录、房间客满统计住宿子系统财务部门隐含收入支出登记、员工薪水管理财务子系统这张表的意义不只是应付评审它能让后面的用例建模直接有据可依——每个用例从哪个角色触发、归属哪个子系统写的时候不会乱。2.2 功能需求拆解把一句话变成可验收的功能点文档 1.3 给了三个子系统的功能描述但描述粒度比较粗。比如住宿子系统写的是「来客登记客人信息{房间号、房间类别、客人名字、证件号码、入住时间、退房时间}」和「房间管理旅客入住对用户信息进行登记并对相应房间数量进行修改」。这种写法作为需求概述没问题但要作为后续建模的输入粒度不够。我在实际项目里会把每个功能点拆成「操作主体 动作 数据对象 结果状态」四元组。拿「退房付款」来拆操作主体前台服务员动作根据客人入住记录计算费用、收款、更新客房状态数据对象入住记录房间号、入住时间、退房时间、房费标准、财务记录发票号、数额、经手人、日期结果状态客房状态从「已入住」变为「可预订」财务表新增一条收入记录这么拆完后面画用例图时每个用例的粒度就自然对齐了——一个四元组就是一条用例的正常事件流。文档里 2.5 提出的辅助需求「酒店客房量 100 间、客房容纳人数 2 人」也要单独记下来这是后面做客房查询和并发预定的硬约束属于非功能需求里最容易漏掉的部分。3. 用例建模从参与者列表到用例规格说明3.1 参与者和用例怎么对应才不会漏文档 2.1 给了三个参与者酒店管理员管理后台数据、员工、客房、前台服务员客户信息管理、客户入住酒店的人。2.2 的用例列表里管理员有员工信息管理、客房管理、登录接待员有登录、客房经营客户有客户信息提供。这里有个关键判断登录到底算不算用例文档里把它列进了用例列表这是实验报告常见的做法——把登录当作一个独立的用例目的是展示系统的认证边界。但在真正的软件工程实践里登录一般建模成「包含include」用例而不是独立业务用例。比如「客房经营」包含「登录」意思是执行客房经营之前必须先完成认证。这块我的建议是实验报告按文档的写法没问题但如果你要把它当项目交付物最好在用例图里用«include»关系把登录挂到其他业务用例下面。这样既保留了认证边界的表达又不会让登录占据业务用例的位置。参与者和用例的映射关系可以整理成表参与者直接关联的用例通过包含关系间接关联酒店管理员员工信息管理、客房管理、登录—前台服务员客房经营、登录客户信息管理客户客户信息提供客房经营触发3.2 用例规格说明的五个要素照着写就不会被挑刺文档 2.4 的用例规格说明格式是标准的六段式用例描述、参与者、前置条件、后置条件、正常事件流、备用事件流。这套格式看着简单真正写得合格的实验报告不多。以「客房经营」用例为例文档的写法是前置条件为「接待员登录系统客户提供信息」后置条件为「接待员将客户信息存入数据库客户拿到入住单」。这条用例的问题在于前置条件的「客户提供信息」不是系统状态没法验证后置条件的「客户拿到入住单」也是业务结果不是数据结果。我一般会把前置条件改成可检查的系统状态断言比如「接待员已登录且客房余量 ≥ 1」后置条件改成数据库层面的结果比如「已插入一条 customer 记录和一条 check_in_record 记录对应客房的剩余量减 1」。下面给一个「客房预订」的规格示例这也正是文档里缺失的那条核心用例要素内容用例名称客房预订参与者前台服务员主、客户辅助前置条件前台服务员已登录系统存在状态为「空闲」的客房后置条件系统创建入住记录客房状态改为「已预订」客户获得预订凭证正常事件流1. 前台服务员查询指定房间类别和入住日期2. 系统返回可预订客房列表3. 前台服务员选择客房并录入客户证件信息4. 系统校验证件并创建入住记录5. 系统将客房状态改为「已预订」备用事件流3a. 客户证件号已存在但入住历史无不良记录直接关联已有客户档案3b. 所选客房状态在查询后被其他订单占用提示重新选择注意备用事件流的写法不是笼统说「操作失败就报错」而是具体到第几步、触发了什么条件、系统怎么响应。这一点评审时加分最明显。3.3 把用例图落到工具里能用脚本生成就别手画实验报告要求画用例图手画费时间还容易改来改去。我习惯用 PlantUML 先生成图再导出图片贴进报告。给出一个与文档用例列表对应的脚本startuml left to right direction actor 酒店管理员 as admin actor 前台服务员 as receptionist actor 客户 as customer rectangle 酒店管理系统 { usecase 登录 as UC_Login usecase 员工信息管理 as UC_Employee usecase 客房管理 as UC_Room usecase 客房经营 as UC_Operation usecase 客户信息管理 as UC_CustomerInfo usecase 客户信息提供 as UC_CustomerProvide } admin -- UC_Login admin -- UC_Employee admin -- UC_Room receptionist -- UC_Login receptionist -- UC_Operation UC_Operation . UC_Login : include customer -- UC_CustomerProvide customer . UC_Operation : triggers enduml这段脚本里的逻辑说明admin -- UC_Employee表示参与者与用例之间是直接关联画实线UC_Operation . UC_Login : include表示客房经营这个用例包含登录是虚线箭头方向从「基础用例」指向「包含用例」容易画反注意箭头方向是从被包含方指向包含方customer . UC_Operation : triggers是我自己加的辅助关系表达客户是客房经营的触发者但并非直接操作系统这种带标签的虚线在实验报告里是加分项因为它能表达参与者之间的间接协作。如果你不想用 PlantUML也可以在 draw.io 里照着这结构画关键是把包含关系和参与者边界表达清楚。4. 对象建模从用例文本反推类、属性和关联4.1 管理类和实体类怎么区分别把「模块」当成「类」文档 3.1 给出的分类是5 个管理类客房管理、用户管理、财务管理、顾客信息管理、酒店管理和 4 个实体类酒店管理员、前台、顾客。这个分类有一个典型的实验报告通病把子系统模块直接当成了类。「客房管理」和「用户管理」更像是业务模块的名字而不是面向对象意义上的类。判断标准很简单类要有属性属性要有值域。技巧是看这个类能不能实例化。「客房管理」能实例化吗它没有独立的实例数据它的数据其实是「客房」这个实体类的属性。所以我一般会做一次名词抽取法把用例规格说明里所有名词圈出来去重后归档。从这个文档的用例文本里抽出来的是员工、客房、入住记录、客户、财务记录、发票号、客房类别……这些才是真正的候选类。不过实验报告的评分标准不一定要求这么严格。文档把管理类和实体类分开列说明作者已经有「控制类 vs 实体类」的意识这是值得保留的。我的建议是在类图里把「客房管理」这样的管理类标注为«control»或«boundary»把「顾客」「客房」标注为«entity»用构造型区分职责这样评审就挑不出毛病。4.2 属性定义与关联多重性直接照文档抄会漏掉两个细节文档 3.3 给了 9 个类的属性清单信息是够用的但有两个关键细节没写全。第一个是属性类型文档只写了属性名没有标类型和约束。比如「客房」类的「剩余量」没有写是整数且不能小于 0「证件号码」没有写格式约束。这个在实验报告里可以简化但至少要养成写类型的习惯。第二个是关联的多重性文档 3.2 列了六条关联描述但表述是文字化的「一个前台管理对应多个入住记录」「一位顾客可以对应多个入住记录」「一个客房在一段时间里会有多个入住记录」。要画成类图需要把这些文字转成多重性标记。整理成表源类关联目标类多重性前台创建并管理入住记录1 — 0..*顾客产生入住记录1 — 0..*客房被记录于入住记录1 — 0..*客房类别规定客房1 — 1..*酒店管理员维护员工1 — 0..*员工前台填写财务记录1 — 0..*这里最容易被漏掉的是「客房类别」那条文档原文说「一个客房规格信息对应多个客房但至少一个」翻译成多重性就是1 — 1..*意思是每个客房必须归属一个类别一个类别下必须有至少一间房。这是数据库里外键约束的基础后面写建表 SQL 时要用到。属性这块我建议按这个模板整理每个类类名、类型实体/控制/边界、关键属性带类型、候选方法。以文档中「客房」类为例类名类型关键属性带类型候选方法客房entity类别号 String、名称 String、设备 String、收费标准 Double、总数量 Int、剩余量 Int、管理人员 String查询可预订房间、修改剩余量入住记录entity房间号 String、入住时间 Date、退房时间 Date、客户证件号 String创建记录、结算费用客房管理control—添加客房、删除客房、修改客房规格注意「客房管理」类的属性是空的——它的职责是操作不是存储数据。这就是前面说的区分点管理类写方法实体类写属性。4.3 系统类图绘制的三个边界画到什么程度算合格画系统类图实验报告里最常见的三个问题我来逐一说明。第一个边界管理类和实体类之间画什么线。管理类对实体类的操作应该画依赖线虚线箭头而不是关联线实线。比如「客房管理」依赖「客房」因为它在方法参数里使用客房对象但不持有客房对象。如果用实线关联说明它长期持有引用这在这里并不成立。第二个边界属性要不要带可见性符号。实验报告里建议带上-表示私有表示公有。酒店管理系统这种场景实体类的属性基本全是私有方法基本全是公有。加上之后图面信息量立刻提升评审印象会好很多。第三个边界类图的范围。只画和当前用例迭代相关的类。这份文档里涉及登录、客房预订、退房三个核心场景那么类图里应该出现的实体类就是员工前台、顾客、客房、入住记录、财务记录。「酒店管理」这个管理类如果画进去它和其他类的关系会很虚我建议要么删掉要么把它标注为系统整体边界。给一个简化版类图的 PlantUML 脚本对应文档里的 9 个类但做了上述规范化处理startuml class 客房 { - 类别号 : String - 名称 : String - 收费标准 : Double - 总数量 : Int - 剩余量 : Int 查询可预订() : List 修改剩余量(amount : Int) : Boolean } class 顾客 { - 证件号码 : String - 姓名 : String - 入住时间 : Date - 退房时间 : Date } class 入住记录 { - 房间号 : String - 入住时间 : Date - 退房时间 : Date } class 员工 { - 员工号 : String - 姓名 : String - 部门号 : String - 职务 : String } class 财务记录 { - 发票号 : String - 数额 : Double - 经手人 : String - 日期 : Date } 员工 1 -- 0..* 入住记录 : 办理 顾客 1 -- 0..* 入住记录 : 产生 客房 1 -- 0..* 入住记录 : 被记录 客房 1 -- 1..* 入住记录 : 对应 enduml这段脚本的要点说明--是实线关联两侧标注多重性每条关联都加了动词办理、产生、被记录、对应避免类图变成一堆方框连线「客房和入住记录」这条关联的语义是每次入住都绑定一个具体客房所以多重性是1 — 0..*表示一个客房可以被多次入住。到这里类图的静态结构就立住了下一步就是动态建模。5. 动态建模与五个高频坑顺序图、状态图的画法纠正5.1 顺序图的生命线、激活条和消息方向照着画不出错文档 4.1 要求画登录、入住、退宿三张顺序图。我以入住为例给一个可以直接套用的 PlantUML 脚本把「前台服务员 客户 系统」的三方交互画出来startuml actor 客户 participant 前台服务员 as receptionist participant 酒店管理系统 as system participant 数据库 as db 客户 - receptionist : 提供证件与入住需求 receptionist - system : 查询可用客房(category, date) system - db : SELECT room WHERE status空闲 db -- system : 可用客房列表 receptionist - system : 选择客房并登记入住(customerInfo, roomId) system - db : INSERT customer, INSERT check_in_record system - system : 更新客房剩余量(status已入住) system -- receptionist : 入住成功提示 receptionist -- 客户 : 交付房卡与入住单 enduml这里的重点有三处。第一消息方向-是同步消息实线实箭头--是返回消息虚线箭头。很多人把数据库返回结果也画成实线箭头这是错的——返回不是一次新的请求它是查询结果的回传。第二激活条PlantUML 里participant后面的对象在执行期间自动带激活条但如果你手画要注意只有收到消息并处理的那段时间画激活条处理完就收起。第三自调用system - system表示系统内部更新客房状态这种表达比把更新逻辑画到数据库消息里更清晰因为数据库只是被动执行。退宿顺序图的画法同理把入住流程反过来客户还卡 → 前台计算费用 → 系统生成财务记录 → 系统更新客房状态为空闲。状态迁移的触发事件要写清楚比如「退房付款完成」之后才从「已入住」迁到「空闲」不能把付款和状态更新画成并行分支否则会出现房还没退就能被下一个客户订走的逻辑错误。5.2 画动态图之前先回答三个问题动态建模容易做得花哨但站不住核心原因是没想清楚就动笔。我每次画顺序图之前会强制自己回答三个问题第一个问题谁是触发者顺序图最左边一定是人或外部系统。入住流程的触发者是「客户」还是「前台服务员」严格来说是客户发起需求前台服务员作为系统操作者执行。所以客户和前台服务员都要出现在图里但只有前台服务员和系统之间有消息交互。第二个问题消息是请求还是返回请求用实线箭头返回用虚线箭头。很多同学把「系统返回可预订客房列表」画成先从系统指向数据库、再从数据库指向系统的实线方向没错但类型错了。返回消息不触发新的处理逻辑它们是配对的一条请求对应一条返回。第三个问题分支画多深实验报告的顺序图不需要把异常路径也画全。文档里的入住顺序图画到「查询可用客房」时如果无房用一条alt分支返回「无空房提示」就够了不需要再画「系统通知客房部」「客房部调整房间」这种二三级分支。画得太深反而让主流程难以辨认。5.3 五个高频坑现象、原因、解决以下五条是我在批改需求分析报告和实际项目评审里反复看到的问题按「现象 → 原因 → 解决」展开。坑一用例图和类图严重脱节。现象是用例图里有「客房经营」类图里却找不到对应的「入住记录」类。原因是建模顺序不对先画了类图再补用例图两边没有对上数据。解决方法是强制做一次映射检查每个用例的正常事件流里出现的每个数据对象必须在类图中有一个类对应。做法是给用例的每个步骤写一个数据足迹比如「前台录入客户证件号」对应「顾客.证件号码」「系统生成入住记录」对应「入住记录」类。这张足迹表能在一小时内排查完所有脱节点。坑二属性写成功能。现象是「客房管理」类的属性列表里写着「添加客房信息、删除客房信息」。原因是把操作动词当成了类的属性。解决方法是记住一个原则属性是名词方法是动词。判断标准是问自己「这个字段存在数据库的哪张表里」如果答不上来那它就不是属性是方法。坑三顺序图的返回消息画成实线。现象是整张图全是实线箭头分不清请求和响应。原因是把「返回结果」理解为「系统主动发起的消息」。解决方法是在画完图之后做一次线条检查从每个对象发出的虚线箭头必须能找到一条配对的实线请求找不到配对的说明消息源画错了。坑四状态图只有状态没有迁移条件。现象是状态图里画了「空闲、已预订、已入住」三个方框但方框之间没有写上触发条件。原因是把状态图理解成了流程图只画了顺序。解决方法是给每条迁移箭头加一个事件标签格式是「事件参数[守卫条件] / 动作」例如客户退房入住记录号[账单已结清] / 客房状态改为空闲。守卫条件必须有它是状态迁移的合法校验没有它系统会允许非法跳转。坑五后置条件不可验证。现象是「后置条件数据正确录入数据库」「后置条件操作成功」。原因是把业务目标写成了后置条件而业务目标无法自动检查。解决方法是把后置条件全部落到可观测的系统状态上。格式是「已新增一条 X 记录字段 Y 的值为 Z客房剩余量减少 1」写成这样测试用例就能直接照着验证。这条我每次评审都会提属于性价比最高的修正项。6. 验证这份需求分析文档的三种方式从纸面走到数据库和接口需求分析文档写完了不能只是画了几张图就收工得想办法验证它是不是自洽的。我常用的一个验证方法是把这份文档当输入推一版数据库建表脚本出来。因为如果类图里的关联能顺畅转换成表结构说明对象建模基本是合格的。下面是一段与前述类图对应的精简建表 SQLCREATE TABLE room ( room_id VARCHAR(10) PRIMARY KEY, category_id VARCHAR(10) NOT NULL REFERENCES room_category(category_id), status VARCHAR(10) NOT NULL DEFAULT 空闲 ); CREATE TABLE customer ( customer_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20) NOT NULL, id_number VARCHAR(20) NOT NULL UNIQUE ); CREATE TABLE check_in_record ( record_id INT PRIMARY KEY AUTO_INCREMENT, room_id VARCHAR(10) NOT NULL REFERENCES room(room_id), customer_id INT NOT NULL REFERENCES customer(customer_id), check_in DATETIME NOT NULL, check_out DATETIME ); CREATE TABLE finance_record ( finance_id INT PRIMARY KEY AUTO_INCREMENT, invoice_no VARCHAR(20) NOT NULL, amount DECIMAL(10,2) NOT NULL, handler VARCHAR(20) NOT NULL, record_date DATE NOT NULL );对照这段 SQL能验证文档里的三个关键结论room 表的外键 category_id 对应文档里那条「一个客房规格对应多个客房但至少一个」的关联这就是1 — 1..*的落地形态check_in_record 表的 customer_id 外键对应「一位顾客可以对应多个入住记录」finance_record 的 handler 字段对应「员工填写财务记录」。如果文档的关联写得不对到这一步就会卡住。第二种验证方法是用角色走一遍完整场景。拿「客户入住」场景顺着顺序图走前台查客房 → 客户提供证件 → 插入 customer 记录 → 插入 check_in_record → 更新客房状态。每一步检查这一步需要的数据是否都能在前面的类属性表里找到。找不到说明类图漏了属性找到了但类型对不上说明属性定义有误。第三种验证方法是文档自身的可追溯性检查。我习惯做一张「需求 → 用例 → 类 → 方法」的追溯表比如需求描述用例涉及类动态图客户办理入住客房经营顾客、客房、入住记录入住顺序图退房时结算费用客房经营入住记录、财务记录退宿顺序图管理者维护员工信息员工信息管理员工不需要这张表做完整理的其实不只是文档还包括自己对需求分析流程的理解。从那以后我每次交需求分析报告之前都强制自己走完一遍「用例 → 类图 → 顺序图 → 追溯表」的闭环任何一个环节接不上就先改报告再交而不是等评审来挑。这套方法不止适用于酒店管理系统换到图书馆管理、教务系统、库存管理都一样成立。希望帮到你。本文还有配套的精品资源点击获取