简介一份围绕“超市进销存系统”开展UML建模的演示文稿面向软件工程学习者、系统设计初学者以及需要完成相关课程设计的学生。内容从销售、库存、订货、统计四个核心业务入手逐步拆解业务场景并用用例图、顺序图、类图和状态图展示建模全过程例如售货员销售流程、库存盘点与报损、订货单状态变化等。通过具体案例帮助读者理解如何从需求描述中识别参与者、用例与实体类并理清边界类、控制类与实体类之间的交互关系。资源为单个pptx文件体积仅369KB便于快速浏览和对照练习。目前已有271人学习下载适合作为UML建模课程配套参考或项目设计前的思路梳理工具。1. 为什么“超市进销存系统进行UML建模”不是画几张图那么简单软考中级的案例题和课程设计里经常能看到“超市进销存系统进行UML建模”这类标题。它看着像是把用例图、类图、顺序图各画一张再往PPT里一贴就能交差但真正做起来就会发现评审问的第一句话往往是“你这个用例图里的参与者为什么有六个”“采购单和采购明细为什么画的是聚合而不是组合”。建模最难的从来不是画图而是把业务边界、对象职责、状态流转一字不差地对齐。这篇文章就是按我平时交付这种设计说明的思路从用例图一路做到状态图每一步都给出能直接抄到PPT里的图表结构、参数和验收标准。适合正在备考软考中级、做课程设计或者要给客户讲系统设计方案的工程师。2. 先定业务边界用例图与活动图把进销存拆干净2.1 角色先于用例超市进销存系统到底有哪几类人画用例图最容易翻车的地方不是不会画而是不知道把谁画成参与者。很多人直接把组织架构图抄过来店长、副店长、值班店长、采购员、收银员、理货员、仓管、财务全部堆在用例图左边结果用例图变成通讯录。UML里的参与者Actor是“与系统交互的角色”不是职位。同一职位的人在不同场景下可以扮演不同角色反过来不同职位的人如果跟系统的交互方式完全一样也应该合并成一个角色。我一般先列一张“角色与核心用例”清单再动手画图。超市进销存系统常见的角色就五类店长、采购员、收银员、仓库管理员、系统管理员。店长负责商品资料维护、采购审核、查看进销存报表采购员发起采购申请、维护供应商信息收银员做前台收银和退货处理仓库管理员做入库验收、库存盘点、库存调整系统管理员管权限分配和日志。把这张表先写出来用例图就是按表填图。角色核心用例说明店长商品资料维护、采购审核、进销存报表管基础数据与经营决策采购员采购申请、供应商维护发起进货收银员前台收银、退货处理门店销售仓库管理员入库验收、库存盘点、库存调整管实物与账面库存系统管理员权限分配、日志查看、数据备份系统运维下面是用 PlantUML 画用例图的源码适合直接维护成版本化文本再导出图片放进PPT。注释里的内容对应上面的清单。startuml left to right direction skinparam shadowing false actor 店长 as boss actor 采购员 as buyer actor 收银员 as cashier actor 仓库管理员 as keeper actor 系统管理员 as admin rectangle 超市进销存 { (商品资料维护) as P1 (采购申请) as P2 (采购审核) as P3 (入库验收) as P4 (前台收银) as P5 (退货处理) as P6 (库存盘点) as P7 (进销存报表) as P8 (权限分配) as P9 } boss -- P1 buyer -- P2 boss -- P3 keeper -- P4 cashier -- P5 cashier -- P6 keeper -- P7 boss -- P8 admin -- P9 enduml这段源码里的left to right direction会让参与者显示在图左侧用例横向排列适合PPT页面比例。skinparam shadowing false去掉阴影导出图片在投影上更干净。我给用例命名时一律用“动词宾语”比如“采购审核”而不是“审核功能”因为用例的价值是描述角色能获得什么结果不是描述系统有什么功能。如果你的PPT受众是软考中级阅卷或答辩评委还要在用例图旁边补一行文字每个用例对应一个业务事件。比如“采购审核”的事件是“店长收到采购申请后确认是否下单”这个事件就是后面活动图和顺序图的起点。用例图不负责画流程只负责说清楚边界哪些事在这个系统里做哪些事不做。2.2 活动图要画“泳道”一次进货从申请到入库的全过程用例图定了“什么人能做什么”活动图要回答“这件事具体怎么走”。很多初学者把活动图画成普通流程图一个开始节点、一串处理框、一个结束节点完全没有角色区分。这种图在PPT评审时基本扛不住追问因为看不出每一步到底由谁负责。超市进销存系统建议画三张活动图采购入库、销售出库、库存盘点。每张都用泳道Swimlane把参与对象隔开。以采购入库为例参与对象是采购员、店长、供应商、仓库管理员、系统。这里供应商虽然是外部角色但它是采购流程里不可跳过的一环必须画进泳道否则“验收”这个动作没有来源。startuml |采购员| start :查询库存; if (库存不足?) then (是) :填写采购申请单; else (否) stop endif |店长| :审核采购单; if (审核通过?) then (是) :通知供应商发货; else (否) stop endif |供应商| :发货; |仓库管理员| :收货并验收; if (验收合格?) then (是) :登记入库单; :更新库存; else (否) :生成退货单; endif |系统| :记录操作日志; stop enduml这段活动图里|采购员|是泳道分隔它后面的处理框都落在对应泳道内。if (库存不足?) then (是)是判断节点活动图允许用判断节点表达分支。最关键的一段是“验收合格”分支合格走“登记入库单→更新库存”不合格走“生成退货单”。这两条路径都必须在图里存在否则评审会问“收货时发现商品破损怎么办”。绘制活动图时有几个参数要养成习惯状态节点用圆角矩形判断节点用菱形并发用同步条横杠。PlantUML 里用fork和join表达并发比如“登记入库单”和“更新库存”其实可以并行但我建议在PPT上串行画因为进销存系统里入库单登记完才允许库存变化串行更符合事务边界。活动图的层次也不要太深控制在三方泳道以内、15个节点以内放一页PPT刚好能看清。如果流程超过这个规模就拆成多张图不要硬挤。2.3 把用例图和活动图组织进PPT先讲清单再讲流程用例图和活动图在PPT里不能孤立摆放。我一般会在一页里放用例图旁边配一张“角色职责表”讲的时候先念表格再顺着用例图里的连线指一遍活动图单独一页下方配三行文字版主流程比如“申请→审核→发货→验收→入库”。这样即使投影仪分辨率不高听众也能从文字里跟上逻辑。这里有个容易被忽略的细节活动图里“更新库存”是系统做的不是仓库管理员做的。仓库管理员只是触发这个动作。落到类图和顺序图阶段这个动作会被分配到一个控制类的方法上。如果活动图阶段不区分“人工动作”和“系统动作”后面的对象职责就会乱。3. 静态结构建模类图与包图把概念钉成对象3.1 从用例中“提取”类实体类、控制类、边界类用例图和活动图解决的是“业务怎么流转”类图解决的是“系统里有哪些对象、对象之间什么关系”。很多初学者一上来就把数据库表转成类商品表变商品类库存表变库存类字段原样搬上去方法只写get/set。这样做出来的类图只是一个ER图的翻版完全没有面向对象设计的信息。我习惯把类分成三层边界类、控制类、实体类。边界类负责与用户交互比如登录窗口、采购录入界面、收银界面控制类负责业务逻辑和事务比如采购控制器、销售控制器、库存控制器实体类负责持久化的业务数据比如商品、供应商、采购单、采购明细、销售单、销售明细、库存、会员。这个划分对应UML里的“分析类”概念PPT里明确标出这三层评审一眼就能看出你不是在画表格。类别职责代表类边界类与用户或外部系统交互登录界面、采购录入界面、收银界面控制类业务逻辑、事务控制、流程编排采购控制器、销售控制器、库存控制器实体类业务数据及其生命周期商品、供应商、采购单、采购明细、库存下面这个类图覆盖了进销存系统的核心静态结构。注意类图里每个类只保留最少必要属性并写上业务方法而不是get/set。startuml class 商品 { - 商品ID: String - 名称: String - 规格: String - 进价: BigDecimal - 售价: BigDecimal 按条码查询(): 商品 修改售价(): void } class 库存 { - 仓库ID: String - 数量: int - 预警下限: int 入库(数量): void 出库(数量): void 检查预警(): boolean } class 采购单 { - 单号: String - 供应商ID: String - 状态: String - 下单时间: Date 创建(): void 审核(): void 收货(): void } class 采购明细 { - 商品ID: String - 数量: int - 进价: BigDecimal } class 销售单 { - 单号: String - 会员ID: String - 金额: BigDecimal - 状态: String 创建(): void 支付(): void 退货(): void } class 销售明细 { - 商品ID: String - 数量: int - 单价: BigDecimal } class 供应商 { - 名称: String - 联系人: String - 电话: String } 商品 1 -- 1 库存 : 对应 采购单 1 *-- 1..* 采购明细 : 包含 商品 1 -- 0..* 采购明细 : 被采购 销售单 1 *-- 1..* 销售明细 : 包含 商品 1 -- 0..* 销售明细 : 被销售 供应商 1 -- 0..* 采购单 : 供货 enduml这段代码里*--是组合关系表示采购明细不能脱离采购单存在采购单删了明细一起删。--是关联关系商品和库存是独立对象只是存在对应关系。1、0..*、1..*是多重性读法是“一个采购单包含一至多条采购明细”“一个商品可以出现在零至多条采购明细里”。画类图时先画关系再补属性方法顺序不能反过来。3.2 类图要画关系而不是画字段关联、聚合、组合怎么分评审最爱问的一个问题是“你这里为什么用的是组合而不是聚合”。区别在于部分能否脱离整体独立存在。采购明细离了采购单没有任何业务含义所以是组合而货架可以离开某个仓库单独存在那就是聚合。超市进销存系统里最典型的组合关系就是单据和单据明细采购单与采购明细、销售单与销售明细全部用组合。商品和库存之间用关联因为商品可以没有库存记录库存记录也可以独立调整。依赖关系在类图里经常被忽略但它很重要。比如销售控制器在“收银”操作里会调用商品类的“按条码查询”方法销售控制器依赖商品类画成虚线箭头。这个关系在代码层面对应“方法的参数、返回类型或局部变量里使用了对方”。如果PPT里能画出几个依赖关系说明你不是只考虑了数据存储还考虑了调用方向。属性字段不要贪多。一个类画四到六个属性足够关键是字段名要统一。有人类图里叫“商品ID”用例图里叫“商品编号”数据库设计里叫goods_id评审会觉得你没做统一建模。我一般会在PPT前面加一页术语表把所有核心名词统一成一套商品、采购单、采购明细、销售单、销售明细、库存、供应商、会员后面所有图都只允许用这几个词。3.3 包图等于PPT的导航目录七个包让系统结构一眼看懂包图不是必须画的但画了能大幅提升PPT的说服力因为它展示的是系统的模块划分。超市进销存系统我习惯分成七个包登录与权限、基础数据、采购管理、销售管理、库存管理、报表统计、系统管理。包与包之间要保持单向依赖比如采购管理依赖基础数据因为采购单要引用商品和供应商信息报表统计依赖采购管理和销售管理因为报表要汇总单据数据。包图的原则是“不允许出现环状依赖”。如果采购管理和销售管理互相依赖说明模块边界没划清。真实项目里可以通过引入中间层或者事件解耦来打破环但课程设计和软考答题里直接画成严格的单向依赖就够了。包图画完PPT后面讲类图时就有了章法每一页类图对应一个包。4. 动态行为建模顺序图与状态图让逻辑可推演4.1 顺序图以“前台收银”为例把一条消息链路走通静态结构图类图画完评审会问“这些对象是怎么协作的”。顺序图回答的就是这个问题谁发消息、谁处理、结果怎么返回。超市进销存系统里前台收银是最值得画顺序图的场景因为它跨越了边界类、控制类、实体类三层还涉及库存扣减这个事务点。画顺序图之前先确定参与对象不要把所有类都拉进来。收银场景只需要收银员、收银界面、销售控制器、销售单、商品、库存这六个对象。顺序图的原则是只画关键消息一条业务流程控制在八个消息以内超过就拆图。下面的例子演示了从扫描商品到预占库存的完整链路。startuml actor 收银员 participant 收银界面 as ui participant 销售控制器 as ctrl participant 销售单 as order participant 商品 as product participant 库存 as stock 收银员 - ui : 扫描商品条码 ui - ctrl : 查找商品(barcode) ctrl - product : 按条码查询(商品ID) product -- ctrl : 返回商品信息 ctrl - order : 添加明细(商品, 数量) order -- ctrl : 返回明细行 ctrl - stock : 预占库存(商品ID, 数量) stock -- ctrl : 预占成功 ui -- 收银员 : 显示商品与金额 enduml顺序图里的实线箭头是同步消息表示调用方要等被调用方处理完虚线箭头是返回消息必须成对出现。很多人只画实线不画虚线画出来的顺序图像单向流程图评审一看就觉得你漏了返回值。查找商品(barcode)括号里的内容是消息参数返回消息上用中文注明返回值比如“返回商品信息”。这一步在PPT里很加分因为体现出了“调用有入参有出参”。如果要在顺序图上体现事务边界我会在“预占库存”旁边加一个注释扣减库存和生成销售单明细必须放在同一个事务里任一失败则全部回滚。这个注释不需要画成正式的事务边界符号但一定要写因为进销存系统最怕的就是“销售单生成了库存却扣失败”。4.2 状态图给采购单和库存画生命周期状态图只针对有“状态”的实体不是所有类都要画。采购单、销售单、库存、会员是进销存系统里四个有生命周期的对象。其中采购单最典型从草稿到已结算中间要经过审核、收货、结算多个环节每个环节还可能有驳回和取消。状态图画得好不好直接决定PPT里“业务规则”这一部分有没有说服力。画状态图的步骤是固定的先列状态再列事件最后画转换。采购单的初始状态是草稿提交后变待审核店长审核通过与驳回是两个事件驳回回到草稿审核通过后第一次收货进入部分收货状态全部收完才到已收货已收货之后是已结算。同时不能漏掉作废路径草稿直接作废、已审核后全部退货都会进入已取消状态。startuml [*] -- 草稿 草稿 -- 待审核 : 提交 待审核 -- 草稿 : 驳回 待审核 -- 已审核 : 审核通过 已审核 -- 部分收货 : 第一次收货 部分收货 -- 已收货 : 最后一次收货 已收货 -- 已结算 : 财务结算 草稿 -- 已取消 : 作废 已收货 -- 已取消 : 全部退货 已取消 -- [*] 已结算 -- [*] enduml状态图里每个转换的冒号后面写的是“事件名”不是“结果”。比如“驳回”是事件“回到草稿”是结果。事件名要用业务语言不要写成方法名比如“财务结算”而不是“doSettle”。状态图的完整性可以这样自查对每个非终止状态问一句“用户不想继续了怎么办”“数据错了怎么办”。能答出“作废”和“退货”状态图才算闭环。4.3 顺序图与协作图二选一别凑页数UML里协作图和顺序图表达的信息是等价的只是视角不同顺序图强调时间顺序协作图强调对象间的连接关系。PPT里只需要选一种。我一般只画顺序图因为顺序图有清晰的时间轴答辩时讲起来线性、不容易乱只有当评审明确提出要看对象间结构时才补一张协作图。为了凑页数两种都画反而让人觉得你分不清它们的关系。5. 避坑清单UML建模PPT里最常见的5个翻车点5.1 参与者画成“职位”而不是“角色”现象用例图左侧出现“店长、副店长、值班店长、财务主管”一排角色实际用例却完全一样。评审问“副店长和店长的权限差异是什么”答不出来整张图的可靠性被质疑。原因直接把组织架构的职位表抄进了UML没理解参与者是“与系统交互的角色”。同一职位在不同流程里可能扮演多个角色多个职位如果交互完全相同也应该合并。解决用例图只保留五类角色店长、采购员、收银员、仓库管理员、系统管理员。如果确实存在权限差异用泛化关系表达比如“系统管理员”泛化成“店长”表示店长继承系统管理员的全部权限再扩展经营权限而不是并列画两个角色。5.2 类图画成了数据库表现象商品类里十几个字段库存类里也有库存ID、商品ID、仓库ID、数量、预警值、创建时间、修改时间方法全部是get和set。整张类图的信息量和ER图没有区别看不到任何业务行为。原因画图前先打开了MySQL建表脚本照着表结构搬类。面向对象的类是“职责封装”不是数据容器。解决先写行为再补字段。商品类只保留商品ID、名称、规格、进价、售价五个属性方法写“按条码查询”“修改售价”库存类只保留数量、预警下限方法写“入库”“出库”“检查预警”。方法名必须面向业务不能面向数据库操作。5.3 顺序图只有“向下调用”没有任何返回消息现象顺序图一排实线箭头从actor指到底部实体类没有一条虚线箭头。讲PPT时说到“预占库存”环节听众不知道这个操作有没有成功后面“显示商品与金额”就显得没有依据。原因画图时只考虑了方法调用方向忘了返回值一样是需要建模的消息。有些人把顺序图想成了“流程图”以为箭头只是流程走向。解决每个同步调用后面都补一条返回消息。查询类消息返回查询结果写操作消息返回“成功/失败”。如果消息超过八条说明顺序图粒度太粗或太细拆成“主请求消息”和“子请求消息”用编号1、1.1、2表达嵌套调用。5.4 状态图漏掉“取消/驳回/异常”路径现象采购单状态图画了草稿→待审核→已审核→已收货→已结算这条完美路径评审问“审核不通过怎么办”“货全退了怎么办”图上没有任何出口。原因只画了业务流程的主线没画分支路径。UML状态图的完整性要求每个状态都要有进入和离开路径正常路径之外的失败路径也必须建模。解决画完主路径后逐个状态问三个问题这个状态能取消吗能驳回吗数据错了怎么回退至少补上待审核→草稿驳回、草稿→已取消作废、已收货→已取消全部退货三条路径。5.5 包含和扩展关系乱用现象用例图里把“登录”画成所有业务用例的include整张图密密麻麻全是登录箭头。评审问“为什么要包含登录”得到的解释是“因为不登录不能用”这属于对包含关系的误用。原因把“功能的前置条件”当成了“包含关系”。登录是系统级横切关注点不是某个业务用例的组成部分如果登录失败这些用例根本不会启动这属于前置条件画在用例说明里即可。解决业务用例图里不画登录。单独画一张“登录与权限”用例图参与者是系统管理员和普通员工用例是身份认证、权限校验、密码修改。业务用例的说明里写一行前置条件“用户需已完成身份认证”。6. 交付前用一致性检查表自测把UML图变成能讲十分钟的方案最后一件事不是画新图而是做一致性检查。UML建模里最隐蔽的问题就是图与图之间互相矛盾用例图里的参与者叫“仓库管理员”活动图里写成“仓管员”类图里根本没有对应的边界类评审翻一遍就能看出来每个图各讲各的。我一般会在PPT倒数第二页放一张一致性检查表也用它给自己验收。检查项核对规则参与者一致性用例图、活动图泳道、顺序图actor里的角色名完全一致类一致性类图里的每个实体类都能在顺序图中找到实例或消息状态一致性状态图里的事件名与活动图里的判断分支一一对应边界一致性边界类与参与者之间存在交互控制类不直接接触界面词条一致性商品/采购单/销售单/库存/供应商在全部图中命名统一PPT页面分配我习惯这样排第1页放标题与术语表第2页放角色职责清单第3到5页放用例图第6到7页放活动图第8到12页放类图与包图第13到15页放顺序图第16页放状态图第17页放一致性检查表。按这个结构讲十分钟到十五分钟正好不会讲不完。如果是在软考中级备考场景还要给每张图配两到三句“看图说话”。比如类图里的组合关系“采购明细与采购单同生共死”状态图里的“驳回后回到草稿采购单可以修改后再提交”。这些解释不是图上的文字而是讲述时的口头内容能体现你真的理解建模逻辑。我的习惯是先用PlantUML维护全部图的源码改图只改文本再批量导出图片贴进PPT。这样评审提出修改意见时不用抓着PPT里的图形手动挪改完源码重导出就行。一致性检查表也留在源码目录里每次改完图跑一遍再更新PPT。这套流程多花十分钟但能省掉后面改版的大把时间希望帮到你。本文还有配套的精品资源点击获取