数据流图(DFD)考点梳理:软考系统架构设计师复习笔记

这篇笔记是为软考系统架构设计师准备的,主题是结构化分析里最核心的工具——数据流图,英文 Data Flow Diagram,简称 DFD。写它有两个目的:把这个考点从头捋一遍,再把案例题的破题思路固定下来。

DFD 初看简单,四个符号而已;但软考恰恰爱在「细节」上挖坑:什么关系该用什么符号、父图子图怎么平衡、数据字典里的加号和逻辑关系里的加号为什么不一样。这些点不单独拎出来想清楚,考场上容易错。所以这篇按考点顺序走,而不是按「画图入门」的顺序走。

先看清:软考里 DFD 考什么

系统架构设计师的案例分析,第一题基本是结构化分析:题干给一段需求描述,再给一张或多张不完整的 DFD,让你补全。翻来覆去就考这几样:

  • 补外部实体、补数据存储、补遗漏的数据流;
  • 判断错误或多余的数据流、多余的文件;
  • 补充数据字典条目。

要答对,光会认四个符号不够,得分层、平衡、设计原则、数据字典这四关都过了才行。下面按这个顺序,一条条过。

一种图,四个符号认全

先看一个最简单的场景:一个客户下一单,系统处理这个订单,然后把它存进订单表。画出来是这样:

flowchart LR C[客户] -->|订单信息| P1((处理订单)) P1 -->|新订单| D1[(订单表)]

这张图里一共出现四种东西,DFD 的全部零件就这四种,任何一张复杂的数据流图,都是把它们放大、组合起来的结果:

外部实体(External Entity)——站在系统外面的东西,负责给系统送数据、或者从系统拿数据。人(客户、管理员)、别的系统(支付平台、邮件服务)都算,画成矩形。区分它的关键是「边界」:先想清楚你要画的这个系统边界在哪,边界外的人和系统,就是外部实体。

加工(Process)——把一种数据变成另一种数据的地方,画成圆。名字用动词短语(「处理订单」「检查库存」),再带个编号,方便后面展开分层。判断一个东西算不算加工,看「变换」:输入进去啥样、出来还是啥样,那它只是过道,不该出现在图上。

数据存储(Data Store)——数据停下来、被保存的地方,比如数据库表、文件、缓存,画成两条平行线。它是被动的,自己不会动数据,一定得靠某个加工去读它或写它。名字用复数名词(订单表、用户表)。

数据流(Data Flow)——正在移动的一包数据,画成带箭头的线,箭头上标名字。名字写的是「内容」而不是「通道」:写「订单信息」,别写「HTTP 请求」或「邮件」。每条数据流都必须有名字,没有名字的箭头在 DFD 里等于一个 bug。

四种符号的样子看这张图:

四种 DFD 符号:外部实体、加工、数据存储、数据流

四样东西里,最容易用错的是「数据流」的命名。整个图都在讲数据,箭头名字一定要具体到「什么东西」,别写「data」「信息」这种说了等于没说的词。

箭头的方向,就是数据的流向

认完四个符号,还得知道它们之间靠什么连。规则不复杂:箭头方向代表数据流向,箭头上的名字代表流的是什么。四种符号之间能出现的连线,一共五种:

  • 外部实体 → 加工:把数据送进系统(输入)。
  • 加工 → 外部实体:把数据送出去(输出)。
  • 加工 → 加工:数据在系统内部从一个处理流到下一个。
  • 加工 → 数据存储:把数据写进去。
  • 数据存储 → 加工:把数据读出来。

其中「读」和「写」尤其容易漏——它们是两条方向相反的箭头,不是一回事。一个「处理订单」的加工,既要读库存表看有没有货,扣减之后又要写回去,画出来是两条线:

flowchart LR D1[(库存表)] -->|现有库存| P((处理订单)) P -->|库存变动| D1

别画成一条双向箭头。DFD 里每条数据流都有明确方向,读和写是两件不同的事,就分成两条线写清楚。

命名上再补一句:箭头名字永远写「正在流动的那包数据」,跟方向无关。「现有库存」是读出来的结果,「库存变动」是写进去的变化,两个名字不一样——这正好印证了后面要讲的「加工的输出不该和输入同名」。

