☰
数据流图与数据字典:面向数据流的需求分析实践
2026/10/28 14:27:52 网站建设 项目流程

简介:这份PPT面向软件工程课程学习者与需求分析初学者,围绕面向数据流的分析方法展开,借助小型图书馆管理系统的案例讲解从现实业务到逻辑模型、物理模型的抽象与建模过程。压缩包内仅含1个PPT文件,大小约1.41MB,适合课堂讲授、复习整理与需求分析专题自学。已有225人学习下载。内容涵盖抽象、模型、需求获取与需求定义、功能性与非功能性需求、结构化与面向对象开发方法等知识点,并串联借还书、图书增删、按作者或领域检索、借阅记录查询等需求场景,帮助读者理解数据流向分析、当前系统与目标系统模型转换及需求验证思路,可作为软件工程需求分析章节的配套学习材料。

1. 面向数据流的需求分析:一份能照着推演到落地的课件拆解

很多人学软件工程,卡住的地方不是不会写代码,而是拿到一句"做一个图书馆管理系统"就无从下笔:需求从哪来、怎么建模、模型和代码之间隔着什么。这份课件讲的就是这段空白——面向数据流的分析方法,用一个小型图书馆管理系统当贯穿案例,把"现实世界到计算机世界"的映射拆成物理模型、逻辑模型、目标系统逻辑模型、细化验证四步走。它适合两类人:正在做课程设计、需要把需求文档写扎实的学生,以及接了小型信息管理系统、需求访谈完却不知道怎么落成数据流图的从业者。课件里那套 DFD、数据字典、功能分解的推演路径,是现在很多敏捷文档里被省略、但排查需求遗漏时最好用的后悔药。

对"面向数据流的分析方法"这个说法,先给个边界:它不是画图技巧课,核心是把系统看成一串加工和流动的数据,用结构化分析(SA)的视角把功能、数据、行为三个领域逐一落地。课件里反复出现的抽象、模型、需求获取、功能性需求与非功能性需求分类,是这套方法的骨架。下面按"这套方法是什么 → 图书馆案例怎么一步步建模 → 参数与边界怎么写 → 坑在哪"的顺序拆开,每一步都能对着自己的项目抄。

2. 从物理模型到逻辑模型:把图书馆的五条需求拆成可建模的输入

课件的第一个硬核动作,是拿"学生买教材"举了个例子:调查现实环境得到物理模型(谁在哪个房间、走什么单据),去掉非本质因素得到逻辑模型(审查有效性、开发票、开领书单、发书),再分析当前系统与目标系统的差别,得到目标系统的逻辑模型。这条链路看着简单,实际是需求分析里最容易翻车的地方——大部分人的"调研"停在了物理模型,把"教务科在信北 206 手工登记"这种实现细节当成了需求。

图书馆案例的五条功能,正好可以按这个思路先做一次粗切:借书还书是数据流的双向主干,增删图书是数据维护分支,按作者或专业领域检索是查询分支,找出某读者借出的书、找出最近借走某本书的读者是两条反向追溯。这五条不是平级的,前两条是事务型加工,后三条是查询型加工,建模时数据存储和加工的划分完全不同。先把它们按"输入什么、加工什么、输出什么"写下来,再动手画图。

2.1 五条功能的输入-加工-输出拆解表

不用一上来就画 DFD,先用一张表把每条需求的数据流对齐,比直接画图少走很多弯路。这张表就是个草稿纸,但它是后面所有图和数据字典的源头:

功能编号输入数据流加工输出数据流涉及数据存储
F1 借书读者号、图书编号校验借阅资格与库存借阅记录、库存状态变更读者表、图书表、借阅记录表
F2 还书图书编号核对借阅记录、更新库存归还确认、超期信息借阅记录表、图书表
F3 增删图书图书信息 / 图书编号新增或注销图书记录操作结果图书表
F4 检索图书作者名 / 专业领域匹配查询图书清单图书表
F5 追溯借阅者图书编号按时间倒序匹配借阅记录读者信息借阅记录表、读者表

