news 2026/10/15 19:05:22

面向数据流的分析方法:从DFD到数据字典的图书馆系统建模指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
面向数据流的分析方法:从DFD到数据字典的图书馆系统建模指南

简介:围绕软件工程中的面向数据流分析方法,赵良老师的PPT教学课件系统讲解了需求分析建模的核心内容。课件从抽象与模型概念出发,区分逻辑模型与物理模型,结合小型图书馆管理系统的借还书、检索、读者管理等典型场景,演示如何完成现实环境调查、当前系统逻辑模型抽取、目标系统逻辑模型建立,以及需求获取、需求定义与功能性/非功能性需求分类,并延伸介绍结构化与面向对象开发方法。适合软件工程初学者或需要系统梳理需求分析流程的读者,尤其有助于理解软件工程中“做什么”与“怎么做”的层次。包内为单份PPT文件,压缩包约1.41MB,内容紧凑、案例完整,已有223人学习下载。通过课件内容可掌握从当前系统物理模型到目标系统逻辑模型的过渡思路,并理解数据流分析方法在实践中的具体应用。

1. 面向数据流的分析方法:先别画界面,把数据流讲清楚再说

接手“小型图书馆管理系统”这类题目时,新手最容易做的事是打开画板先画界面原型,或者直接建数据库表。但按面向数据流的分析方法,这两步都干早了。这套方法的思路是:需求阶段不关心界面长什么样、表怎么建,只回答一个问题——数据从哪里来、经过哪些加工、流向哪里去。这份软件工程讲义正是围绕这一点展开的,核心工具是数据流图(DFD)、数据字典(DD)和加工说明,适合正在做课程设计、期末大作业或第一次接触结构化需求分析的从业者。把数据流理清楚了,后面的设计、编码、测试才有骨架可依。

2. 需求分析到底要分析什么:从物理模型到逻辑模型的抽象过程

2.1 为什么需求分析要“抽象”而不是“描述”

讲义里有一句关键的话:需求分析的过程,第一步是“通过对现实环境的调查,获得当前系统的物理模型”,第二步是“去掉具体模型中的非本质因素,抽象出当前系统的逻辑模型”。很多初学者把这两步混成一步,对着现实业务一通记录,最后交上去的所谓需求文档,读起来像操作手册,而不是逻辑模型。

两者的差别可以用讲义里的教材购买案例说清楚。现实的物理模型是这样的:学生递交购书申请,教务科审核有效性,会计室收款开发票,教材科凭发票和领书单发书。这里面有具体的岗位、具体的单据流转路线,甚至具体到哪个办公室。但如果把“教务科”“会计室”“教材科”这些组织名称全部抹掉,只保留动作和数据,就得到逻辑模型:审查购书申请、收费开发票、开领书单、发书。再往下,如果目标是做一个计算机教材管理系统,还要把“无效购书单”这个分支补上,让系统直接对无效申请做拦截,而不是靠人工识别。

这个抽象过程放到图书馆管理系统中同样成立。现实中的借书流程是:读者到服务台出示借书证,管理员查目录卡片确认图书在馆,然后去书库取书,在借书登记簿上手写记录。抽掉“服务台”“目录卡片”“书库”这些物理载体后,逻辑模型变成:读者提交借书请求,系统验证读者资格,验证图书状态,创建借阅记录,更新图书状态。物理模型描述的是“现状怎么做”,逻辑模型描述的是“本质是什么”,两者之间差的那一层,正是做需求分析的人要思考的东西。

2.2 小型图书馆管理系统的功能、角色与约束

讲义给出了一个具体的需求背景:一个小型图书馆管理系统,需要完成五件事——借书、还书、增加或删除一本书、按作者名或专业领域检索一批书、找出被某位读者借出的一批书、找出最近借走某本图书的读者。系统有两类用户:图书管理员与普通读者。

这里容易看漏的是功能与角色的对应关系。不是所有功能都开放给所有用户,讲义里明确写了:功能4(检索图书)供普通读者使用;功能1(借书)、功能2(还书)、功能5(查最近借书人)供图书管理员使用。功能3(增删图书)没有点名,但结合实际场景与“图书管理员”的职责范围,归到管理员操作是合理的。