输出流之间的三种逻辑关系

接上一条,一个加工如果同时有好几条输出,它们之间还可能有一层「组合关系」。软考在这一点上出过不少判断题,用三个符号标注:

符号关系含义
*与(AND)几个输出会同时产生,全都要
+或(OR)几个输出里至少产生一个
异或 / 互斥(XOR)几个输出里有且仅有一个产生,二选一

反过来,把这几条当成输入也一样:* 表示几条输入到齐才能加工,+ 表示任一条到了就能加工, 表示有且仅有一条到了才加工。

举个互斥的例子:一个「结算订单」的加工,处理完后要么生成「发票」、要么生成「退款单」,不会两个都出——这就是输出流之间的互斥关系,标

这里要和流程图的「判断分支」分清:流程图的分支是「先判断、再决定走哪条」,有先后、是控制流;DFD 里的 只是说「这几条输出里最终只会出现一条」,不表达先后,箭头本身仍然是数据流。所以「别画控制流」这条规则没被推翻, 只是多标了一层「输出怎么组合」的约束。

和流程图分清,这是两道不同的题

对 DFD 最常见的误会,是把它当成「讲数据的流程图」。这两个图画的是完全不同的问题。同一段下单场景,流程图和 DFD 长这样:

flowchart TD A([开始]) --> B[接收订单] B --> C{是否已支付?} C -->|是| D[保存订单] C -->|否| E([结束]) D --> E
flowchart LR C[客户] -->|订单信息| P((处理订单)) P -->|订单记录| D[(订单表)]

上面那张问的是「按什么顺序走、在哪个点分叉」,有菱形判断框、有开始和结束;下面那张问的是「什么数据在动、存在哪」,没有时间概念,没有判断、没有循环、没有起止。

一个快速判断的口诀:当你想画一个「是不是」的菱形框,或者想给步骤标先后,你要的是流程图;当画着画着冒出「这条数据存到哪张表」「要不要跟哪个外部系统打交道」,你要的是数据流图。真实系统往往两张都要——DFD 管数据骨架,流程图管某一条具体路径。

分层和编号:大题的地基

DFD 是分层画出来的,先画最外面一层,再一层层往里钻。分层的两条硬性规则——怎么编号、能不能平衡——直接决定了案例题里你能不能补对数据流。

第 0 层,叫上下文图(context diagram)。 把整个系统当成一个圆,外面摆上所有外部实体,只画出跨过系统边界的那些数据流。拿在线书店举例:

flowchart LR E1[客户] -->|下单信息| S((在线书店)) E2[支付平台] -->|支付结果| S S -->|派送单| E3[仓库] S -->|通知邮件| E4[邮件服务]

这张图简单,但它逼你回答两个问题:什么东西在系统里面,什么东西在外面。这个边界就是全部重点——连自己的系统边界都说不清,后面谁都画不下去。

第 1 层。 把那个圆圈拆成几个主要加工(一般 3 到 7 个),外部实体原封不动,数据存储在这一层第一次出现:

flowchart LR E1[客户] -->|订单信息| P1((1.0 检查订单)) P1 -->|有效订单| P2((2.0 收款)) E2[支付平台] -->|支付结果| P2 P2 -->|已付款订单| D1[(订单表)] D1 -->|待发货订单| P3((3.0 发货)) P3 -->|派送单| E3[仓库] P4((4.0 通知)) -->|通知邮件| E4[邮件服务] D1 -->|订单状态| P4 D2[(库存表)] -->|可用库存| P1 P3 -->|库存变动| D2

对照这两张图能看出一个规律:从第 0 层拆到第 1 层,外部实体的集合没变(还是客户、支付平台、仓库、邮件服务),变的只是圆圈的内部。这个性质叫「平衡」——父图里某个加工进出的数据流,必须和它子图边界上的数据流在数量和名字上对得上。它就是别人检查你有没有把数据凭空造出来、或者偷偷弄丢的办法,也是补数据流题最核心的一句依据。

编号规则,软考有明确规定:

  • 顶层图(上下文图)只有一张,加工只有一个,不用编号。
  • 下面一层(0 层图)只有一张,加工编号用 1、2、3…
  • 某个加工继续往下拆,子加工编号就是「父编号 . 子序号」。加工 3 拆成三个,就是 3.1、3.2、3.3;3.2 再拆,就是 3.2.1、3.2.2。