这张表的意义在于,它逼你把"功能 4 供普通读者使用,功能 1、2、5 供图书管理员使用"这条角色约束提前落到数据流上:F5 的输出是读者信息,属于敏感数据,只有管理员能触发;F4 的输出是图书清单,普通读者可触发。角色不是画在用例图上就完事,它决定了加工由谁激活、数据存储谁可读谁可写。

2.2 用 Python 把约束条件写成可执行的校验规则

课件里给了三条必须满足的条件:所有未借出的书随时可借;同一时刻一本书不能既借出又被借阅;一个读者一次借出的数目不超过预定值。这三条在文档里是自然语言,在实现里必须变成判断分支,否则需求评审时谁都说"满足了",上线后照样出现一本书被两个人同时借走。

常见做法是先把约束写成状态机与计数规则,再用一段最小可运行代码验证逻辑是否闭环。下面这段不是完整系统,只是把约束条件翻译成判定函数,用来在需求阶段就跟业务方对齐口径:

from dataclasses import dataclass MAX_BORROW = 5 # 单个读者一次借出的上限,对应课件中"预定值" @dataclass class Book: book_id: str author: str field: str is_out: bool = False # 是否已借出,唯一状态位 @dataclass class Reader: reader_id: str borrowed: int = 0 # 当前借出数量,需与借阅记录保持一致 def can_borrow(book: Book, reader: Reader) -> tuple[bool, str]: # 条件2:书已被借出则拒绝,保证一本不能同时被两人持有 if book.is_out: return False, "该书当前处于借出状态" # 条件3:借出数量不得突破预定值 if reader.borrowed >= MAX_BORROW: return False, f"已达借阅上限 {MAX_BORROW} 本" return True, "允许借阅" def borrow(book: Book, reader: Reader) -> str: ok, msg = can_borrow(book, reader) if not ok: return f"借阅失败:{msg}" # 条件1:未借出的书可借,借出后立即置位,避免同一时刻双重占用 book.is_out = True reader.borrowed += 1 return "借阅成功"

这段代码里,is_out是单一状态位,而不是"在库/借出/预约"多状态混用,好处是条件 2 的判定只有一处,不会出现两个字段互相矛盾的黑匣子。MAX_BORROW用常量而不是散落在各处的魔法数字,因为课件明确说这是"预定值",意味着它是可配置的业务参数,不是硬编码。can_borrow与borrow分开,是为了让校验逻辑可以被查询类功能复用(比如 F5 追溯时判断某本书当前状态)。真做并发场景还要加锁或数据库行级锁,这属于实现层,但需求阶段就该把"同一时刻"这句话标注成需要事务保证,不然评审时说"同一时刻",开发时各写各的。

参数上要留意:borrowed计数与借阅记录表存在冗余,这是为了查询性能刻意做的反范式设计。代价是每次借还都必须双写,一旦某次写失败就会出现计数与记录不一致。我的习惯是把计数改成由记录表聚合查询得出,或者至少加一个定时对账任务,别让两个真实来源互相打架。

3. 数据流图分层与数据字典:从顶层图推到二级图的具体画法

面向数据流的分析方法落到交付物,主要是分层数据流图加数据字典。课件里"物理模型 → 逻辑模型 → 目标系统逻辑模型 → 细化"这条线,对应的就是 DFD 的逐层分解:顶层图只画系统和外部实体,一级图展开主要加工,二级图再把每个加工拆细,直到每个加工都能用一段结构化描述说清。

分层的关键纪律是父子平衡:父图上某条数据流的输入输出,在子图里必须原样出现,不能凭空多出或消失。这条纪律听着教条,实际是抓需求遗漏最有效的检查手段。图书馆案例的顶层图有两个外部实体——图书管理员和普通读者,中间一个加工"图书馆管理系统",数据流是借阅请求、检索请求、操作结果。到一级图,加工拆成借还处理、图书维护、检索服务、借阅追溯四块,数据存储出现图书表、读者表、借阅记录表三个。