功能编号功能描述使用角色备注
F1借书图书管理员读者借出时登记
F2还书图书管理员归还后更新状态
F3增加/删除一本书图书管理员馆藏变更
F4按作者名或专业领域检索普通读者检索一批书
F5找出被某读者借出的一批书普通读者查询读者借阅列表
F6找出最近借走某本图书的读者图书管理员追踪图书去向

注意,讲义里功能列表的编号顺序和描述有一点跳跃:原文第4项是“找出被某位读者借出的一批书”,第5项是“找出最近借走某本图书的读者”。我在表中按功能逻辑重新排了序,实际建模时建议以功能编号F1到F6为准,避免文档描述和图上的编号对不上。

系统还必须满足三条约束条件。第一,馆中所有未借出的书籍能够供读者随时借阅;第二,在同一时刻,一本书不能既被借出又被借阅;第三,一个读者一次借出的书籍数目不能超过预定值。这三条约束分别对应着“图书状态检查”“并发借阅互斥”“借阅数量上限”,都是后面加工说明和判定表里必须落地的业务规则,不能只写在需求描述里就完事。

2.3 把图书馆业务从物理模型抽成逻辑模型的实操步骤

参考讲义里“当前系统→目标系统”的四步走方法,图书馆管理系统的抽象过程可以这样执行。第一步,画出当前系统的物理模型:读者在服务台填借书单,管理员核对证件,进书库找书,登记簿上记录借出信息,归还时再核销。第二步,抹掉物理载体,得到逻辑模型:借书请求进入系统,校验读者和图书,生成借阅记录,更新库存状态。第三步,分析目标系统和当前系统的差别:目标系统需要支持按作者名或专业领域检索,需要自动判断借阅数量上限,需要能回答“某本书最近被谁借走”这类追踪问题,这些都是物理模型里的登记簿做不到的。第四步,细化逻辑模型,把“校验读者”“校验图书”“创建借阅记录”分别定义成独立的处理步骤。

实际动手时,我一般会用一张表把物理模型要素和逻辑模型要素对应起来,逐项确认哪些是本质的、哪些是非本质的。比如“借书证”是本质的,因为系统需要标识读者身份;“纸质登记簿”是非本质的,因为换成电子记录后,簿册本身就消失了。用这种逐项核对的方式过一遍,抽象过程基本不会漏。

3. 数据流图(DFD)分层建模:图书馆系统的骨架怎么画

3.1 DFD 的四个要素与命名规则

面向数据流的分析方法,核心成果物是数据流图。一张完整的 DFD 由四种基本要素构成:外部实体、加工、数据流、数据存储。外部实体是系统边界之外的人和系统,比如读者、图书管理员;加工是对数据执行的处理动作,比如“借书登记”“检索图书”;数据流是带方向的数据传递,标注名次必须是名词短语,比如“借书请求”“图书状态更新”;数据存储是数据停留的静态位置,比如“图书表”“借阅记录”。

命名这条最容易翻车。数据流名不能是动词短语,“验证读者”是加工名而不是数据流名,数据流应该是“读者信息”“校验结果”;加工名必须是动宾结构,“借书处理”“还书处理”没问题,但“借书”单独做加工名就有歧义,是动作还是数据流?图上不标方向的时候根本分不清。数据存储名用名词,且尽量和后续数据库表名保持对应,省得设计阶段还要再做一次翻译。

这些要素组合起来,规则只有一条:任何一个加工都必须有输入数据流和输出数据流,输入是加工要消费的数据,输出是加工产生的数据。只有输入没有输出,或者只有输出没有输入,都说明这个加工的定义有问题,要么是数据没画全,要么是加工边界画错了。

3.2 顶层图与 0 层图:先定边界再拆加工

DFD 是分层的,第一层是顶层图,也叫上下文图,它只画一个加工——整个系统,以及和系统交互的外部实体。图书馆管理系统的顶层图里,外部实体有“普通读者”和“图书管理员”,系统加工叫“图书馆管理系统”,数据存储在这一层通常不画,或者只画在最外围标识边界。