点号的意思就是父子:左边是父加工,右边是这一层的序号。看到 3.2.1,就知道它是「3 的儿子 3.2 的儿子」。前面图里用的 1.0 / 2.0 是 Yourdon 风格的另一套写法,本质一样,都是靠点号划层级;软考大题里按 1、2、3 和 3.1、3.2 这套更常见。

画图的顺序,自顶向下三步走:

  1. 画顶层图:整个系统当成一个加工,先定外部实体,画出跨边界的数据流。
  2. 画 0 层图:把那个大加工拆成几个加工,用数据流连起来,让「顶层的输入」经过若干加工后变成「顶层的输出」。
  3. 对还需要细化的加工重复第 2 步,继续画子图,直到剩下的每个加工都简单到不用拆。

判断一个加工要不要继续拆,有一条经验:在「数据流的组成或值发生变化」的地方,就藏着一个加工。把「一起到达、一起被处理」的几个数据,当成同一条数据流。

九条设计原则,错误数据流就靠它们排查

DFD 的规则列出来有一堆,但背后就一句话:数据不会自己动,只有加工能转换数据。下面九条都是它的自然结果,也是判断题里排查错误/多余数据流的依据。

  1. 虚线外禁行。 外部实体不能直接连外部实体,数据存储不能直接连数据存储,外部实体也不能直接连数据存储。数据的流动中间必须经过一个加工——实体在系统外够不到你的数据库,存储自己也不会挪地方。
  2. 每条数据流都要命名,写内容、不写通道。
  3. 每个加工必须既有输入又有输出。 只有输入的加工是「黑洞」(数据进去就没了),只有输出的加工是「奇迹」(数据凭空变出来),都算画错。
  4. 数据守恒。 一个加工所有输出的数据,必须能从它的输入里直接得到、或者由它加工产生。输出凭空多出来的字段,说明漏画了某条输入。
  5. 数据存储要有读有写。 在整套图里,每个数据存储必须既有读的数据流、又有写的数据流;单独某一张子图里可以只读或只写。
  6. 加工的输出流不该和输入流同名,哪怕组成一模一样。同名会让读图的人分不清哪个进、哪个出。
  7. 分层要平衡,前面讲过。
  8. 画数据流,别画控制流。 想表示「如果满足条件就走这条路」,那是流程图的事,别塞进 DFD。
  9. 局部文件别上父图。 某个数据存储首次出现时,如果只和一个加工有关,就当它是这个加工的内部文件,别画在父图里,留到子图再画。这条直接是「找多余文件」那类题的判断依据。

这些规则合起来,保证的是同一件事:图上的任何一个箭头,你都能说清「什么东西、从哪、经过谁的转换、到哪」。说不清的,就是还没画完。

数据字典:图上的名字靠它收尾

DFD 画得再清楚,也只是一张图。图上每个名字到底指什么、包含哪些字段,得靠数据字典(Data Dictionary)说清。软考经常把 DFD 和数据字典合在一起考。

数据字典要定义四类东西:

  • 数据流条目:一条数据流由哪些数据项组成。比如「订单 = 订单号 + 客户号 + 商品列表 + 金额」。
  • 数据存储条目:一个存储的结构,通常还要指出关键字。比如「订单表」的关键字是「订单号」。
  • 数据项:不可再拆分的最小数据单位,写名称、类型、取值范围。比如「订单号:由数字组成的 8 位编号」。
  • 加工条目:这个加工具体做什么,用自然语言、判定树或判定表描述。

定义时用一套符号,软考常考:

符号含义
=定义为 / 由…组成
+与(顺序连接)
[a 或 b]或,方括号里二选一
{ }重复,花括号里内容重复 0 到多次
( )可选,括号里内容可有可无

比如「订单 = 订单号 + 客户号 + {商品项} + (备注)」,意思是订单由订单号、客户号、若干商品项、以及可选的备注组成。

