ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

图书馆管理系统UML建模:用五类图理清需求、流程与类职责

图书馆管理系统UML建模:用五类图理清需求、流程与类职责 简介这份资料围绕图书馆管理系统的UML建模设计展开面向软件工程课程设计、系统分析与设计学习者及需要绘制标准图形化文档的开发者。内容完整覆盖用例图、活动图、类图、时序图与状态图并结合借书、还书、罚款、预订等典型业务场景对各图的角色、流程和类间关系做了逐项说明可直接用于课程报告、毕业设计或项目文档参考。资源包共1个doc文件大小约375KB文档结构清晰既有需求分析和功能模块划分也附有借书时序图、罚款时序图等关键图表的文字解说便于读者对照学习UML在管理信息系统中的实际建模过程。目前已有9000余人学习下载适合需要快速理解图书馆管理系统建模思路并获取完整设计说明的学习者。1. 从一份课程设计 doc 说起图书馆管理系统 UML 建模在画什么很多人下载这份 doc 的时候以为能直接跑起一个图书馆管理系统打开才发现里面是五类 UML 图用例图、活动图、类图、时序图和状态图。这恰恰是它最容易被低估的地方。图书馆管理系统这个题目难点不在业务代码而在于如何把借书、还书、预订、罚款这些流程用不同视角的图表达成一套不自相矛盾的模型。这份 doc 相当于一个完整可改的建模蓝本需求分析、角色整理、类与方法命名、状态迁移规则都摆在那里。适合做软件工程课程设计、UML 入门练习以及备考系统分析师时拿来对照使用。2. 需求到用例图先把角色边界和用例关系立住2.1 管理员与读者两类参与者的用例怎么拆用例图解决的第一个问题是“系统为谁服务、提供哪些功能”。它不是详细设计画到每个操作按钮那种粒度就过头了。这份 doc 的顺序是对的——先写需求分析再画用例图角色和用例都是从需求里直接抽出来的不会出现“用例里有但需求里没有”的悬空功能。拿这份 doc 复现时第一步不是打开画图工具而是把需求分析里出现的角色先列一遍。管理员侧用例是登录系统、书籍管理、书籍借阅管理、读者管理、自动借书机管理读者侧用例是登录系统、借书、还书、查询、预订、逾期处理、书籍丢失处理、自动借书机使用。关键点在于借书、还书、预订、逾期处理这些业务管理员侧和读者侧都存在但视角完全不同。读者是业务发起人管理员是业务执行人。如果硬把两个角色塞进同一个用例就会出现“借书到底归谁”的争论正确做法是让一个用例同时连接两个参与者或者干脆分成两张图来画。下面的 PlantUML 代码用的是第一种方式让共用用例被两个参与者同时引用。startuml 图书馆管理系统用例图 顶层用例图管理员与读者按权限拆分 left to right direction actor 管理员 as admin actor 读者 as reader rectangle 图书馆管理系统 { usecase 登录系统 as UC1 usecase 书籍管理 as UC2 usecase 书籍借阅管理 as UC3 usecase 读者管理 as UC4 usecase 自动借书机管理 as UC5 usecase 借书 as UC6 usecase 还书 as UC7 usecase 查询 as UC8 usecase 预订 as UC9 usecase 逾期处理 as UC10 usecase 书籍丢失处理 as UC11 usecase 自动借书机使用 as UC12 admin -- UC1 admin -- UC2 admin -- UC3 admin -- UC4 admin -- UC5 reader -- UC1 reader -- UC6 reader -- UC7 reader -- UC8 reader -- UC9 reader -- UC10 reader -- UC11 reader -- UC12 } enduml代码逻辑usecase 后面的名称要和需求文档里的功能名保持一致否则后面做时序图和类图时找不到对应关系。自动借书机拆成“管理”和“使用”两个用例是因为管理员和读者对它的操作权限完全不同合并成一个会让权限边界变模糊。参数说明actor 声明参与者rectangle 定义系统边界usecase 定义用例-- 表示参与者与用例之间的关联关系。文档原文把“书籍借阅管理”整体算作一个用例实际画的时候拆成借书、还书、预订、逾期、丢失五个子用例更接近底层实现。2.2 include 与 extend借书、预订、逾期处理的关系怎么定用例图画出来后下一步是补关系。区分 include 和 extend 有一条实用准绳如果 A 用例执行时B 的步骤必然发生用 include如果 B 只在特定条件下才触发用 extend。借书时序图的第一个动作是 login()说明登录是借书流程里的必做步骤所以“登录系统”和“借书”之间适合画 include。而“逾期处理”只有在还书扫描发现超期时才出现属于条件分支适合画 extend“预订”同理只有书籍已经被预订时才会在借书流程里触发取消预订的动作。startuml 借书相关用例关系 include 表示必做步骤extend 表示可选分支 usecase 借书 as borrowUC usecase 登录系统 as loginUC usecase 查询 as queryUC usecase 预订 as reserveUC usecase 逾期处理 as overdueUC borrowUC .. loginUC : include borrowUC .. queryUC : include borrowUC .. reserveUC : extend borrowUC .. overdueUC : extend enduml为什么把“查询”也放进 include因为借书前必须确认书目信息文档里 gettitle 就是查询动作不查就没法继续。写 include 时虚线箭头指向被包含的那个用例阅读顺序是“借书”包含“登录”和“查询”。这套关系理清后后面画活动图时每个分支条件都能直接搬过来不会漏掉“被预订”这个判断节点。也正因为预订和逾期是扩展分支类图里的 Reservation 类和罚款逻辑才与 borrow 主流程保持松耦合。2.3 用例与五个子系统的对应防止用例图失控文档在一开始列了五个子系统基本业务功能、基本数据录入、信息查询、数据库管理、帮助功能。用例超过十个时如果不做归纳图面会被交叉线塞满。我一般在用例图之外整理一张用例-子系统映射表既方便答辩讲解也方便自己检查有没有遗漏需求。子系统对应用例基本业务功能借书、还书、预订、自动借书机使用基本数据录入书籍管理、读者管理信息查询查询数据库管理逾期处理、书籍丢失处理、借阅信息管理帮助功能登录系统含用户授权信息、获取帮助表里“获取帮助”在文档的需求清单里没有明确用例原文只提了一句“帮助功能子系统”。实际操作时我建议在读者侧补一个“获取帮助”用例或者用注释标注否则这个子系统的存在没有用例承接评审时容易被追问。这张表同时也为后面的覆盖矩阵打底每个用例都必须落到活动图、时序图或类图里缺一个模型就不闭环。3. 时序图与状态图把消息顺序和对象状态钉死3.1 借书时序图九个消息的顺序怎么定时序图的价值在于体现“调用-返回”和“条件分支”。我见过有人把借书流程画成读者、管理员、系统、数据库四条生命线一条直线走到底没有任何返回消息那其实是活动图的变体不是时序图。时序图必须回答一个问题谁在什么时刻调用了谁的哪个方法。文档的借书时序图给出了九个函数login登录、checkstu_card验证读者卡、showinformation显示读者信息、borrow借书、getreaders获取读者信息、gettitle获取书目信息、getreservation检验是否被预订、getnoreservation确认无预订、create创建外借记录。顺序很讲究先验证读者身份再确认读者有借书资格然后查书最后检查预订并创建借阅记录。注意 borrow 和 create 是两个动作borrow 是读者发起借书请求create 才是系统真正生成借阅记录建模时把这俩合并后面代码设计就会少一层接口。startuml 借书时序图 借书流程九个核心消息先验证读者再查书目 actor 读者 participant 管理员终端 as admin participant 系统 as sys participant 数据库 as db 读者 - admin : 提交书籍与借书证 admin - sys : login() admin - sys : checkstu_card() sys - db : getreaders() db -- sys : 读者借书资格 sys -- admin : showinformation() admin - sys : borrow() sys - db : gettitle() db -- sys : 书目信息 sys - db : getreservation() db -- sys : 预订状态 alt 未被预订 sys - db : getnoreservation() sys - db : create(borrower, item) db -- sys : 外借记录已创建 end enduml这段代码里我加了“数据库”这条生命线文档原本没有显式画它。不加的情况下getreaders 和 gettitle 会让人误以为是系统内部方法后面类图里就找不到数据来源。参数说明actor 是发起点participant 是参与对象实线箭头表示同步调用虚线箭头表示返回alt 表示条件分支。后面做类图时create(borrower, item) 的方法签名可以直接放到 borrow 类里这就是时序图向类图的输出。3.2 还书与罚款时序图分支要显式画出来文档把还书和罚款拆成两张时序图还书只给了三个函数login、getitem、update。这样拆的优点是图面干净缺点是把一条完整业务流程砍成了两段。更贴近业务的做法是把罚款作为 alt 分支合并进还书时序图扫描书籍、判断是否过期过期则先交罚款再统一更新借阅信息。startuml 还书与罚款时序图 还书流程超期的书走罚款分支后再更新 actor 读者 participant 管理员终端 as admin participant 系统 as sys participant 数据库 as db reader - admin : 归还书籍 admin - sys : login() sys - db : getitem() db -- sys : 书籍条目信息 alt 书籍已过期 sys - db : 计算罚款(过期天数) db -- sys : 罚款金额 reader - admin : 缴纳罚金 admin - sys : 确认收款() end sys - db : update() db -- sys : 借阅信息已更新 endumlalt 是时序图画分支的关键字把“过期”和“未过期”两条路径分开。文档写“过期天数和罚款金额由系统自动计算”在图上对应“计算罚款”这个动作传参是过期天数返回值是金额。update 这个名字在借书、还书、罚款三张图里都出现复现时要把类图里的 update 方法定义清楚比如归还书籍后调用的是 updateBorrowRecord()更新读者信息的是 updateReader()别让一个 update 管所有事。3.3 书籍状态图五个状态和迁移事件状态图与前面几种图最大的区别是它表达的是对象在事件驱动下的状态变化而不是某个流程步骤。文档给出了书籍的五种状态新加书籍、在库、预订、借出、可用。按文档描述书籍先进入“新加”状态入库登记后变为“在库”“在库”可以预订、可以外借“预订”状态下也可以外借超出预订期限则转“可用”取消预订也转“可用”外借归还后也转“可用”。这里有个建模取舍“在库”和“可用”在字面上接近但保留这两个状态更合理——“新加书籍”还没进入可借池“可用”是归还或取消预订后的再入池状态合并成一个会让“新加”动作没有落点。startuml 书籍状态图 书籍生命周期五状态事件驱动状态迁移 [*] -- 新加书籍 新加书籍 -- 在库 : 入库登记 在库 -- 预订 : 读者预订 在库 -- 借出 : 借书通过 预订 -- 借出 : 外借成功 预订 -- 可用 : 取消预订 预订 -- 可用 : 超过预订期限 借出 -- 可用 : 归还 可用 -- 在库 : 重新上架 enduml状态图里的每条迁移都必须带触发事件没有事件的转移是无效模型。预订状态的两个出方向都到“可用”但触发事件不同一个是读者主动取消一个是系统定时任务扫描超期落到代码里就是两个方法。文档原文对“取消预订”只提了一句但状态图必须补上这条迁移否则系统的取消预订功能在模型层面没有出口。迁移核对表如下。当前状态事件目标状态新加书籍入库登记在库在库读者预订预订在库借书通过借出预订外借成功借出预订取消预订可用预订超过预订期限可用借出归还可用可用重新上架在库4. 活动图与类图从业务流程落到类职责4.1 活动图泳道和分支让流程可执行活动图的任务是把用例展开成可执行的流程它和时序图的区别在于关注点不同时序图画的是对象之间发消息的顺序活动图画的是流程怎么走、在哪些节点要作出判断。文档里的借书活动图描述得很细扫描借书证、检验是否符合条件、检查借书数量上限、检查过期情况、扫描书籍条形码、检查是否可借或已预订、更新书目和读者信息。startuml 借书活动图 泳道区分角色职责每个判断点必须成对处理 |读者| start :提交书籍与借书证; |管理员| :扫描借书证; if (读者符合借书条件?) then (是) :扫描书籍条形码; if (书籍可借?) then (是) :更新书籍信息; :更新读者借阅信息; stop else (否) :提示不可借; stop endif else (否) :提示借书失败; stop endif enduml|读者| 和 |管理员| 是活动图的泳道哪个角色做哪个动作一目了然。start 和 stop 之间只保留一个入口和一个出口if 后面的 then 和 else 必须成对否则流程图走不完。这份文档还书活动图带了罚款分支预订活动图带了“检查是否已被预订或外借”分支画法和这个模板一样。如果只能提醒一条经验那就是每个 if 语句在图上都要有“是”和“否”两个出口只画成功路径的活动图拿去评审一定会被问“失败了怎么办”。4.2 类图七个类怎么从需求和图里长出来类图是整套建模的收口。文档给出了七个类reader读者、admin管理员、Title书目、Item具体书籍、borrow借阅信息、Reservation预订信息、persistent store持久存储。这些类不是凭空出现的而是从前面几张图里推导出来的。reader 类的属性包括 reader_id、reader_Name、Address、class、borrowed操作有 addborrowed、deleteborrowed、reservationTitle 类记录 name、author、book_idItem 类有 id 和 reserve、find_on_title 操作borrow 类记录 ISBN 和 dateReservation 类记录 date、ISBN、UserID。借书用例产生了 borrow 类预订用例产生了 Reservation 类书籍管理用例产生了 Title 和 Item 类系统管理用例产生了 admin 类。startuml 类图 业务类来自用例图与时序图persistent store 作为统一存储接口 class reader { -reader_id : String -reader_Name : String -Address : String -class : String -borrowed : ListItem addborrowed() deleteborrowed() reservation() } class admin { -admin_id : String -admin_Name : String addBook() deleteBook() updateBook() addReader() deleteReader() } class Title { -name : String -author : String -book_id : String } class Item { -id : String reserve() find_on_title() } class borrow { -ISBN : String -date : Date create(borrower, item) update() } class Reservation { -date : Date -ISBN : String -UserID : String } class persistent store { store() load() } reader 1 -- 0..* borrow Item 1 -- 0..1 borrow reader 1 -- 0..* Reservation Item 1 -- 0..* Reservation Item * -- 1 Title persistent store .. borrow : 存取借阅记录 enduml画类图最怕的是箭头画反。这里 reader 和 borrow 是实线关联因为 reader 类里直接持有 borrowed 列表Item 和 borrow 是 1 对 0..1 关联一本书最多只有一条在借记录Item 和 Title 是多对一多本具体的书对应同一条书目信息Reservation 同时关联 reader 和 Item但它和 borrow 是并列关系不是继承关系。UML 类图里常见的几种箭头含义对照如下。符号含义本项目中的应用实线加箭头关联长期持有的关系reader 到 borrow虚线加箭头依赖临时使用的关系persistent store 依赖 borrow空心三角加实线继承本项目未使用菱形加实线聚合整体与部分可把 Title 视为 Item 的聚合容器admin 类和 reader 类之间没有直接关联这是对的。管理员操作读者信息是后台动作不是业务流程里的对象间交互。很多人画类图习惯性地把 admin 和 reader 连一条线反而把业务关系搞混。如果你习惯用 StarUML 画类图画完一定要检查每条关联线的线型和方向StarUML 里同样一条线可以右键切换关联、聚合、依赖三种类型切换后视觉差异很小语义差很远。4.3 persistent store被低估的存储抽象persistent store 是整套类图里唯一跳出业务对象之外的类。文档原话是“其他与书籍有关的活动都要经过其存储类”这句话的分量很重借书要经过它更新外借记录还书要经过它更新书目条目罚款也要经过它更新借阅信息。如果没有这一层borrow、Reservation、Item 三个类都得各自对接数据库类之间的耦合会明显上升。它对应的是数据访问层接口而不是某一张具体的表。后续做数据库设计时可以从它派生出图书表、读者表、借阅表、预订表但类图阶段先保留抽象不要在业务类里写 SQL。我一般会在 persistent store 的说明里加一句“对存储介质的访问统一走该类”答辩时这句话能解释清楚为什么类图里多了一个非业务类。5. 建模实操避坑我在这套 UML 图上翻过的五个坑5.1 时序图消息命名混乱答辩被问住现象借书时序图里同时有 login、checkstu_card、getreaders 和 borrow、create命名风格不统一有的带下划线有的不带。答辩被问“checkstu_card 和 getreaders 到底谁调用谁”时一时说不清楚。原因文档本身就是课程设计产物函数名是从不同参考模板里拼出来的没有统一命名规范。解决复现时把所有消息按“动词操作对象参数”重命名。校验读者用 checkReaderCard()获取读者用 getReaderInfo()创建借阅记录用 createBorrowRecord()让消息名和类图方法一一对应代码阶段直接照抄方法名。保持命名风格一致图和图之间的对应关系会清晰很多。5.2 类图关联箭头画反StarUML 里看不出归属现象把 Item 指向 Title 画成了依赖虚线把 reader 和 borrow 画成了无方向的实线导出图后完全看不出谁拥有谁。原因对 UML 箭头含义凭感觉处理。依赖和关联都带箭头但一个是虚线一个是实线含义完全不同聚合和组合也都带菱形但一个是空心一个是实心。解决记一条口诀——实线是“长期有关系”虚线是“临时用一下”空心三角是继承。画完类图后逐条检查每条线的语义borrow 的 create 方法里直接用了 Item 对象所以 borrow 依赖 Item用虚线reader 的 borrowed 属性是长期持有的列表用实线关联。检查顺序先线型后方向能基本杜绝画反。5.3 状态图漏了“取消预订”分支现象跟着文档文字描述画状态图只画了预订到借出、预订超时到可用后来发现需求原文写着“借阅者在规定的预订时间内也可以考虑取消预订”状态图里却没有对应的迁移。原因注意力全放在“超时”事件上忽略了“取消预订”这个由读者主动触发的事件。解决给预订状态补一条迁移预订到可用触发事件是“取消预订”。还要注意取消预订和超时取消最终都落到“可用”但一个来自读者操作一个来自系统定时任务类图里对应的是两个不同方法不是一个。状态图的每条迁移都要能在需求原文里找到依据找不到就说明需求没覆盖完整。5.4 活动图分支条件丢失流程线走不到底现象复现借书活动图时只画了主流程线没有画“读者不符合借书条件”和“书籍已经被预订”的分支。审查的人问“借书失败怎么办”时图里找不到答案。原因把活动图理解成了流程图的简化版默认流程一定能走通没有画 decision node。解决每个 if 都必须在图上画成显式分支失败路径也要有落脚点。借书活动图至少要有三个判断点读者资格、书籍可借性、预订状态每个判断都要有“是”和“否”两个出口。写活动图代码时把 then是和 else否成对写完再继续下一步就不会漏。5.5 doc 里的模板痕迹直接抄会翻车现象文档第三部分“实验心得”写的是“此次实验我们实现了对网上选课系统的设计”和图书馆管理系统完全是两个项目。直接复制到自己的报告里会被当成粘贴了别人的模板。原因原文档从其他课程设计改过来只改了图和正文心得段落没有同步改系统名。解决拿到这类 doc 的第一件事是全文搜索“选课”“网上选课”等词把残留的模板文字清干净。我拆这份文档时还发现需求分析里的读者字段、书籍字段是直接从别的系统照搬过来的画类图前先统一成带类型的属性定义不然类图里的字段类型会写得五花八门。6. 把这套 UML 模型搬到自己项目里复现顺序与验证闭环6.1 推荐复现顺序不是从类图开始我最初做这类建模时习惯先画类图因为类图最像“设计成果”。但这个项目让我改掉了这个习惯类图里的类和方法要靠用例图、时序图、活动图来推导先画类图等于在需求边界都没立住的时候定对象很容易多出几个没人用的类。正确的顺序是用例图定边界活动图理流程时序图定消息状态图找事件最后类图收口。工具上PlantUML 适合用文字快速出图和做版本管理StarUML 适合精调类图和用例图的线型draw.io 适合和队友一起改。无论用哪个建议把图源文件保留下来导出的 PNG 只是结果源文件才是能改的模型。如果你习惯用 StarUML 画类图每次画完都检查一次关联线的线型这是我踩过的坑里性价比最高的检查项。6.2 验证方法一张覆盖矩阵检查表复现完全部图之后用一张覆盖矩阵做逐行核对每行是一个用例每列是一张图。比如“借书”用例要能在借书活动图里找到主流程在借书时序图里找到完整的消息链在类图 borrow 类和 Item 类上找到对应方法“预订”用例对应预订活动图和 Reservation 类“逾期处理”用例对应罚款时序图和 borrow 类的更新操作。逐行核对下来缺哪张图就补哪张图。用例活动图时序图类图借书借书活动图借书时序图borrow、Item、reader还书还书活动图还书时序图borrow、Item预订预订活动图文档未给出复现时需补画Reservation、Item逾期处理还书活动图的罚款分支罚款时序图borrow、persistent store注意这份 doc 只给出了借书、还书、罚款三张时序图预订用例没有对应的时序图。复现到预订时按借书时序图的模式补一张否则覆盖矩阵会缺一行。从那以后我每次做 UML 建模都强制走一遍覆盖矩阵先用例后类图再回来补缺失的图。这份 doc 把借书、还书、罚款、预订的模型都摆在明面上照着复现一次比来回翻十篇教程更管用。希望帮到你。本文还有配套的精品资源点击获取
返回列表