0 层图把顶层图里的“图书馆管理系统”这个唯一加工展开成多个加工。按讲义里的功能列表和用户角色划分,0 层图可以拆成这样六个加工:

  • P1 借书处理:输入借书请求,校验读者和图书,生成借阅记录
  • P2 还书处理:输入还书请求,更新图书状态和借阅记录
  • P3 图书管理:增加或删除图书,维护馆藏信息
  • P4 图书检索:按作者名或专业领域输出图书列表
  • P5 借阅查询:按读者输出其借出的一批书
  • P6 图书追踪:按图书输出最近借走该书的读者

数据存储在 0 层图就要出现了,至少包括“图书表”和“借阅记录表”。P1 借书时要读“图书表”校验状态、读“借阅记录表”统计读者当前借出数量,同时写入新的借阅记录并更新“图书表”中的状态字段;P2 还书时读“借阅记录表”定位记录、更新“图书表”状态;P3 图书管理写“图书表”;P4 图书检索读“图书表”;P5 借阅查询按读者编号读“借阅记录表”;P6 图书追踪按图书编号读“借阅记录表”。每一条数据流都要能对应到具体存储或外部实体,这是分层画图时最值得花时间对账的地方。

3.3 数据字典(DD):让每条数据流都有据可查

数据流图画完之后,图上的每个命名都只是名字,具体包含什么字段、什么类型、有什么取值范围,全部由数据字典定义。数据字典是 DFD 的配套文档,没有字典的 DFD 就像没有图例的地图,画得再漂亮也读不懂。

数据字典的条目分三类:数据流条目、数据存储条目、数据项条目。数据流条目定义一条数据流的组成,用“=”表示组成关系,比如“借书请求=读者编号+图书编号+借书日期+预定归还日期”。数据存储条目定义存储内的记录结构,比如“图书=图书编号+书名+作者+专业领域+状态”。数据项条目定义最底层的数据项,包括类型、格式和取值范围。

图书馆管理系统里几条核心字典条目可以这么写:

数据流条目: 借书请求: 别名: 借阅单 组成: 读者编号 + 图书编号 + 借书日期 + 预定归还日期 来源: 外部实体.普通读者(经图书管理员录入) 去向: 加工.借书处理 还书请求: 组成: 读者编号 + 图书编号 + 还书日期 来源: 外部实体.普通读者(经图书管理员录入) 去向: 加工.还书处理 数据存储条目: 图书表: 组成: 图书编号 + 书名 + 作者 + 专业领域 + 状态 关键字: 图书编号 状态取值范围: [在馆, 已借出] 借阅记录表: 组成: 借阅编号 + 读者编号 + 图书编号 + 借出日期 + 归还日期 + 状态 关键字: 借阅编号 状态取值范围: [借出中, 已归还] 数据项条目: 读者编号: 类型: string 格式: R + 三位数字,如 R001 备注: 唯一标识一个读者 图书编号: 类型: string 格式: B + 四位数字,如 B0001 备注: 唯一标识一本图书

写完字典条目后要做一轮交叉检查:DFD 图上的每条数据流,在字典里都必须有一条对应定义;字典里的每个数据流,在图上也必须找得到。图上有、字典里没有的,说明命名或定义漏了;字典里有、图上找不到的,说明字典里混入了没有实际流向的数据。这种交叉检查是需求分析阶段性价比最高的验证手段之一,能发现大量看似无关紧要但后期很致命的遗漏。

4. 加工说明与系统映射:借书、还书、查询的细节怎么落定

4.1 用结构化语言描述“借书”加工

DFD 表达了数据从哪里来到哪里去,但没有表达加工内部的处理逻辑。比如“借书处理”这个加工,读者提交请求之后,系统到底先验证什么、再验证什么、什么情况下返回什么结果,都需要加工说明来补充。面向数据流的分析方法里,最常用的逻辑描述工具是结构化语言——介于自然语言和编程语言之间的写法。

借书加工是这套系统里约束最多、最值得展开的一个。它要满足讲义里的三条约束:图书必须在馆、一本书同一时刻只能被一个读者借出、读者借出数量不能超过预定值。用结构化语言表达:

