数据流图DFD:符号语义、分层分解与父子图平衡
发布时间:2026/11/3 13:42:49 锦皓数字建站

简介围绕数据流图的入门与实例演练这份PPT面向软件工程、管理信息系统课程学习者及需要梳理系统逻辑的业务分析人员帮助其从符号含义、绘制步骤到分层图实例建立完整认知。内容以数据流、加工、数据存储、外部项四类基本元素为线索讲清命名、编号与避免交叉线等规范并给出从识别外部项、确定输入输出流到自顶向下逐层分解、检查完善的绘制流程。压缩包仅含1个PPT文件约312KB篇幅集中、便于课堂讲解或自学查阅。资源结合银行取款处理等实例展示关联图、顶层图与下层分解图的画法并提示数据流必须经过加工、数据存储作为界面安排、编号与布局等注意事项。已有626人学习适合作为DFD练习前的速查材料与案例参照。1. 数据流图为什么一张“不含技术”的图反而最难画对数据流图DFD最反直觉的地方是它主动剥离技术不谈表结构、不谈接口协议、不谈界面只留下“什么数据从哪来、被谁加工、存到哪、最后到哪去”。很多人第一次画数据流图觉得四个符号太简单画到第三层才发现难的不是画而是决定哪一层停手、哪个加工该拆、哪条流压根不该存在。它解决的其实是一件事让业务方和开发方在没有共同技术语言时对“系统要做什么”达成一致。它天生就是一只黑匣子把实现全部挡在外面也正因如此它在需求阶段被反复修改的成本极低——改一条流比改一张表便宜得多。2. 四个符号的语义边界F、P、D、S 为什么必须各管一摊数据流图只由四种符号构成数据流F、加工P、数据存储D、外部项S。看起来是四个图形实质是一套语法约束——每个符号只允许表达一件事不允许越界。新手画图时出现的绝大多数错误本质都是某个符号越界替另一个符号说话用数据流表达顺序用数据存储表达加工用外部项表达内部逻辑。这套约束不是为了好看是为了让图能被“形式化检查”也就是能靠肉眼或工具逐条勾对判断这张图是否自洽。2.1 数据流它描述的是“一次搬运”不是“一份数据”材料里对数据流的定义是“由一个或一组确定的数据组成”。这句话的关键词是“确定”——它必须是可枚举、可命名的一批数据项而不是“一些信息”这种模糊指代。画在图上一条带箭头的线代表某个东西从 A 被搬到 B箭头方向表达的是“谁给谁”而不是“先做哪个”。这一点被反复强调两个符号之间可以存在多条数据流数据流图并不表明它们之间的次序、主次关系。换句话说它画的是信息依赖不是执行顺序。命名规则直接决定图的可读性。数据流名要能直观反映含义通常是业务名词短语比如“取款单、存折”“明细帐”“汇总订单”而不是“输入”“处理结果”“数据”这类在图上到处都是的名字。材料还提到一条容易被忽略的规则数据流可以同名也可以有相同的数据结构但必须有不同的数据或不同的含义。我一般会这么理解——同名流在图上出现两次读者必须能靠上下文立刻分辨它们不是同一条如果分辨不了就该改名而不是在注释里解释。还有一条边界常被踩实物不是数据流。经典的取款例子里特意标注了“现金是实物不能作为数据流”。现金离开柜台是物流取款单、存折、结算清单才是信息流。数据流图只对后者负责把现金画进去等于在逻辑模型里混入了物理搬运图马上就失去了“与物理实现无关”这个最大价值。2.2 加工与数据存储谁改变数据谁只是被读写加工又称处理、变换表示对数据流的操作。符号分上下两部分上部分是标识部分写加工编号编号必须唯一以“P”开头下部分是功能描述部分写加工名。之所以要把编号和名字分开是因为名字会改、编号不能改——编号是跨图引用和变更影响分析的锚点。材料同时点明加工名要简单能概括说明加工行为即可详细描述放到数据词典里。这个分工非常重要图上写不下逻辑硬写会让图变成文字墙。数据存储用于存贮数据符号是开口的长方框名字写在框内概要说明其中主要数据编号写在左端小方格以“D”开头。分层数据流图里数据存储通常只属于某一层或某几层所以也被称作局部文件。材料给了一条硬性要求数据存储上一定要有数据流。我在实际审查时会把它加强成“既有流入也有流出”——只有流出说明数据凭空产生只有流入说明这份数据永远没人用两者都是漏画加工的典型症状。这两者的区别可以用词性记忆加工是动词性的负责改变数据数据存储是名词性的被动地被读被写。一个加工既能读某个存储又能写同一个存储是完全合法的取款处理就是既查帐目库又改帐目库。但如果两个加工之间直接拉一条数据流、中间不经过任何存储就要问一句这份数据不落盘吗很多业务里这个问题的答案恰恰是“必须落盘”漏了存储后面设计阶段就得补一个没人定义过的表。P2.3 随时处理优先订单 输入流 : F1 订单订单号、书名、数量、顾客号、订单类型 读取 : D7 优先订单 写入 : D3 待发出订单 加工逻辑: 按顾客号逐条判断订单类型为优先的记录生成待发记录不等批次 触发 : 随时不做定期合并这段是数据词典里一个加工条目的写法格式本身能说明问题图上只写“P2.3 随时处理优先订单”一行字所有字段、读写关系、触发条件全部落在词典里。代码块里的四条字段正好对应图上能画出来的东西输入流、读取、写入和画不出来的东西加工逻辑、触发。数据流图画“有没有”数据词典写“是什么”两者缺一模型就不完整。2.3 外部项系统边界钉死的地方外部项又称源点和终点是系统之外的实体存在于环境之中与系统有信息交流从源点进入系统的信息是输入从系统流向终点的信息是输出。同一个端点既可以是人也可以是其他系统。材料明确说引入源点和终点是为了便于理解系统所以不需要详细描述它们编号以“S”开头。“不需要详细描述”这句话经常被误读成“随便画”。恰恰相反外部项是整张图里最不能含糊的部分因为它定义了系统的承诺范围凡外部项内部的逻辑一律不画凡跨越边界的数据一律要显式画出。一个外部项与系统之间只能通过数据流相连而且这条流必须最终落到某个加工上——外部项直接连数据存储等于宣称“系统外的人可以直接读写我的库”这在逻辑模型层面是说不通的不管你实现上是不是真这么干。边界划错的代价是连锁的。外部项多画一个系统就多背一块本不该它负责的逻辑少画一个就会出现某个数据流“没有来源”的悬空箭头。我见过最常见的情形是把“上级主管部门”画成外部项却又在系统内部画了一堆“审批规则”加工——边界一旦这样定图就开始同时描述两个系统了。3. 分层分解从关联图到二层图逐层展开到底在收敛什么材料给出的绘制步骤是七步确定外部项 → 确定整个系统的输入输出流、把系统当一个加工画出关联图 → 确定主要信息处理功能、分解成若干加工并确定各自输入输出与相关数据存储 → 自顶向下逐层分解 → 重复直到分解结束 → 检查与合理布局 → 与用户交流确认。七步里真正的技术含量集中在前三步和第四步之间前三步在“定边界”第四步之后在“守住边界”。3.1 关联图先把整个系统压成一个加工关联图是最高层的一张图只有外部项、一个代表整个系统的加工、以及穿越边界的数据流不出现数据存储。这个“不出现存储”不是疏漏而是逻辑必然关联图描述的是系统与外界的信息交换数据存储属于系统内部的实现细节在这一层画出来等于提前把内部结构泄漏到接口定义里。取款例子的关联图很干净储户交出“取款单、存折”取款系统返回“存折、利率单、结算清单”两端都是同一个外部项储户只是分别充当源点和终点。图书预订例子同样干净顾客交“订单”系统给出版社发“汇总订单”。这两张图一旦画错后面所有层都要重画因为分解是在关联图定义的外部项和输入输出流基础上进行的。我一般会在这里做一次自检把关联图上的输入流和输出流各自读一遍读成一句人话——“系统接收 X产出 Y 给 Z”。如果这句话读不通或者需要加“然后”“之后”才说得通说明你在这一层就想表达时序了那是分解阶段该干的事。3.2 父子图平衡输入输出守恒是分解的唯一硬约束分解的核心约束是平衡父图中某个加工的输入流和输出流必须在它的子图中原样出现在子图的边界上。子图内部可以新增流那是内部细节但边界上的流一条都不能少、不能改名、不能换源。这条约束是整张图能够被逐层验证的基础——没有它分解就只是“画得越来越细”而不是“同一个系统被逐层展开”。用取款例子走一遍。父图上加工“取款系统”接收 F1“取款单、存折”输出 F2“存折、利率单、结算清单”。分解后子图有两个加工P1 取款审核接收 F1把合格件作为 F1.1 送 P2把不合格件作为 F1.2 退回储户P2 取款处理读改 D1 帐目库、写 D2 取款记录最终产出 F2。这里出现了一个需要说明的细节父图的 F1 在子图里被拆成了 F1.1 和 F1.2 两条流。严格按守恒读这属于“数据流被分解”而不是凭空新增。常见的实现思路是允许这种拆分但要求拆分后的数据项集合与父图那条流保持一致——F1.1 和 F1.2 合起来仍然覆盖 F1 的全部数据项只是按“合格/不合格”这个业务判定做了分流。这也是我判断一张子图是否真平衡的实用方法不只看箭头在不在还要看流里的数据项有没有被偷偷增减。检查项父图一侧子图一侧判定输入流是否齐全F1 取款单、存折P1 接收 F1通过输入流是否被分解F1F1.1 合格件、F1.2 不合格件通过数据项集合守恒输出流是否齐全F2 存折、利率单、结算清单P2 产出 F2通过是否新增跨界流无无通过加工编号是否继承P 取款系统P1、P2通过图书预订系统的例子把“分解不止一层”演得更充分。顶层图上P1 订单检查读 D1 图书目录、回退 F3 不合格订单P2 订单处理产出 D2 合格订单P3 发送订单读 D3 待发出订单和 D4 出版社要求输出 F2 汇总订单。到了二层图只有 P2 被继续展开成 P2.1 数目统计、P2.2 订单分类、P2.3 随时处理、P2.4 定期处理产出 D7 优先订单和 D8 正常订单。这说明分层不是全场通铺——每一层只展开那些“还说不清”的加工已经足够简单的 P1、P3 就停在顶层。3.3 分解到什么时候停基本加工的判定材料说“重复步骤直到逐层分解结束”但没说结束的标志是什么。这恰恰是新手最卡的地方也是最容易画过头的敌方。我一般会用三条判据来定基本加工一是单一职责一个加工只做一件能被一句话说清的事出现“并”“同时”“根据情况”就该拆二是数据词典能写死输入字段、输出字段、读写哪些存储在词典里能列全三是业务方能读懂把这张子图单独拿给提需求的人看他能指出哪条流不对。三条里最重要的是第三条。数据流图的目的是沟通如果一层图只有画图的人自己看得懂那它已经失去存在意义。实践经验是层级别超过三到四层再往下业务方就不看了图变成开发团队自娱自乐的产物这时候该换载体了——用数据词典写细节用状态说明写规则而不是继续往图上堆符号。分解还牵涉到一个顺序问题。材料的原则是“自顶向下、逐层扩展”但在实际作图时我习惯先用关联图把边界钉死再一次性把顶层图的加工列全然后挑最不确定的那一个先往下拆。理由是最不确定的加工往往藏着最多的未知业务规则它一旦拆通其他加工多半是重复劳动反过来先拆简单的容易在后期发现边界定义有问题前面全白画。4. 编号与布局一套命名体系怎么撑住几十张图的可维护性单张数据流图好画难的是十几张、几十张图放在一起还能查、能改、能对得上。材料在注意事项里专门提了编号原则部分提了合理布局这两条看起来像格式要求实际是分层模型的可维护性基础设施。4.1 编号P2.1 里的点号是一条继承链加工编号以 P 开头且必须唯一分解后的子加工用父编号加点加序号的方式命名父图上的 P2在子图里被展开成 P2.1、P2.2、P2.3、P2.4。这个点号不是装饰它编码了两条信息这个加工属于谁以及它在同级里的位置。看到 P2.3不用翻图就知道它是 P2 的第三个子加工再往下若出现 P2.3.1层级关系也是一眼可见。数据存储编号以 D 开头外部项编号以 S 开头两者在整份模型里全局唯一不随层变化。这种不对称是有道理的加工会随分解不断产生新编号必须挂在父编号下面才不会乱而数据存储和外部项是跨层的稳定实体同一份帐目库在顶层图和二层图上必须是同一个 D1改编号等于换了一个东西。编号真正的价值在变更管理上。业务方说“订单分类这块规则要改”你从 P2.2 这个编号出发能立刻定位到它所在的子图、它的父加工 P2、它读写的 D6 和 D7/D8以及依赖这些数据的所有下游加工。没有编号这套追溯只能靠记忆有了编号改动影响面是可以被机械枚举出来的。4.2 数据存储重复绘制用重复换掉交叉线材料提到一条很实用的规则为避免数据流图中出现交叉线同一数据存储可以在多处画出用专门的重复符号表示。具体做法是在开口长方框的左端再加一条竖线表示“这是同一个存储的另一次出现”编号仍用同一个 D 编号。这条规则背后的取舍很清楚交叉线是图可读性的头号杀手一条线从左上角斜穿到右下角中间跨过三四个符号读者必须反复追踪才能确认它连的是谁。而重复绘制一个方框的成本极低只要编号一致语义上没有歧义。用重复换交叉本质是用“符号冗余”换“路径清晰”。代价也很明确同一个存储在图上出现多次命名漂移的概率直线上升。一处写“帐目库”另一处写“账户台账”读者很难判断这是同一个还是两个。约束手段就是把 D 编号当唯一标识名字只是注释——编号相同就是同一个名字不一致属于要修的瑕疵而不是两个实体。4.3 布局与检查从左到右的信息流合理布局是材料列出的四条绘制原则之一但没展开。按数据流图的一般惯例布局服务于“读图动线”输入类外部项放在左侧输出类外部项放在右侧加工居中数据存储放在被它服务的加工附近数据流整体保持从左向右的走向。这不是审美问题而是让读者能顺着一个方向读完整个流程不用来回跳。检查环节材料列得很细分解是否恰当、彻底各层是否有遗漏、重复、冲突各层之间及同层各图之间关系是否正确命名与编号是否确切、合理。这几项可以整理成一张可执行的勾对表按图逐项过边界流是否与父图一致每个数据存储是否既有流入又有流出每个加工是否至少一进一出是否存在外部项直连存储是否存在没有来源的流编号是否与词典一致。这套检查做完图基本就能拿去和用户对话了。最后一步“与用户交流”是流程的一部分不是可选项。材料把它写成“在用户完全理解数据图的内容的基础上征求用户的意见”这句话的重心在“完全理解”——图没被读懂收集到的意见就是噪音。5. 常见问题排查五个让我返工的 DFD 错误这一节是我自己的血泪经验汇总按“现象 → 原因 → 解决”整理。这几类错误在评审里出现频率极高而且大多不是画功问题是语义理解偏了。5.1 把实物当数据流画进图里现象图上出现“现金”“货物”“纸质发票”这类箭头从外部项直通加工。原因把业务动作原样搬进信息模型没有做“物流/信息流”的分离。数据流图描述的是信息运动实物搬运属于物理层。解决把实物抽象成触发它的单据或记录比如取款业务里画“取款单、存折”而不画现金确实需要说明实物交付的写在图外的注释或数据词典条目里不占符号。5.2 外部项直连数据存储现象一条线从 S1 客户直接连到 D1 帐目库中间没有任何加工。原因脑子里想的是实现画面——“客户查库”于是照着实现画。解决任何跨越系统边界的数据流都必须经过加工中间补一个“查询处理”P输入是查询请求输出是查询结果读写 D1 发生在加工内部。这条规则的实质是系统对外只暴露加工不暴露存储。5.3 父子图不平衡现象父图上某加工明明有 F3 输出翻到子图找不到这条流或者子图凭空多出一条流向外部项的流。原因分解时顺手改了接口却没有回头同步父图改到第三层时前面的图已经对不上了。解决每画完一张子图立刻拿出父图逐条勾对边界流重点看三件事——输入流齐不齐、输出流齐不齐、有没有新增跨界流。发现不一致时先判断是子图画错还是父图该改永远先改上游别在下游打补丁。5.4 数据存储被当成两个加工之间的传话筒现象两个加工之间没有直接数据流各自连一条线到同一个数据存储图上看起来像是“通过存储通信”但存储既没有被写入的明确来源也没有明确的下游消费者。原因把存储当成了管道而不是数据本身。材料的原则是“数据存储环节一般作为两个加工环节的界面来安排”——它是一条明确的分界线不是一个模糊的连接器。解决明确谁写、谁读、写什么字段如果确实只是临时传递、不需要持久化那就应该是一条直接的数据流而不是一个存储。5.5 命名空泛图看得懂形状却看不懂业务现象加工叫“处理数据”“业务处理”数据流叫“信息”存储叫“数据文件”。原因画图时把详细描述都推给数据词典结果词典也没写。解决加工名用动词加宾语例如“订单检查”“订单分类”“发送订单”数据流名用业务名词例如“不合格订单”“汇总订单”存储名概括其中的主要数据例如“图书目录”“待发出订单”。判断标准很简单把图上的名字连起来读能不能读出这个系统在干什么。读不出来就是命名没做到位。6. 设计取舍DFD 主动丢掉的东西才是它好用的原因数据流图最值得琢磨的设计决定是它主动放弃表达能力。它不表达时序两个符号之间可以有多条流图不说明先后、不表达控制没有判断分支、没有循环、没有触发条件、不表达数据结构的细节那是数据词典的活、也不表达物理实现。把这些全部拿掉之后剩下的是唯一一样东西信息依赖。谁产出这份数据谁消费这份数据中间经过哪些变换和存放。这个取舍在需求阶段极其划算因为需求阶段变化最频繁的恰恰是控制和实现而信息依赖相对稳定。业务规则从“三天内处理”改成“当天处理”加工逻辑变了、时序变了但订单从顾客到出版社这条依赖链没变图基本不用重画。反过来如果把时序画进图里任何一次规则调整都会引发大面积改图模型很快失去可信度。模型表达重点变化时的影响面适合阶段数据流图信息依赖与变换小规则变化通常不动图需求分析、逻辑建模流程图执行顺序与分支大顺序一变整图重排详细设计、算法说明状态图状态与迁移条件中状态集稳定时影响小交互逻辑、设备控制实体关系图数据之间的静态关系中结构变更需同步数据库设计失效边界同样清楚。强时序系统、实时控制、带大量状态机的业务用数据流图描述会非常别扭因为它的语法里根本没有“何时”这个维度。这时候该换模型而不是硬往图上加符号——加了制动符号的 DFD 就不再是 DFD也失去了它最大的好处能被非技术人员读懂。验证一张图是否真的守住了取舍我有个笨办法把图给一个完全不懂技术的人看让他复述“这个系统收到什么、发出什么、中间存了哪些东西”。如果他复述得出来说明边界和信息依赖都画对了如果他开始问“那先做哪个”说明你在图上暗示了顺序得回去检查是不是哪里多画了箭头或者名字带了动作感。从那以后我每次动笔画数据流图都会强制先只画关联图把外部项和跨界流钉死再往下走一层分解过程中每完成一张子图就回头拿父图勾对一遍边界流宁可多花十分钟也不吃后期返工的后悔药。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。