3.1 顶层图与一级图的平衡检查清单

画完一级图别急着往下拆,先做一次平衡核对。下面这张清单是我每次评审前都会过一遍的,五个问题能挡掉大部分返工:

检查项判定标准图书馆案例中的对应点
外部实体一致性顶层图与一级图的外部实体集合相同管理员、读者两个,不多不少
数据流守恒父图每条输入输出在子图中出现借阅请求必须流入借还处理
数据存储无凭空产生每个存储至少有一个写入加工和一个读取加工借阅记录表由借还处理写、由追溯读
加工命名动宾化加工名是"动词+名词",不出现"数据"这类空词"校验借阅资格"合格,"处理数据"不合格
无孤立数据流每条流都有源和宿归还确认流向管理员

第三项最容易被忽略。很多人画图时把"读者表"画上去,但没有任何加工往里写数据,这张表就成了装饰。要么补上读者注册加工,要么把它从本层图里删掉,留到后续迭代。

3.2 数据字典的条目写法与一致性校验脚本

DFD 只说明数据怎么流,说不清数据长什么样,这部分靠数据字典补。数据字典的条目分四类:数据流、数据元素、数据存储、加工说明。每条定义用"="、"+"、"[]"、"{}"这套记号描述结构,比如借阅记录可以写成"借阅记录 = 读者号 + 图书编号 + 借出日期 + 应还日期 + 归还日期"。

字典最怕的是与图脱节:图改了,字典没改,两边各说各话。手工核对不现实,写个小脚本做交叉校验更靠谱。下面这段读两份文本,一份是数据流清单,一份是字典条目,检查每条流是否都有定义:

import re def load_flows(path: str) -> set[str]: """读取数据流清单,每行一条流名称""" with open(path, encoding="utf-8") as f: return {line.strip() for line in f if line.strip()} def load_dict_entries(path: str) -> set[str]: """从数据字典中提取已定义的条目名,形如 '借阅记录 = ...' """ entries = set() with open(path, encoding="utf-8") as f: for line in f: m = re.match(r"^\s*([^=\s]+)\s*=", line) if m: entries.add(m.group(1)) return entries def check(flows_path: str, dict_path: str) -> None: flows = load_flows(flows_path) defined = load_dict_entries(dict_path) # 图中出现但字典未定义的流,是需求评审最该追问的部分 missing = flows - defined # 字典里有但图中没有的条目,通常是删图后忘记清理的残留 orphan = defined - flows print("未定义的数据流:", sorted(missing) or "无") print("字典中孤立条目:", sorted(orphan) or "无") if __name__ == "__main__": check("flows.txt", "data_dict.txt")

逻辑很直白:两个集合做差。missing是图里有、字典没有的流,这类条目在评审时最危险,因为没人说得清它的结构,开发到一半才发现字段缺失。orphan是删改后留下的僵尸条目,不影响功能但会误导后来人。参数上唯一要改的是文件路径和字典行的格式约定,如果你的字典用 Markdown 表格维护,把正则改成按竖线切分就行。

提示:这套校验只查"有没有",不查"对不对"。数据流的结构是否与数据存储字段吻合,还得靠人工比对,脚本只负责把遗漏摊到桌面上。

4. 功能性需求与非功能性需求的边界:图书馆案例里那些没写进图的东西

课件把用户需求分成功能性需求和非功能性需求两类,前者说系统做什么,后者说系统工作时的特性。图书馆案例的五条功能全是功能性的,但真正决定这个系统能不能用的,往往是没画进 DFD 的那部分:检索响应时间、并发借阅的吞吐、借阅记录保留多久、读者信息谁能看。