这里藏着一个最容易踩的坑:数据字典里的 + 表示「与」(顺序连接),但前面讲的数据流逻辑关系里,+ 表示「或」,* 才表示「与」。两套符号长得像、含义还错位了,软考专门爱在这个地方挖坑。记一句就绕得开:字典里 + 是连接,逻辑关系里 * 是同时

两种记法,认得就行

DFD 有好几种画法(记法),最常用的两种符号长得不一样,但意思完全一样:

Yourdon/DeMarco 与 Gane-Sarson 两种 DFD 记法对比

  • Yourdon/DeMarco:加工是圆,数据存储是两根平行线,外部实体是矩形。教材和软件工程课里最常见,也是这篇一直用的那套。
  • Gane-Sarson:加工是圆角矩形,数据存储是一边开口的矩形,外部实体是带阴影的方块。在企业架构、业务分析里更常见。

真正的差别只在形状,语义一模一样。自己画的时候选一套用到底,但两套都要认得,免得换个工具或文档就看懵了。

另外常被问到「逻辑 DFD」和「物理 DFD」:逻辑图讲「系统做了什么」,物理图讲「具体怎么实现」(用哪台机器、哪个程序、哪支团队)。软考考的是逻辑图,别一开始就陷进实现细节。

题型和破题思路,照着套

案例题第一题的题干结构基本固定,题型就四类,主线一条条列:

  1. 补外部实体(E1、E2…)。 先圈出说明里所有「系统外的人 / 组织 / 系统」,再对照图里已有的实体。实体就是数据的来源或归宿。
  2. 补数据存储(D1、D2…)。 从说明里找「存入 XX 表」「记录到 XX 文件」这类字眼,存储的名字就是这些表和文件。
  3. 补遗漏的数据流(名称 + 起点 + 终点)。 这是最核心、也最难的一类,三条破法:先上下层图对照找「平衡」,父图某加工的输入输出,子图必须在数量和名字上对得上;再逐个检查每个加工是否既有输入又有输出;最根本的依据还是题目说明——说明里写的每个功能,图上都该有一条数据流来体现。
  4. 找错误 / 多余的数据流、多余的文件。 用「平衡」和前面那九条原则(数据守恒、输出不与输入同名、局部文件等)去排除;多余文件尤其盯「局部文件」那条——文件只和一个加工有关,却画在父图里,就是多余的。

做题顺序固定成一条流水线:先读说明(圈出实体和存储),再补顶层图,再逐层对照平衡,最后逐个加工、逐个存储查读写出入。按「说明顺序」或「数据流向」排查,别想起谁查谁。

还有两个几乎每次都挖的经典陷阱:

  • 第三方 Email 系统。 只要说明里出现「通过 Email 给客户发通知」,就必须在图上补一个「Email 系统」外部实体,通知类数据流要从它出,而不是直接发给客户。粗心的人最容易漏掉这个实体。
  • 通知类数据流别漏。 「提交成功要通知用户」「批改完要通知学生」这类描述,对应的是一条从加工到实体(或 Email 系统)的数据流,是最容易漏掉的一类。

结语:临考前的一页速查

这篇文章写下来,我记得最牢的一点:DFD 逼你先回答「边界在哪、数据从哪来到哪去」,后面那九条原则,都是这两问的自然展开。临考前扫一眼这几组关键词就够用:

  • 四种成分:外部实体(矩形,在系统外)、加工(圆,动词+编号)、数据存储(双线,复数名词)、数据流(箭头,写「内容」)。
  • 编号:顶层不编号,0 层用 1、2、3,子图用「父.子」——点号左边是父、右边是子。
  • 九原则里最常考三条:数据守恒、每个存储既有读又有写、局部文件别上父图。
  • 逻辑关系* 与(同时)、+ 或(至少一个)、 互斥(二选一);数据字典里 + 反而是「与」,别混。
  • 题眼:补数据流靠「父图子图平衡」+逐个查加工进出;「第三方 Email 系统」别漏画成实体。

真上了考场,先读说明圈出实体和存储,剩下的都在图里对平衡。

参考资料

版权声明: 本文首发于 指尖魔法屋-数据流图(DFD)考点梳理:软考系统架构设计师复习笔记https://blog.thinkmoon.cn/post/1039-notes-dfd-data-flow-diagram/) 转载或引用必须申明原指尖魔法屋来源及源地址!