加工编号: P1 加工名称: 借书处理 输入: 借书请求(读者编号, 图书编号, 借书日期) 输出: 借出成功回执 或 借出失败原因 begin 根据读者编号 查询读者记录; if 读者不存在 then 返回 "无效读者"; end_if; 根据读者编号 统计当前借出且未归还的记录数量; if 当前数量 >= 读者类型对应的借阅上限 then 返回 "借阅数量超限"; end_if; 根据图书编号 查询图书记录; if 图书状态 != "在馆" then 返回 "图书不可借"; end_if; 创建借阅记录(读者编号, 图书编号, 借出日期, 状态="借出中"); 更新图书状态(图书编号, 状态="已借出"); 返回 "借出成功"; end

这段逻辑的检查顺序是有讲究的。先查读者存在性,再查数量上限,最后查图书状态,这样安排是为了让失败原因更精确:读者都不存在时,谈上限和图书状态没有意义;读者超限时,读者资格已经确认,可以直接归因到数量问题;图书不在馆的情况最后才出现,说明这是借阅行为本身的冲突,而不是读者资格问题。这个顺序如果反过来,先查图书再查读者,一个无效读者请求一本在馆图书,返回的失败原因就会把两个问题混在一起,后面排查时增加不必要的沟通成本。

4.2 用判定表处理借阅规则组合

结构化语言适合表达顺序逻辑,但当条件组合多起来,一段一段写容易漏分支。讲义里的约束条件恰好适合用判定表来列:读者是否存在、读者是否超限、图书是否在馆,三个条件的组合决定了借书请求是放行还是拒绝。判定表能把所有组合一次性列出来,是检查规则完备性的好工具。

借书处理的判定表可以设计成:

规则编号读者存在数量未超限图书在馆处理结果
R1是是是借出成功
R2否--无效读者
R3是否-借阅数量超限
R4是是否图书不可借
R5否--无效读者(与R2合并)

这里用“-”表示该条件不影响结果。R2 和 R5 实际合并成一条规则,因为读者不存在时,系统根本没机会检查数量上限和图书状态。整理判定表的过程,其实就是在验证加工说明里的分支是否覆盖了所有可能。比如只写了“图书不可借”但忘了“无效读者”,判定表里就少了一条规则,测试设计时也会跟着漏掉这个用例。

还书加工比借书简单一些,但也值得写清楚。还书时要根据读者编号和图书编号定位未归还的借阅记录,更新记录状态为“已归还”,同时把图书状态改回“在馆”。如果系统需要计算逾期天数,那个计算逻辑应当在还书加工内部作为单独的输出数据流处理,但注意,程序里做的是“计算逾期天数”,不是“自动罚款”——罚款规则属于业务流程决策,讲义没有给出相关的业务规则,建模时就不要自己加。

4.3 从 DFD 到软件结构:变换分析与事务分析的映射思路

面向数据流的建模方法不止于需求分析,讲义末尾提到的结构化开发方法里包含了从分析到设计的延伸。DFD 模型建立后,软件结构图可以通过两种方式映射出来:变换分析和事务分析。这是结构化设计阶段的内容,但提前理解它,能让需求阶段的 DFD 少走弯路。

变换分析适用于“输入数据→中心变换→输出数据”这种线性结构。以还书处理为例:还书请求输入系统后,经过“定位借阅记录”“更新记录状态”“更新图书状态”几步变换,最后输出“还书成功回执”。结构图沿着数据流的路径逐级分解,每个 DFD 加工对应结构图里的一个模块,数据流变成模块间的调用关系和数据传递关系。

事务分析适用于“一个入口、多个分支”的结构。借书处理就是一个典型事务:先做读者校验和数量校验,再根据校验结果决定走“创建借阅记录”分支还是“返回失败原因”分支。结构图里,事务中心是一个控制模块,它把不同类型的输入分发到不同的处理模块。

说了这两个方法,核心建议只有一条:画 DFD 时就要考虑每个加工是属于变换型还是事务型,因为这会影响加工的展开粒度。一个加工如果既是变换又是事务的混合体,后面结构设计的模块划分就会很别扭。我一般画完 0 层图后会先标一遍类型,P1 借书处理标事务型,P2 还书处理标变换型,P4 图书检索标变换型,这样后续映射时边界清楚,不用返工。

