ARTICLE DETAIL

资讯详情

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

学生选课系统DFD数据流图绘制:从边界到分层实践

学生选课系统DFD数据流图绘制:从边界到分层实践 简介学生选课系统DFD图文档是面向计算机相关专业学生和初学者的系统分析参考资料围绕顶层DFD与第一层DFD绘制清晰刻画管理员、教师、学生三类外部实体与系统间的数据交互可辅助完成课程设计或毕业论文中的系统建模部分。文档侧重两层级分解顶层图界定系统边界第一层图细化用户登录、选课系统、教师开课、学生选课四个核心处理过程覆盖账号分配、课程申请、选课操作、成绩录入与统计等典型数据流并以选课信息、课程信息、成绩信息、个人信息等定义关键数据流便于梳理系统逻辑。预览中还包含教师先发布开课通知、学生再收到选课通知的流程以及登录失败提示、密码修改等细节有助于理解系统实际运行顺序。资源包共1个doc文件压缩包大小23KB内容适合系统分析与设计入门、DFD图绘制练习及报告撰写参考。目前已有4139人学习/下载借助分层数据流图可掌握从外部实体、处理过程到数据存储的逐步分解方法为后续编写数据字典和系统设计提供参考。1. 学生选课系统画 DFD先解决边界问题学生的选课请求提交之后系统要做三件事查课程容量、查时间冲突、写选课记录。这三件事没有一件关心页面长什么样、按钮叫什么名字它们全部围绕数据在转——这就是 DFDData Flow Diagram数据流图适合建模这类系统的原因。学生选课系统 DFD 图的难点不在于符号记不住而在于边界经常被画错外部实体和加工混在一起、存储直接出现在最顶层、或是在分层时悄悄多出一条数据流。而标题里的.doc也提示了一点这份图的最终交付形态是一份要放进 Word 的文档它要经历评审、答辩和批注不是画给自己看的草稿。2. 从上下文图到 0 层图把选课系统拆成三个主加工2.1 四种符号在选课系统里分别对应什么DFD 的基础符号只有四种外部实体、加工、数据存储、数据流。选课系统里学生、教师、管理员是外部实体它们位于系统边界之外只负责提供数据或接收结果加工是系统内真正做事的环节比如选课管理、课程管理、成绩管理数据存储是数据停留的位置比如课程文件、选课记录、成绩单数据流则是连接前三者的带箭头线段。边界判断有一个非常实用的标准这个角色需要登录系统吗需要登录的几乎都在边界里面不需要登录或只提供原始输入的人在边界外面。学生虽然要在界面上操作但在 DFD 的视角里学生只是「选课请求」这个数据流的来源选课规则、容量检查这些逻辑都属于系统内部加工。教材里银行取款过程的 DFD 图常被拿来当范例储户在边界外取款、验密、记账在边界内学生选课系统完全可以套用同样的划分方式。2.2 用 PlantUML 画出上下文图的最小代码上下文图也叫顶层图整张图只有一个加工名字就是系统本身。它的作用是锁定外部实体以及系统对外交互的数据流评审时第一眼看的往往就是这张图。下面是我常用的一段 PlantUMLstartuml left to right direction actor 学生 as stu actor 教师 as tea actor 管理员 as adm rectangle 学生选课系统 { usecase 选课系统 as system } stu -- system : 选课请求 system -- stu : 选课结果 stu -- system : 退课请求 system -- stu : 退课结果 tea -- system : 成绩单 system -- tea : 成绩确认 adm -- system : 课程与账号数据 system -- adm : 处理结果 enduml这段代码里actor声明外部实体usecase在这里借用来表示加工rectangle画出系统边界--表示数据流方向冒号后面是数据流名称。注意每个外部实体和系统之间至少有一进一出两条流学生有选课请求进、选课结果出退课同理。如果只画了一条单向箭头评审第一个问题就会是「结果怎么回去」。2.3 0 层图的两个拆分原则上下文图确认之后把「选课系统」这个加工往下拆一层就得到 0 层图。这一层要把系统内主要的加工摆出来。我一般遵循两个原则第一外部实体之间的数据流不允许出现学生不会直接把成绩单发给教师所有交互都必须经过系统内部加工第二外部实体不能直接读写数据存储存储是系统内部资源学生不能直接操作课程文件。基于这两个原则选课系统可以拆成三个主加工选课管理负责接收学生的选课和退课请求课程管理负责管理员对课程信息的维护成绩管理负责教师成绩单的录入与确认。存储则在需要的时候才引入课程文件、选课记录、成绩单分别挂在对应加工下面。整个 0 层图用 PlantUML 写出来大约就是这个结构startuml left to right direction actor 学生 as stu actor 教师 as tea actor 管理员 as adm rectangle 学生选课系统 { usecase 1 选课管理 as sel usecase 2 课程管理 as course usecase 3 成绩管理 as score database D1 课程文件 as D1 database D2 选课记录 as D2 database D3 成绩单 as D3 } stu -- sel : 选课请求 sel -- stu : 选课结果 stu -- sel : 退课请求 sel -- stu : 退课结果 adm -- course : 课程信息 course -- adm : 审核结果 course -- D1 : 写入课程 D1 -- course : 读取课程 sel -- D1 : 读取容量 D1 -- sel : 容量信息 sel -- D2 : 写入选课记录 D2 -- sel : 已选记录 tea -- score : 成绩单 score -- tea : 确认回执 score -- D3 : 写入成绩 enduml加工编号从 1 开始三个主加工分别记为 1、2、3存储编号用 D 前缀D1、D2、D3避免和加工编号混淆。数据流命名要直接对应业务动作比如「读取容量」就比「数据」多出大量信息。这里用database符号只是为了快速出图正式文档里建议把存储画成两条横线的标准符号语义更贴近 DFD 规范。3. 1 层与 2 层分解把选课管理拆到冲突检测3.1 加工 1 的内部四个子加工怎么协作0 层图里的「选课管理」仍然太粗它至少包含选课登记、冲突检测、退课处理、记录更新四件事。把它们画成 1 层子图加工编号采用小数点层级1.1 选课登记、1.2 冲突检测、1.3 退课处理、1.4 记录更新。这里最容易犯的错是把「登录」也画进选课流程登录属于身份认证通常作为独立加工存在不要混入选课管理内部。startuml left to right direction actor 学生 as stu rectangle 1 选课管理 { usecase 1.1 选课登记 as reg usecase 1.2 冲突检测 as check usecase 1.3 退课处理 as drop usecase 1.4 记录更新 as upd database D1 课程文件 as D1 database D2 选课记录 as D2 } stu -- reg : 选课请求 reg -- check : 待检选课信息 check -- D1 : 读取容量 D1 -- check : 容量与时间 check -- D2 : 读取已选 D2 -- check : 已选课程列表 check -- reg : 检测结果 reg -- stu : 选课结果 stu -- drop : 退课请求 drop -- D2 : 删除记录 drop -- stu : 退课结果 reg -- upd : 通过记录 upd -- D2 : 写入选课记录 enduml这段代码里有一个容易被忽略的细节reg -- check和check -- reg是两条独立的数据流。「待检选课信息」是选课登记向冲突检测发出的请求「检测结果」是冲突检测返回给选课登记的结论。初学者经常把这两条合并成一条带双向箭头的线这在数据流图里是不允许的每条数据流必须方向单一、名字唯一。选课结果最终由选课登记返回给学生而不是直接从冲突检测发出这样设计是为了让对外出口保持统一后续如果增加选课规则只需要在选课登记里调整出口不牵动外部实体。3.2 数据存储在分解中的粒度变化3.2.1 逻辑存储与物理表的区别D1 课程文件在 0 层图里只有一个整体到 1 层分解时没必要拆成「课程基本表」「课程容量表」两张存储DFD 里的存储是逻辑存储不是数据库表结构。课程容量、上课时间、授课教师这些信息在逻辑上都属于「课程文件」物理上拆成几张表是数据库设计阶段的事情。把逻辑存储和物理表混在一起是 DFD 图中最常见的设计过度。存储粒度可以这样把握只要两个加工需要读写的数据集合边界清晰就可以拆成两个存储如果仅仅是为了配合某个加工的动作而拆分不要拆。选课管理内部D1 课程文件提供容量与时间信息D2 选课记录保存学生与课程的对应关系两者的边界非常清晰。退课处理只操作 D2不触碰 D1这也说明退课逻辑不关心课程信息只关心选课记录本身。3.3 子图平衡检查父图子图的数据流必须逐条对上子图平衡是 DFD 分层里最硬的一条规则父图中某个加工的输入输出数据流必须完整出现在它的子图里不能多也不能少。拿 0 层图里加工 1 来对照父图中它的输入是「选课请求」「退课请求」输出是「选课结果」「退课结果」1 层子图里这四条流原样出现才算平衡。数据流名称0 层图加工 11 层子图选课请求输入输入选课结果输出输出退课请求输入输入退课结果输出输出如果子图里多了「调课申请」而父图加工 1 没有这条输入就说明分层时引入了新需求需要回到父图同步修改。反过来如果父图有「选课结果」而子图只有「选课成功信息」名字不完全一致评审也会判为不平衡。子图内部加工之间的数据流不受平衡规则约束比如「待检选课信息」只存在于子图内部这是正常的。另外明确一件容易混淆的事DFD 里不画控制流。「课程是否已满」是加工内部的判断逻辑不能画成从存储引出的分支条件。如果画出「容量已满则拒绝选课」这样的菱形判断那就变成流程图了不再是数据流图。判断条件属于加工的详细说明应该写进数据字典或加工说明文档不占用数据流。4. 数据字典与平衡校验让 DFD 文档经得起评审4.1 数据字典写什么字段DFD 画完数据字典是配套交付物没有数据字典的 DFD 在评审时等于没有一半信息。数据字典的核心是回答「这条数据流里到底有什么」每条数据流给出数据项组成、来源、去向数据项给出类型与取值范围。下面是我给这个系统常用的数据字典结构数据流 / 存储数据项组成来源去向选课请求学号 课程编号 开课学期学生选课登记选课结果学号 课程编号 处理状态 失败原因冲突检测学生退课请求学号 课程编号 开课学期学生退课处理选课记录D2学号 课程编号 开课学期 选课时间记录更新冲突检测 / 退课处理处理状态这一项的取值一般是「成功 / 失败 / 已满 / 时间冲突」取值范围可以继续写在备注列里。数据字典不是用来凑页数的它直接决定后续数据库设计时字段怎么定。看到「选课请求 学号 课程编号 开课学期」建一张选课表时至少这几个字段不会漏掉。如果某条数据流的组成是「各种信息」这种写法后面拿到数据库设计文档时一定会发现字段对不上。4.2 用 grep 检查 DFD 与字典的一致性如果 DFD 是用 PlantUML 文本形式维护的我一般会顺手用 grep 做一次一致性自检。下面的命令在当前目录下的 puml 文件里统计四个关键数据流的出现次数grep -oE 选课请求|选课结果|退课请求|退课结果 选课系统.puml | sort | uniq -c输出的数字能快速暴露一个问题某条数据流在文件里只出现了一次。正常情况「选课请求」至少出现两次一次在上下文图、一次在 0 层图如果某个文件里只有一次说明分层时可能漏画了。注意 uniq -c 统计的是 puml 源文件中的出现次数不能代替人工分层对照它只能帮你把缺失或者拼写不一致的数据流找出来。更实用的是下面的命令列出所有实体、加工、存储的名字当作一份命名清单grep -nE ^(actor|usecase|database) 选课系统.puml这条命令把外部实体、加工、存储在文件里的行号一起打出适合在评审前一天快速确认三件事外部实体数量是否符合预期、加工编号是否连续、存储命名是否都是业务名词而不是「数据库」这种模糊叫法。4.3 三种评审必问的边界情况第一种外部实体直接连存储。有同学把学生指向选课记录画一条「查询」箭头这在 DFD 里是非法连接学生查选课记录必须经过某个加工加工内部再去访问存储。第二种数据流名字含糊叫「数据」「信息」「内容」的都是无效命名数据流要能让人看出传的是什么。第三种存储退化成「数据库」三个字课程、选课、成绩全混在里面等于没画因为无法判断哪个加工在读写哪部分数据。判断存储粒度是否合适可以把银行取款过程的 DFD 图翻出来对照储户在外部取款处理这个加工内部才有验密、扣款、记账几个子加工「账户文件」是一个存储而不是一张「银行数据库」大杂烩。选课系统同理容量检查和选课记录分属两个存储因为它们在加工中的读写频率完全不一样。5. 交付 .doc 前用三招校验 DFD5.1 工具选型与 .doc 嵌入方式画 DFD 的工具没有标准答案Visio 的优势是和 Word 同属一个生态画完直接粘贴为增强型图元文件放大不糊还能继续编辑draw.io 免费且离线可用导出 SVG 后放进 Word 通常需要另存为图片格式再插入PlantUML 则适合用文本方式维护分层图每层图对应一个 puml 文件修改记录可以留在版本管理里。我一般用 PlantUML 出图后渲染成 300 dpi 的 PNG插入 Word 时把图片版式选「嵌入型」这样图片和题注不会因为文字排版而乱跳。5.2 三招快速校验法第一招查边界外部实体只能和加工连线不能连存储外部实体之间也不能互相连线。第二招查子图平衡拿父图加工的输入输出流清单当核对表逐条在子图里打勾。第三招查命名存储和数据流一律用业务名词拒绝「数据库」「数据」这类说法。最后一招是一个答辩时很管用的讲解技巧介绍 DFD 时从外部实体出发顺着数据流走到加工再走到存储比如用「学生发起选课请求选课登记接收后交给冲突检测冲突检测读取课程文件和选课记录最后把结果返回给学生」这条线来陈述。把这句话当成清单外部实体不连存储子图不增删数据流存储不叫「数据库」——三条都过了图就站得住。本文还有配套的精品资源点击获取
返回列表