首页 / 资讯中心 / 文章详情

数据流图DFD实战:结构化分析构建订单系统功能模型

数据流图DFD实战:结构化分析构建订单系统功能模型 ★ FEATURED ARTICLE
做需求分析这么多年我越来越觉得数据流图DFD这玩意儿是被低估的。很多刚入行的朋友觉得它过时了不如画个用例图、写个用户故事来得“敏捷”。但实际上当你面对一个业务逻辑复杂、涉及多个部门和系统交互的需求时DFD 是梳理“数据从哪里来、到哪里去、怎么加工”最锋利的一把刀。它不关心谁用鼠标点了什么只关心数据本身的流转规律而这恰恰是系统架构和数据库设计的根基。这篇内容我想结合自己实际做过的一个某订单处理系统的模拟项目把结构化分析阶段怎么用 DFD 建立功能模型这件事掰开了揉碎了讲清楚。不讲玄乎的理论全是怎么落地的实操、参数怎么定、坑在哪里。1. 为什么要死磕 DFD功能模型这事儿别靠嘴说1.1 从“一团乱麻”到“一张图”我见过太多项目死在需求评审会上。业务方讲得激情澎湃开发人员听得云里雾里最后问一句“那这个数据到底从哪来”全场鸦雀无声。文字描述的需求天然有歧义而 DFD 解决的就是这个痛点。DFD 的核心是用四种基本符号把系统的功能加工、数据流动箭头、数据存储文件和外部交互实体画出来。它构建的是系统的功能模型着眼点是“做什么”而不是“怎么做”。这意味着你在画 DFD 的时候不需要考虑用 Java 还是 Python 实现不需要设计数据库表结构只需要回答一个问题系统为了完成业务目标需要对哪些数据进行哪些处理在我的实践里画好一套分层 DFD相当于把需求文档里的每个动词、每个名词都进行了“物理体检”。比如业务方说“订单要审核”那“审核”这个加工输入是什么输出是什么是直接通过还是走审批流这些含糊点在 DFD 面前无所遁形。1.2 DFD 不是流程图别画成 Swimlane这是新手最容易踩的坑。DFD 关注数据流程图关注控制流。流程图里有判断菱形比如“是否 VIP 用户”DFD 里绝对不允许出现这种逻辑判断符号。因为 DFD 表达的是数据的“加工”和“流动”而不是“决策”和“分支”。如果非要在 DFD 里体现规则用的是“数据流”的命名。比如从“订单校验”加工流出的数据流可以直接命名为“合格订单信息”和“不合格订单信息”。这样一来你既表达了业务规则校验合格/不合格又没有破坏 DFD 的纯净性。2. 实操拆解手把手教你从零构建一套分层 DFD2.1 第一板斧划定系统边界画出顶层图拿到一个项目别急着往里面钻。第一步永远是站在外面看确定系统是干嘛的、和谁打交道。这个“外面”就是顶层图也叫上下文图Context Diagram。我拿之前做的那个订单处理系统举例。系统不是孤岛它要接收客户下单要从库存系统查货要通知财务开票要给物流系统发拣货指令。外部实体External Entity客户、库存系统、财务系统、物流系统。它们都是数据的“源”或“汇”。加工Process只有一个就是“某订单处理系统”。它代表整个系统对外展示的所有功能总和。数据流Data Flow客户发来的“订单请求”系统发出的“订单确认”发给库存的“库存查询请求”库存返回的“库存状态”……顶层图画出来特别简单就一个圆或圆角矩形代表系统周围挂着几个方块代表外部实体。但它的意义极其重大它把所有参与者拉到一个页面上逼着大家统一口径。谁是系统内部的谁是系统外部的这个问题如果不达成一致后面全乱套。注意外部实体只代表数据源或终点它不具备任何数据处理能力。哪怕实际业务中是“客户”这个人做了很多事但在 DFD 里只要这些事不发生在目标系统内部就不画进去。2.2 第二板斧逐层细化画出 0 层图顶层图定了边界0 层图就是把中间那个唯一的加工“炸开”。怎么炸按业务职能拆。在我的订单系统里拆成了四个核心加工1. 订单受理验证客户信息、录入订单2. 库存核验查库存、预占库存3. 订单履约生成拣货单、通知物流4. 财务结算计算金额、对接开票这里有个关键点加工编号。1、2、3、4 的编号不是随便给的它是父子图的“脐带”。0 层图的加工编号对应着 1 层图的整张图编号。从顶层图到 0 层图数据流也要跟着细化。顶层图里的“订单请求”在 0 层图里可能就被拆成了“订单基本信息”和“订单明细项”两条数据流。父图的输入输出必须和子图的输入输出严格对应。这就是 DFD 的灵魂——平衡原则。2.3 第三板斧继续深挖直到没有“黑盒子”0 层图画完每一个加工还是一个“黑盒子”。接下来就是给每个编号加工单独画一张子图直到你认为每一个加工表达的功能足够简单、边界足够清晰为止。这取决于你的项目规模和团队习惯。我通常的标准是如果这个加工内部还存在三种以上的数据流交互或者包含独立的业务状态变化就必须继续往下拆。比如接着拆“2. 库存核验”2.1 库存数量检查查可用量2.2 库存预占锁库存2.3 缺货登记如果不够记录缺货信息同时数据存储就开始出现了。库存数据放在D1 库存台账预占记录放在D2 预占明细。存储的编号用 D 开头从 D1 开始排全局唯一。画到这一层业务人员已经能指着图告诉你“错了我们不是先查库存再预占是先看有没有锁定的库存”。这就是 DFD 的价值——降低沟通成本构建共同语言。3. 关键配角数据字典与加工说明如果你以为画完 DFD 就完事儿了那就太天真了。DFD 只描述了数据的流动路径但没说数据长什么样。这时候就需要数据字典Data Dictionary出场。数据字典用来精确描述 DFD 中的每一个元素数据流“订单明细项”由哪几个数据项组成类型是什么长度多少数据存储“D1 库存台账”由什么字段构成主键是什么加工逻辑“2.1 库存数量检查”具体怎么判断是用当前库存减去预占库存还是只看物理库存加工逻辑的描述工具传统上用结构化英语或判定表/判定树。别小看这一步我见过太多团队流程图画得飞起一到写数据字典就敷衍了事结果开发阶段为了一个字段的长度能在群里吵一天。DFD 是骨架数据字典是血肉缺一不可。我习惯的做法是把数据字典做成一个独立的在线表格和 DFD 图通过“命名”强绑定。DFD 上出现任何一个名词数据字典里必须有它的出处数据字典里写出的任何一个数据项必须能在图上找到它属于哪条数据流或哪个存储。这叫“数据元素的一次定义多处引用”有效避免同名异物、同物异名。4. 动手实践用某订单处理系统走一遍完整演进说了这么多理论不如直接上实战。我带着大家把那个订单处理系统从头到尾过一遍看看 DFD 怎么一步步从粗到细最终变成一个指导开发和测试的“施工蓝图”。4.1 建立顶层图明确系统的“势力范围”项目启动第一周我和业务方、架构师坐到一起。我不让他们讲功能细节先让每个人写下“这个系统必须跟谁打交道”。最后盘点下来外部实体顾客C1、仓储系统C2、财务系统C3顶层加工P0某订单处理系统顶层数据流顾客 - 系统订单请求系统 - 顾客订单回执系统 - 仓储系统拣货指令仓储系统 - 系统出库结果系统 - 财务系统结算请求财务系统 - 系统结算确认这里注意数据流上标注的名字一定要是名词不能是“提交订单”这种动词短语。我们用“订单请求”而不用“顾客下单”因为数据流描述的是数据本身不是动作。顶层图一画完立刻有人提出疑问“发票呢发票数据从哪来”你看这就是边界讨论的价值。最终我们确认发票由财务系统生成不进入本系统范围问题当场消解。4.2 细化 0 层图四大功能域成型把 P0 打破根据业务自然流转画出 0 层图。四个加工编号如下P1 订单处理接收订单请求校验合法性生成订单主记录。P2 库存匹配根据订单明细核对库存可用量锁定可发货部分。P3 拣货出库根据锁定库存生成拣货单发给仓储系统接收出库反馈。P4 财务对账根据出库成功的订单生成结算信息传给财务系统。数据存储在此阶段初步显形D1 订单表订单主信息 状态D2 库存快照表只读引用D3 库存锁定记录锁定时间、数量数据流也在这一层细化。比如 P1 接收“订单请求”输出“有效订单”给 P2同时写D1 订单表。如果订单校验不过系统产生“无效订单通知”直接流回给顾客。库存匹配后有货走“可发运订单”给 P3缺货走“缺货信息”给顾客。这里特别提一点P1 写 D1 的数据流叫“订单记录”不要叫“写订单表”。数据流永远是数据本身动词出现在加工名字里就够了。这个命名习惯我坚持了很多年虽然看起来有点抠字眼但真到了多人协作时能避免无数理解偏差。4.3 展开子图每个加工都不允许有“灰色地带”0 层图里的 P2 库存匹配内部其实挺复杂。我把它单独拆一张 1 层图P2.1 库存数量检查用订单要求的商品编码去 D2 查当前可用库存。P2.2 计算预占库存如果可用库存 需求数量生成预占记录写入 D3。P2.3 生成缺货清单如果不足计算差额生成缺货记录。输入 P2 的数据流是“有效订单”输出是“锁定完成通知”和“缺货通知”。这两条输出加起来正好等于输入没有多也没有少。这就是平衡检查。画到这里我问业务方“如果同一件商品一个客户锁了库存但迟迟不付款预占的库存什么时候释放”对方愣了一下然后意识到原来的业务流程根本没定义这件事。于是我们在 P2.2 和 P2.3 之间增加了一个新的加工P2.4 超时释放数据流“超时订单信息”从 D1 读取释放后的库存回写 D2。这一个图直接推动了一条新业务规则的落地。这就是精细建模对需求的逆向促进。4.4 和用例图配合双剑合璧更高效DFD 不是银弹。我在实操中从来不搞“DFD 至上”而是把它和用例图结合使用。怎么配合用例图从“用户视角”出发回答“谁用什么功能”DFD 从“数据视角”出发回答“数据如何流转”。我习惯先画用例图确定系统边界再针对核心用例画 DFD因为核心用例往往对应多条跨域数据流转用 DFD 梳理最有价值。比如订单处理系统里用例图会画出“顾客下单”“仓库发货”“财务结算”几个椭圆。但用例图看不出“订单数据”和“库存数据”是怎么交互的。一旦补上 DFD数据的首尾去向一目了然。用例图偏重人和系统的交互边界DFD 偏重数据在系统内的生命周期。两者互相补充能让需求调研的盲区降到最低。5. 常见问题与经验坑这些雷我替你踩过了5.1 黑洞、灰洞与奇迹三大最常见错误在评审别人画的 DFD 时我通常先找三类异常黑洞Black Hole只有一个输入数据流没有输出数据流。数据进去了就消失了这在现实中不可能。奇迹Miracle只有一个输出数据流没有输入数据流。数据凭空生成了往往意味着漏画了输入。灰洞Grey Hole有输入也有输出但输入不足以产生输出。比如输入只有“订单号”输出却有“客户姓名”客户姓名哪来的必然是漏画了“客户信息”这条数据流。这三个概念不是考试知识点而是评审利器。每次自查或者互查我只要沿着每条数据流走一遍这种低级却致命的问题立刻暴露。5.2 控制流混入最常见的“破功”操作前文提过控制流混入是 DFD 的头号杀手。最典型的表现是有人在加工之间画了个箭头标注“如果库存不足则跳转到缺货处理”。这就是把程序流程写进了 DFD。DFD 不表达“先做 A 还是先做 B”只表达“A 加工需要 X 数据产出 Y 数据”。正确的改法是把“库存不足”这个判断结果变成数据。“库存校验结果”这条数据流可以带上若干个值充足 / 不足 / 超卖。下游加工根据这个数据流的值走不同分支但分支逻辑写在加工说明里而不是画在 DFD 上。5.3 平衡检查不彻底父子图出入流对不上这是多层级 DFD 最常见的错误。父图中一个加工只有一条输入“订单”但子图里却出现了两条输入“订单基本信息”和“订单扩展信息”。虽然概念上 “订单” “基本信息 扩展信息”但从严格意义上讲父图和子图的输入/输出数据流必须保持数量、方向、命名上的完全一致。我一贯的做法是用一个 Excel 维护父子接口矩阵。每一行的内容包括父加工编号、父输入流名、子图内输入流名、数据类型、来源加工/存储、目标加工/存储。每次改图前先核对矩阵再改图。这个笨办法比任何自动化工具都好使。5.4 命名规范松散图是画了人却看不懂我评审过的 DFD 里最让人崩溃的就是命名问题。加工不写动词写成“订单数据”让人以为是个存储数据流写得含含糊糊写成“信息”完全不知道是什么信息存储命名更是五花八门“库存”、“库存数据”、“库存文件”全都指同一个东西。我强烈建议团队推行一套命名公约加工 动词 宾语例如“生成拣货单”、“校验客户权限”。数据流 名词短语用形容词/定语修饰得更精确例如“已审核的订单请求”。外部实体 名词尽量用业务侧通用叫法。数据存储 名词 介质/含义例如“D5 客户信息表”不要只写“D5 数据”。这套公约不难但贵在坚持。只要坚持住DFD 就能成为团队里真正被反复阅读的资产而不是画完就吃灰。5.5 画到多细算完实用停止规则有个高频问题DFD 到底要分解到第几层分层太深图变得比代码还复杂失去意义分层太浅又起不到明确职责的作用。行业的经验做法是“到功能级即可”。我个人的停止规则是三条加工的输入输出数据流个数总和 ≤ 5 条。加工的功能可以用一句话向一个外行讲明白。加工内部不再包含跨多数据存储的状态变化。如果满足这两条这个加工就不用再拆了。再拆下去就是程序流程图或者伪代码的范畴不属于 DFD 的使命。6. 延伸从功能模型到系统设计的无缝过渡DFD 画完不是终点它是整个结构化分析的输出之一。接下来功能模型要跟数据模型、行为模型配合才能支撑后面的设计工作。通常我在 DFD 定稿后会接着做三件事第一针对每个数据存储定义数据字典实体的字段清单和关系。DFD 里的 D1、D2、D3 几乎可以直接映射成数据库表。一个 DFD 存储就应该对应一组高内聚的数据项这给后续设计数据库实体关系图E-R 图提供了极好的起点。若发现某个数据存储既包含订单又包含物流信息这就是 DFD 分层不合理需要回头调。第二把加工说明整理成功能清单作为开发任务的拆解依据。每个叶子加工对应一个最小功能单元。我在项目管理中经常把展开后的叶子加工整理成任务列表估算工作量、分配责任人。这一招在推动项目进度方面效果显著因为每个任务的边界都清清楚楚。第三用状态迁移图STD补足时序行为。DFD 是静态的它无法表达一个数据对象在不同时刻的状态变化。比如订单要从“待支付”变“已锁定库存”再变“已出库”这个过程需要用状态图描述。DFD 负责空间维度STD 负责时间维度两者一结合需求就真正“立体”了。额外提示DFD 的这种“分层分解”思维并不仅限于软件工程。我后来做过很多非软件类的业务流程梳理也用这套方法。核心思想是从混沌中抓边界从边界中找实体从实体间看流转。结构化分析的生命力恰恰在此。7. 工具选型经验谈白板、Visio 还是专业建模工具关于 DFD 的绘制工具我向来是“情境驱动”的。在需求调研初期信息快速迭代我不建议任何人直接用工具画图。白板加便签是最好的媒介。随手画、随手擦才能鼓励参与者大胆发言。便签一贴一个外部实体换一种颜色代表数据流这种动起来的“纸上原型”比任何软件都高效。一旦客户确认了大方向再把白板图整理进数字工具里精加工。工具选择上我本人常用的是 Visio 和 draw.io。Visio 胜在模板规范适合给客户做正式交付物draw.io 胜在免费、跨平台、能嵌进文档协作工具。至于专业建模工具如 PowerDesigner 或者 Enterprise Architect它们功能很强大但在纯粹的 DFD 表达上反而略显笨重常用于企业级大项目与代码工程整合的场景。我的建议是工具服务于沟通别为了工具而工具。DFD 的核心是逻辑分层与数据流命名在纸上能画清楚在工具里就不会差。另外有一点值得反复强调画图过程中每画完一版一定要找至少一位不直接参与建模的人来“审图”。让他从头到尾不看书面的流程说明单看图把每个数据流的名字读一遍把每条路径讲一遍。如果这个人的讲述和业务规则一致说明这张图是自解释的如果卡壳了恰恰说明图上还有表达不清的地方。这是我用多年项目“换血”换出来的经验强烈建议尝试。落到最后我个人的体会是DFD 看似是“老古董”但它锻炼的是一个人“结构化拆解”的底层能力。当你习惯了用“外部实体—加工—存储—数据流”这四类元素看待一个业务场景你再去看任何复杂的业务流程都会自然而然地抽离出核心骨架而不会被细枝末节缠住。这种思维习惯比记一堆时髦的概念管用得多。
阅读完成 · 觉得有帮助?
咨询建站