5. 避坑与常见问题:一套 DFD 画错五次的典型场景

5.1 把控制流画进数据流图:一条“点击查询”的箭头引发的混乱

现象:DFD 里出现“点击检索按钮”“登录成功跳转首页”这类带动作触发意味的数据流。画图的人觉得自己把系统逻辑表达清楚了,评审的人却一脸茫然。

原因:把控制流和数据流混为一谈。DFD 里的数据流表示“数据从一处传递到另一处”,不表示“某个动作触发了另一个动作”。“点击”是事件,不是数据。

解决:控制逻辑交给状态图或流程图,DFD 只保留名词性的数据流。“点击检索”应改成“检索条件”,“登录成功”应改成“用户会话信息”。我在检查自己的 DFD 时,会看每条数据流的名字是不是名词短语,出现动词就直接标红重画。

5.2 父子图数据流不平衡:评审时被问“这条线哪来的”

现象:顶层图里系统只有一个输入“借书请求”,展开到 0 层图时,P1 借书处理旁边多了一条“读者身份证明”输入;0 层图的 P6 图书追踪输出“追踪报告”,但顶层图里根本没画这条输出去向外部实体。

原因:分层画图时只关注了当前层内部的数据流,没有做父子图之间的平衡检查。父图中的每个加工展开成子图时,子图的输入输出数据流必须和父图该加工周围的输入输出完全一致。

解决:每画完一层就做一次集合对比。父图加工 P1 有输入“借书请求”、输出“借出结果”,那么 P1 的子图里必须且只能有这两个边界数据流。多一条少一条都是不平衡。这个检查可以手工做,也可以用小脚本来辅助,后面第 6 章会给示例。这个坑是评审时最常见的提问点,几乎每次都会被问到。

5.3 数据字典与 DFD 命名不一致:同一个东西两个名字

现象:DFD 上一条数据流叫“借书信息”,数据字典里对应的条目叫“借阅单”;加工说明里引用“读者编号”,字典里却是“借书证号”。看着都能猜到是同一个东西,但没法自动对上。

原因:建模时先画图、后补字典,命名没有统一规范;也可能是不同人分工画不同部分,各自起了名字。

解决:定命名规范,并且以数据字典为准。建图之前先建字典草案,把核心数据项的名字、别名、格式先定下来,然后按字典名字画图。后期如果字典改名词,图上一并同步。做评审准备时,我习惯逐条过一遍:图上的名字在字典里是主名还是别名,凡是只出现在图里、字典里找不到的,全部补齐。

5.4 物理细节漏删干净:扫描枪和柜台的遗留痕迹

现象:逻辑模型里出现“管理员扫描条形码”“系统发送通知到服务台电子屏”“打印借书小票”等描述。看起来细节丰富,但这些是物理实现,不是逻辑需求。

原因:做第二步“去掉非本质因素”时,只删了组织结构,没有删硬件设备和交互载体。扫描枪、红外扫码、打印机都是实现技术,不是系统必须的逻辑行为。

解决:回到讲义的定义——逻辑模型描述“做什么”,物理实现描述“怎么做”。图书馆系统里,本质行为是“读取读者标识”,至于用扫码枪还是手工输入编号,是设计阶段的事,不是需求分析阶段要确定的。我在抽象时用一套过滤词:条形码、扫码、刷卡、打印、显示屏这类词出现,就先问一句“换成别的方式实现,需求变不变”,不变就删掉。

5.5 一个加工的粒度过大:既不内聚也没法细化

现象:0 层图里有一个加工叫“处理借书相关业务”,下面挂了借书、还书、续借、查询四个功能;或者反过来说,0 层图里每个功能都拆到很细,十来个小加工,看不出主次。

原因:加工粒度的划分没有遵循“一个加工对应一个相对独立的功能”的原则。粒度过大,加工内部的逻辑太多,说明不了问题;粒度过小,单层图信息密度过高,看不清楚主数据流。

