跳到正文

数据流图示例:上下文图、0 层图和 1 层图

以一家网店为例讲解数据流图:两种记法下的 DFD 符号、上下文图、0 层与 1 层、平衡规则和常见错误。

· 创始人兼开发者

发布于

中间是 Customer、Payment provider 和 Warehouse 三个方框。左边的上下文图框架中只有一个处理 Online store,它与这些实体交换带名称的数据流。右边的 0 层框架中有 Take order、Process payment 和 Fulfil order,以及 Orders 和 Products 数据存储。

数据流图(DFD)展示信息如何在系统中流动:它从哪里来,被什么转换,存放在哪里,又流向哪里。它不涉及时序和循环,也不说明哪台服务器运行什么,而这恰恰是它的优势。DFD 是就“系统处理哪些数据”达成共识的最快方式,所以它常出现在需求分析、隐私评审和威胁建模中。

本文先介绍两种经典记法下的 DFD 符号,然后用一个例子(一家网店)走完三个层次:上下文图、0 层图和 1 层图。文中还会解释围绕“0 层”的命名混乱、让各层保持一致的平衡规则,以及评审者会重点检查的错误。

DFD 符号

DFD 使用四种元素。主流记法有两种,都来自 20 世纪 70 年代末的结构化分析书籍:Yourdon 与 DeMarco 记法,以及 Gane 与 Sarson 记法。

元素 含义 Yourdon 与 DeMarco Gane 与 Sarson
外部实体 位于边界之外、发送或接收数据的人、组织或系统 矩形 正方形,常带阴影
处理 转换数据的工作 圆形(气泡) 带编号栏的圆角矩形
数据存储 静止的数据:表、文件或队列 两条平行线 一侧开口的矩形,带有 D1 这样的编号
数据流 流动中的数据,用名词命名 箭头 箭头

两种记法是等价的,选一种并坚持使用。许多现代工具把数据存储画成圆柱体,读者一眼就能认出。无论选哪种,都要加上图例。

让 DFD 合法的规则

  1. 每个处理至少有一个输入和一个输出。 只有输入的处理是黑洞,只有输出的处理是奇迹。
  2. 数据只能经由处理流动。 不允许有数据流直接从外部实体流向数据存储、从一个数据存储流向另一个,或在两个外部实体之间流动。
  3. 数据流的名称要描述数据,例如“订单详情”或“支付结果”,而不是“发送”或“检查”这样的动作。
  4. 处理以动词加宾语命名:“接收订单”“履行订单”。
  5. 每个处理都要编号,分解后的子处理沿用该编号:处理 1 分解为 1.1、1.2 和 1.3。

层次,以及 0 层的混乱

DFD 自顶向下绘制,细节逐层增加:

  • 上下文图把整个系统画成单个处理,周围是所有外部实体以及它们之间的数据流。它定义了系统边界。
  • 下一层把这个处理分解为主要处理,加入数据存储,并保持相同的外部数据流。
  • 更低的层次按需要继续分解单个处理。

混乱在于:有些教材和工具把上下文图称为“0 层”,把第一次分解称为“1 层”;另一些则沿用更早的结构化分析惯例,把上下文图看作独立的一层,把第一次分解称为“图 0”或“0 层”。两种说法都没有错。本文采用第二种惯例:上下文图,然后是 0 层,再是 1 层。无论你用哪种,都请在图上写明。

示例:一家网店

一家网店接收客户订单,通过支付服务商收款,并向负责发货的仓库发送拣货单。

上下文图

一个处理“0 Online store”,以及三个外部实体:

数据流 来源 去向
Order details Customer Online store
Order confirmation Online store Customer
Payment request Online store Payment provider
Payment result Payment provider Online store
Pick list Online store Warehouse
Shipment status Warehouse Online store

这就是从外部看到的整个系统。任何人一分钟就能看完,而它已经回答了重要的问题:哪些组织会收到客户数据,我们又依赖哪些系统。

0 层

把网店分解为三个处理和两个数据存储:

  1. Take order 从客户处接收订单详情,从 D2 Products 读取价格,把订单写入 D1 Orders,并把支付请求传给处理 2。
  2. Process payment 把支付请求发送给支付服务商,接收支付结果,更新 D1 Orders 中的订单,并把已支付的订单传给处理 3。
  3. Fulfil order 读取已支付的订单,把拣货单发给仓库,接收发货状态,并向客户发送订单确认。

上下文图中的每一条外部数据流都会在 0 层再次出现,并连接到相同的实体。这就是平衡,下面的图让它一目了然。

1 层

每个 0 层处理都可以继续分解。处理 1(Take order)的 1 层图如下:

处理 输入 输出
1.1 校验购物车 来自 Customer 的 Order details 有效的购物车
1.2 计算订单价格 有效的购物车,来自 D2 Products 的商品价格 已定价的订单
1.3 记录订单 已定价的订单 写入 D1 Orders 的新订单,发给处理 2 的支付请求

1.1 到 1.3 的输入和输出合在一起,必须与 0 层中处理 1 的输入和输出一致。每个 1 层分解都画成单独的图,并在标题中写上父处理的编号。

平衡:评审者最先检查的规则

当流入和流出子图的数据流与流入和流出其父处理的数据流相同时,子图就是平衡的。如果 0 层出现了一条上下文图中没有的“退款申请”数据流,那么两者之一必有错误:要么系统存在一个没人认可过的接口,要么上下文图不完整。平衡让 DFD 的各层作为一个整体值得信赖,检查也很容易:把每一层的外部数据流并排列出来即可。