这部分最容易被当成"以后再说",然后在验收时变成扯皮点。我的做法是在需求阶段就建一张非功能性需求表,每条给出可测量的指标和验证方式,哪怕指标是拍脑袋定的,也比空着强。比如检索功能,写"按作者名检索应在 2 秒内返回前 50 条",比写"检索要快"有用一百倍,因为前者能在联调时直接测,后者只能靠感觉吵架。

4.1 非功能性需求的四类落点与量化写法

课件列了性能需求、环境需求、界面需求、用户因素四类,图书馆案例可以逐类落成具体条目:

类别课件中的关注点图书馆案例的量化写法验证方式
性能响应时间、吞吐量、存储容量检索响应 ≤ 2s;并发借阅 ≥ 20 请求/秒压测脚本统计 P95
环境操作系统、网络、数据库单机部署,浏览器访问,无需外网部署清单核对
界面数据格式、存储介质规定检索结果按书名、作者、状态三列展示原型走查
用户因素用户类型、熟练程度、误操作可能读者端仅两个入口,误操作需二次确认可用性测试

这张表的作用不是凑文档,而是把"系统必须满足条件"这类模糊表述逼成可验证项。课件里说"一个读者一次借出的数目不能超过预定值",这个"预定值"到底是多少、谁来改、改了要不要即时生效,都属于非功能性范畴,得单独约定。

4.2 用状态表固化"一本书同一时刻只能有一种归属"

借阅状态是这个系统里最容易出 bug 的地方,因为它是并发写入的热点。与其在代码里到处加 if,不如先把状态和合法迁移列成表,让所有加工共用一份判定:

当前状态触发动作目标状态前置条件失败处理
在库借书借出读者未达上限拒绝并提示原因
借出还书在库存在未归还记录提示无有效借阅
在库注销已注销无未归还记录拒绝注销
借出注销不允许—提示先归还

状态表定下来后,DFD 里的"校验借阅资格"加工就有了明确输入输出,数据字典里的图书状态字段也有了取值域。这套东西看着笨,但它把课件里"同一时刻一本书不能既被借出,又被借阅"这句自然语言变成了可测的规则。血泪经验是:状态迁移表如果不提前画,开发阶段每个模块都会自己发明一套判断,最后合并时冲突到怀疑人生。

5. 避坑与常见问题:从课件方法落到真实项目时的五处翻车点

课件讲的是方法,方法本身没错,错在落地时的简化。下面五条都是我在类似小型管理系统里真实踩过或见过的问题,按现象、原因、解决三段写,方便对照自查。

5.1 把物理模型当需求,图纸画得越细离需求越远

现象:需求文档里全是"管理员在后台列表页点击新增按钮,弹出表单填写 ISBN"这类描述,评审时业务方点头,开发完却说不是想要的。

原因:停在了物理模型层,把界面交互和操作步骤当成了需求。课件里"去掉具体模型中的非本质因素"这一步被跳过了,导致实现细节污染了逻辑模型。

解决:每条需求回问一句"这条描述去掉界面和操作顺序后,还剩什么"。剩下的是数据和处理规则,那才是逻辑模型该有的内容。物理细节留到设计阶段,需求文档里最多作为参考附注。

5.2 DFD 父子图不平衡,需求缺口在评审后才暴露

现象:顶层图有一条"借阅请求"流进系统,一级图里却找不到对应加工,或者一级图凭空多出一条顶层没有的数据流。

原因:分层是分批画的,画子图时顺手加了新功能,忘了回改父图。人多协作时更严重,各画各的。

解决:每层图画完立刻做父子平衡核对,用第 3 章那张清单逐项过。工具层面可以让 DFD 绘图软件做自动校验,但自动校验只查结构不查语义,数据流的名字对不上照样通过,所以人工核对命名一致性不能省。

5.3 数据字典与图脱节,字段缺失在上线前才被发现

现象:开发到一半发现借阅记录缺"归还日期",或者检索功能需要的"专业领域"字段在图书表里根本没有。

原因:图改了字典没改,或者字典是最后突击补的,补的时候照着图抄,图本身就有遗漏。