解决:按“一个加工对应一个数据变换”的原则来划分。借书、还书、检索是三个不同的数据变换,应该拆开;“处理借书相关业务”是给这一组加工贴标签,不是加工本身。反过来,借书加工里的“验证读者”“验证图书”“创建记录”这些步骤,是加工说明里的逻辑分支,不是 0 层图上的独立加工,除非它们之间有清晰的数据流传递。0 层图控制在六个左右加工规模相对合适,P1 到 P6 按功能拆,不按操作细节拆。

6. 验证与进阶:用平衡检查与场景走查给你的模型上保险

DFD 画完不等于建模结束,最后一道工序是验证。我常用三种方式:父子图平衡检查、数据字典覆盖检查、场景走查。平衡检查做的是结构验证,字典覆盖做的是命名验证,场景走查做的是语义验证。三个都过了,模型基本能站得住。

平衡检查可以用一个简单脚本来做,核心逻辑是对比父图加工边界的输入输出集合和子图的输入输出集合:

def balance_check(parent_flows, child_flows, process_name): parent = set(parent_flows) child = set(child_flows) missing = parent - child extra = child - parent if missing or extra: print(f"[不通过] {process_name}") if missing: print(f" 子图缺少父图已有的数据流: {missing}") if extra: print(f" 子图出现了父图没有的数据流: {extra}") else: print(f"[通过] {process_name} 父子图数据流完全一致")

参数说明:parent_flows 是父图中该加工周边所有输入输出数据流的名称集合,child_flows 是子图边界上的输入输出集合。missing 表示子图漏画了父图已有的数据流,extra 表示子图凭空多出了父图没有的数据流。把借书处理的集合传进去跑一遍,基本就能验证出上一章说的不平衡问题。

场景走查的操作是:挑一个具体读者,比如读者编号 R001,借一本图书 B0001,沿着 DFD 从“借书请求”开始,逐条数据流对账——这条数据流从哪个外部实体或存储来?中间经过哪些加工?加工内部走了哪个分支?最终写到哪条存储?每一步都能在图和字典里找到对应,走查通过。对账过程中一旦出现“这个数据是从哪来的”说不清楚,就说明图上有断点,需要回到上一章排查。

从那以后,我每次交 DFD 之前都强制自己走一遍平衡检查和场景走查,哪怕只改了图上的一个加工名,也要把相关数据流全部过一遍。这套习惯救过我不少次,最深刻的一次是给某课程设计交文档前,发现子图里多画了一条“还书回执”数据流,父图上根本没有对应输出,当场修正才避免了评审翻车。希望你也能在动手画图前先搭好字典,画完后再花半小时做验证,能把返工成本压到最低。希望今天讲到的这些,对你的需求分析建模有点帮助。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 19:04:59

绚星AI实战训练场:不只是培训平台里的一个功能

摘要:绚星AI实战训练场,既可作为绚星企业培训平台的实战训练模块,也可独立售卖,是企业级AI陪练产品,支持企业基于真实业务场景开展模拟训练并获取练习反馈,可按需选择一体化集成或单独采购。不少人将AI陪练…

作者头像 李华
网站建设 2026/10/15 19:04:32

Maya 2018.6 DEVKIT插件编译指南:从环境配置到首个.mll

简介:Autodesk Maya 2018.6 Update DEVKIT Windows 版是一套面向三维工具开发者的官方开发套件,适合熟悉 C、Python 或 C# 的程序员,用于编写自定义插件、扩展节点、自动化工作流以及集成渲染管线。压缩包共含 6297 个文件,主体为…

作者头像 李华
网站建设 2026/10/15 19:04:27

BeefTV 画布完全指南:节点、连线与自由创作工作流

人工智能AI 应用AI Agent媒体生成音视频桌面应用 【免费下载链接】BeefTV High-performance Lightweight AI Native Video workspace. 面向 AI 时代的视频创作工作台。 在画布中,和Agent一起自由连接创意、模型与素材。 项目地址: https://gitcode.com…

作者头像 李华
网站建设 2026/10/15 19:04:05

DeepSeek生成的内容能否下载吗?

DeepSeek生成的内容能否下载吗? 一个被多数人忽略的真相:AI 对话框里的内容,本质上并不属于你 这个问题在搜索引擎里被反复问起,但大多数回答都停留在“截图”或“复制粘贴”的层面。作为长期研究 AI 工作流效率的从业者&#xff…

作者头像 李华