常见错误

  • 画成了流程图。 判断、循环和表示“然后”的箭头属于流程图或 BPMN 图。DFD 展示的是数据,而不是控制流。
  • 数据流没有名称。 没有标签的箭头对评审者毫无意义,要写明它承载的数据。
  • 一张图里处理太多。 一层中超过大约七到九个处理就难以阅读。把它们分组,再在下一层展开各组。
  • 只接收数据的数据存储。 如果从来没有处理读取某个存储,它为什么存在?如果从来没有处理写入,它的数据又从哪里来?
  • 混用层次。 在同一张图上把详细的子处理和高层处理并列,会破坏层次结构。

DFD、流程图与架构图

数据流图 流程图 架构图
展示 数据及其来源、转换和存储 步骤、判断和顺序 组件、部署和连接
时间与顺序 无 有 很少
最适合 需求、隐私评审、威胁模型 规程与算法 设计与运维

DFD 是威胁建模的标准输入:在 0 层图上加上信任边界,就有了 STRIDE 评审的基础,威胁建模数据流图一文对此有详细介绍。它们在隐私工作中同样有用,GDPR 数据映射图就是沿着同类数据流追踪个人数据。

DFD 分层图

中间是 Customer、Payment provider 和 Warehouse 三个方框。左边的上下文图框架中只有一个处理 Online store,它与这些实体交换带名称的数据流。右边的 0 层框架中有 Take order、Process payment 和 Fulfil order,以及 Orders 和 Products 数据存储。

12 个组件 · 17 个连接

在 Archboard 中打开
图表内容
  • Context diagram
  • 0 Online store
  • Customer
  • Payment provider
  • Warehouse
  • Level 0
  • 1 Take order
  • 2 Process payment
  • 3 Fulfil order
  • D2 Products
  • D1 Orders
  • order details
  • order confirmation
  • payment request
  • payment result
  • pick list
  • shipment status
  • order to pay
  • paid order
  • prices
  • new order
  • payment status
同一家网店的数据流图的两个层次。上下文图把整个系统画成一个处理;0 层图把它分解为三个处理和两个数据存储,并与相同的外部实体保持相同的数据流,正是这一点让各层保持平衡。

这张图的读法如下:

  • 外部实体位于中间:Customer、Payment provider 和 Warehouse。两张图都连接到它们。
  • 左边的框架是上下文图:一个处理 0 Online store,与各实体之间有六条带名称的数据流。
  • 右边的框架是 0 层:Take order、Process payment 和 Fulfil order,以及 Orders 和 Products 两个数据存储。
  • 平衡清晰可见:左边的每条外部数据流都在右边再次出现,这次连接到负责它的那个处理。
  • Markdown 块是图例和编号约定。

画出经得起评审的 DFD

  • 每条数据流都用名词命名。 对 DFD 的评审意见大多与没有标签或标签含糊的箭头有关。
  • 各层之间保持一致的编号,让读者能把 1.2 追溯到 1。
  • 外部实体在每一层都放在相同位置,这样一眼就能看出是否平衡。
  • 为你的记法加上图例,尤其是当你把经典符号和表示数据存储的圆柱体混用时。

关于其他图类型的记法,可参阅流程图形式的事件响应示例和BPMN 图示例。

在 Archboard 中构建

  1. 使用 Google 或 GitHub 登录,并新建一张图。
  2. 在中间一列添加三个基础节点包中的 方框 节点,分别表示 Customer、Payment provider 和 Warehouse。
  3. 在左侧添加一个名为 Context diagram 的基础 框架,在其中放一个基础节点包中的 椭圆 形状,表示 0 Online store。
  4. 在右侧添加第二个名为 Level 0 的 框架,在其中放三个 椭圆 形状表示各个处理,再放两个 圆柱 形状表示 D1 Orders 和 D2 Products。
  5. 把数据流画成带标签的连线,实体两侧使用相同的标签。
  6. 添加一个基础节点包中的 Markdown 块,写上图例和编号约定。

这个示例共用 12 个图表节点,在 Free 套餐的限制之内。

常见问题

数据流图的四种符号是什么? 外部实体、处理、数据存储和数据流。Yourdon 与 DeMarco 把处理画成圆形,把存储画成平行线;Gane 与 Sarson 使用圆角矩形和一端开口的矩形。

上下文图和 0 层 DFD 有什么区别? 上下文图把整个系统及其外部实体画成单个处理。下一层把这个处理分解为主要子处理和数据存储。有些资料把上下文图称为 0 层,所以要说明你采用的惯例。

DFD 中的平衡是什么意思? 流入和流出子图的数据流必须与其父处理的数据流一致。这样可以确保各层描述的是同一个系统。

DFD 和流程图有什么不同? DFD 展示哪些数据流向哪里、如何被转换,不涉及顺序和判断。流程图展示步骤的顺序以及步骤之间的判断。

一个 DFD 应该有多少层? 读者需要多少层就画多少层。大多数系统用上下文图和 0 层就能描述清楚,只有复杂或敏感的处理才需要 1 层图。

免费开始 — 1 个席位,无需信用卡。

相关文章

← 返回博客

一分钟打开画布

使用 Google 或 GitHub 登录。单席位免费,团队加入后再升级。