解决:字典与图同源维护,改图必须同时改字典,用 3.2 那段脚本做差集检查,把缺失条目在每次评审前打印出来。更彻底的做法是把数据字典当成唯一事实来源,图从字典生成,虽然前期麻烦,但后期省下的返工远大于投入。

5.4 忽略角色与数据权限的绑定,追溯功能成了隐私漏洞

现象:功能 5"找出最近借走某本图书的读者"做出来之后,普通读者也能调用,能看到别人借了什么书。

原因:课件明确写了功能 4 供普通读者、功能 1、2、5 供管理员,但建模时角色只画在用例图上,没有落到数据流的激活权限上,开发时接口一律不加校验。

解决:在数据字典里给每个数据存储标注读权限和写权限,在 DFD 上给每条流入敏感存储的流标注触发角色。接口层再做一次角色校验,两层都做不是冗余,是防止某一层被绕过。这类问题属于设计缺陷而非编码 bug,测试阶段很难覆盖到,只能靠建模时想清楚。

5.5 约束条件写成自然语言,并发场景直接失效

现象:单机测试全通过,两个人同时借同一本书时都成功了,库存变成负数或者出现两条借出记录。

原因:"同一时刻一本书不能既被借出又被借阅"这句话在文档里是约束,在代码里没有对应的事务或锁,校验与写入之间存在时间窗口。

解决:需求阶段就把这类约束标注为"需事务保证",并在数据字典里写明该书状态字段的更新必须原子。实现层用数据库行锁或乐观锁版本号,别指望应用层先查后写能挡住并发。这条坑的教训是:凡出现"同一时刻""同时""不超过"这类词,都要单独拎出来问一句"并发下还成立吗"。

6. 从课件到交付:用一份需求追踪矩阵收口

课件最后停在"需求分析的验证",但没给具体验证手段。真正让这套方法闭环的,是一份需求追踪矩阵:把每条功能需求、每条约束、每条非功能性指标,映射到 DFD 的加工编号、数据字典条目和验收用例编号。矩阵不需要工具,一张表就够,但它是唯一能回答"这条需求到底有没有被实现"的东西。

我的做法是三列对齐:需求编号一列,对应的一级图加工名一列,验收用例编号一列。中间再插两列,一列写涉及的数据存储,一列写触发角色。填不满的行就是缺口,要么需求没落图,要么图没落测试。图书馆案例填完大概长这样:

需求编号加工数据存储触发角色用例编号
F1 借书借还处理图书表、借阅记录表、读者表管理员TC-01
F4 检索检索服务图书表读者、管理员TC-04
F5 追溯借阅追溯借阅记录表、读者表管理员TC-05
C2 唯一借出借还处理图书表—TC-11

矩阵填完后还有一步验证容易被跳过:拿用例反查需求。正向填表只能证明"每条需求都有落点",反向走一遍才能发现"每个加工是否都有需求支撑"。一级图里如果有个加工在矩阵里找不到对应需求行,那它要么是多余设计,要么是某条需求被漏写了——两种情况都值得停下来查。

再补一个具体技巧:约束类需求(比如"借出数量不超过预定值")不要只挂在一个加工上,它往往横跨借书、还书、追溯三个加工,矩阵里应该出现多次。只挂一处的结果是,开发在另一个加工里忘了校验,测试也只测了挂靠的那个入口。我一般会在矩阵下方加一行备注,写明该约束的全部生效点,评审时逐点确认。

从那以后我每次做这类小型信息系统的需求分析,都会强制走一遍"物理模型剥离 → 分层 DFD → 字典差集校验 → 追踪矩阵反查"这四步,哪怕项目再小也不省。省掉的每一步,后面都会以返工的形式还回来。这份课件的价值不在它讲了多深的理论,而在于它把一个完整案例的推演过程摊开给你看,照着走一遍,比读十篇方法论都实在。希望帮到你。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询