先交代一下背景:数据流图这个东西,你只要做系统需求分析、软件工程建模相关的事,几乎绕不开。不管是传统的结构化分析(SA方法)还是Yourdon/DeMarco、Gane-Sarson那一套,DFD都是核心交付物。很多人觉得画DFD就是摆几个泡泡和箭头,画得好看就行,结果评审会上被别人问一句“这个数据流哪儿来的?”就答不上来。问题基本出在没吃透一套约束规则上。下面这篇,我就把这套规则掰开揉碎讲清楚,配合实例、易错点、校验方法一起给你。
这套规则,其实是给DFD建模立起来的一组“交通规则”。它约束的不是画图风格,而是图的语义正确性。你在需求阶段用它当草稿,在评审阶段拿它当检查清单,在画到第三层细节的时候可以让你的图不至于崩成蜘蛛网。我建议所有产品经理、业务分析师、软件工程方向的学生,以及刚接触系统设计的开发人员,都先把这套东西背下来再用。
1. 先搞清楚DFD里的四个基本符号
四条规则要落地,你得先认识DFD的建筑材料。所有数据流图,不管画得多复杂,本质上只有四种基本图形元素:外部实体、加工、数据存储和数据流。这个认知很重要,因为在评审现场吵起来的,多半不是逻辑问题,而是有人把“控制命令”画成数据流,或者把“业务角色”直接当成加工。
1.1 外部实体与加工:把“谁跟系统打交道”和“系统做什么”分开
外部实体也叫源点/终点,通常用矩形表示。它代表的是系统边界之外的人、组织或另一个系统。比如图书借阅场景里的读者、图书馆职工,再比如一个电商项目里的支付网关、物流系统,这些都是外部实体。为什么强调“外部”?因为画上下文DFD的时候,你第一步就是把系统边界划清楚,凡是边界外的东西一律进不了加工,只能通过数据流跟加工联系。很多初学者最容易犯的错,就是把角色权限、组织架构画进去,或者把某个部门当成加工来计算,这就把外部实体和系统内部逻辑混在一起了。
加工是真正干事的节点,你用圆角矩形或者圆形表示。加工必须有编号、有名字、有清晰的输入和输出。判断一个节点能不能成为加工,最简单的标准只有一条:它是否把输入数据变成输出数据?比如“读者借书登记”是加工,因为它接收“借书请求”然后输出“借书结果”;而“排队等待叫号”就不是加工,它是过程状态,不该出现在DFD里。
1.2 数据流与数据存储:流的本质是数据在移动,不是控制在流转
数据流用带箭头的线表示,它专门描述数据在元素之间的移动方向。这里有两个非常容易被忽视的坑。
第一,数据流只描述数据,不描述控制流和时间顺序。很多人在DFD里画“点击按钮后页面跳转”,这就错了。“事件”“命令”“触发信号”这类控制信息在DFD里没有合法位置,你得把它们放到流程图、状态图里,而不是DFD里。DFD是“数据的物流图”,它不是“业务的时序图”。
第二,数据流不能凭空出现,也不能消失,它必须连接在加工和加工、或加工与外部实体、或加工与数据存储之间。数据存储,一般用开口矩形或者两条平行线表示,它代表数据的静态停留地,比如数据库表、文件。对数据存储的判断要小心,不是所有中间产物都要画成存储,只有那些“加工之间需要传递数据,但又不是立即通过数据流带走”的场景才需要存储。
1.3 两套主流表示法的差异,别换工具就乱了
你可能会看到不同教材、不同工具里符号略微不同。严格来说,结构化分析领域有两套常见的表示法:一套是Yourdon/DeMarco,加工用圆或椭圆,数据存储用两条横线;另一套是Gane-Sarson,加工用带圆角的矩形,数据存储用开口矩形,数据流的箭头也更方一点。
| 元素 | Yourdon/DeMarco风格 | Gane-Sarson风格 |
|---|---|---|
| 外部实体 | 矩形 | 直角矩形 |
| 加工 | 圆/椭圆(中间标编号和名称) | 圆角矩形(分隔线上下分别写编号和名称) |
| 数据存储 | 两条平行横线 | 开口矩形 |
| 数据流 | 有向箭头 | 有向箭头(方向标识更严格) |
这两种风格没有本质对错,你选一种,项目里所有图保持一致就行。我见过一些团队画图用Visio自带的模板,结果上下文图用的是Gane-Sarson风格,到了0层图又变成Yourdon风格,评审的时候符号都对不上号,那四条规则再好使也用不起来。标准统一,是一切校验的前提。下面我讲的规则适用于两种风格,你只要把元素概念替换成对应的符号就行了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 四条规则逐条拆解:它们到底在约束什么
如果说前面是认零件,那这一节就是把零件组装起来时必须遵守的规矩。这套规则我从实战角度归纳成四条,很多人叫它“四条规则”,其实就是DFD建模的四大校验准则。每次画完图自己先拿这四条过一遍,再拿给同事评审,你的图会直接上一个档次。
2.1 第一条规则:加工必须有进有出,不允许只有一条腿
最直白的一条:任何一个加工,至少有一个输入数据流,也必须至少有一个输出数据流。这背后的道理很简单,加工的本质是变换,把输入变成输出。如果没有输入却有输出,那数据就是凭空变出来的;如果有输入但没有输出,那数据就被莫名吞掉了,这两件事在物理世界里都说不通。
我在实际评审中,最爱干的事就是先找“只有一条腿”的加工。如果你画了一个加工叫“生成统计报表”,结果只有一条箭头从外部实体指向它,那就得问:数据进来之后去哪了?是被加工吃掉了还是没画完?反过来,一个加工只有输出,没有任何输入,比如“5G消息推送”,但没有画出数据从哪个库或哪个消费者来,这也是典型的可疑节点。画图时随手多画一条线容易,在评审会上解释为什么这条线存在很难。这条规则能帮你挡掉至少一半的烂图。
2.2 第二条规则:数据守恒,输出不能凭空产生
加工“有进有出”只是基本门槛,还需要更进一步:输出的数据内容,必须能从输入的某个组合中推导出来,或者至少能解释清楚它从哪个输入数据流得来。说得专业一点,叫做数据守恒。仍以“统计报表”为例,如果一个加工输入是“读者基础信息”,输出的却是“借阅趋势分析报告”,那显然解释不了“趋势”从哪个数据来的,除非还有一条多余的输入流你忘了画。
这里有一个典型的实操误区:很多刚学结构化分析的人,会把“系统内部缓存”“临时变量”想进去,觉得加工自己有点“记忆”,能存一些状态。要时刻提醒自己:DFD建模时的加工,在分层图中是可以有内部细节的,但在上一层你只看该加工和外部的数据交互,并不能假设加工能自己“凭空长”出数据。如果数据确实是被持久化存储的,那就应该画出一个数据存储,让数据流从存储出发,经过加工输出。数据守恒规则,本质是在约束模型的封闭性和可追溯性:任何输出都能沿着数据流往回找到来源。
第二个常见误区是:数据流的守恒不是说“输入数据的量必须等于输出的量”,而是“输出依赖输入且可解释”。比如一个加工“审核借书申请”,它的输入是“借书申请”,输出是“通过通知”或“驳回原因”,这是守恒的,因为输出确实是由输入处理后产生的。不要死板地认为输入输出必须一一对应数量相等。守恒指的是业务含义和数据来源上的守恒,符号数量的对比没有意义。
2.3 第三条规则:数据存储不能绕开加工,所有数据流的起点或终点必须落在加工上
这是最容易被忽略,也最常被画错的一条。核心是:外部实体与数据存储之间不能直接画数据流,数据存储与数据存储之间也不能直接画数据流。所有数据流必须至少有一端落在加工上,因为只有加工才能对数据进行读写操作。举个例子,你画了一个“借阅记录”数据存储,想表示读者查自己的历史借阅,于是你直接从“借阅记录”拉一条箭头到“读者”外部实体。这时候就明显犯规了:谁去执行这个查询?查询逻辑是不是被漏掉了?这条数据流一旦绕过加工,就说明系统里存在一块不受加工控制的数据访问行为,这会直接导致后面的功能分解缺一层关键逻辑。
同理,你要表达“把读者信息表导入到借阅记录表”,也不能直接从数据存储到数据存储画一条线。正确的做法是画一个类似“数据同步/数据迁移”的加工,接收读者信息,经过转换,写入借阅记录。换句话说,所有落库和取数的动作,都必须有加工作为执行主体。这条规则在需求分析阶段意义很大:它强迫你把每个业务动作都抽象成加工,而不是让数据自己在系统里“飞”。
另外注意,数据存储最好同时有流入流和流出流。如果某个存储只有流入,说明数据只有写没有读,那这个存储就是死存储,大概率是多余的表;如果只有流出,没有流入,说明数据不知道从哪里来的,要么是外部系统灌进来的,要么就是漏画了存储过程。当然,特殊情况下允许存储只有流入或只有流出,比如“归档库”可能只有写,但如果你在DFD里画它,就得认真想想它是否真的参与了当前系统的业务闭环。
2.4 第四条规则:数据流必须命名清晰且全局唯一,加工的编号要随分层保持一致
规则四看上去很“文案”,但它直接决定整批图能不能被理解。DFD里每一条数据流,都必须有一个能准确反映数据内容的名字,而且这个名字应该在整套分层图中表示唯一的一条流。流名不能含糊,不能起“数据”“信息”“查询结果”这种谁都能用的名字,它应该是一个具体的数据载体描述。比如“借书请求”“读者借阅次数统计”“罚款催缴通知”,越明确越好。如果一条流里包含多个字段,数据字典里必须能展开看到字段组成,这条流才算定义完整。
加工编号也不能乱来。上下文图只有一个加工0,0层图里的加工从1、2、3开始编号,0层图的加工如果继续往下分解,子图里的加工就采用父子编号。例如0层图里的“1 借书登记”继续分解出1.1、1.2、1.3;如果再展开1.2,里面就出现1.2.1这种编号。这套编号系统是怎么给你好处的?评审的时候,只要有人指着“1.2.3”问这是什么,你马上知道它在哪个父图位置,父子关系一目了然。但编号系统必须跟父图子图平衡配套,否则编号再整齐也没有用。
四条规则并不是孤立存在的。第一、二条管单个加工内部的合理性,第三条管元素间的连接边界,第四条管整套图的表达质量。把它们合起来用,就是一张DFD的质检清单。每次画完图,我基本是闭着眼睛把四条在脑子里过一遍:每个加工有输入输出吗?输出有来源吗?存储连接加工了吗?流有名字、编号能回追吗?一遍下来,绝大多数低级错误都跑不掉。
3. 最重要的实践:上下文图与逐层分解
四条规则如果单独看会显得比较“死板”,它们的真正威力,要结合DFD最核心的建模思路——分层分解——才会体现出来。完整的一个DFD模型,从来不是一张巨大的图,而是一组呈树状结构的图。按规则建模,就是要把这组图控制在高内聚、低耦合的状态。
3.1 上下文图:先定义系统边界,避免范围蔓延
画DFD的第一步,永远是画上下文图。上下文图只画一个加工,表示整个系统,然后画所有外部实体和系统之间的数据流,不出现任何内部加工和数据存储。它的核心任务是回答“系统跟外界交换什么”,说白了就是划定边界。
很多需求跑偏的项目,早就在上下文图阶段埋了雷。比如人事系统,你画上下文图时把“考勤机”画成外部实体,并让它直接向系统发“打卡记录”,这就是一个范围声明的动作;如果你没有把“薪酬核算系统”画成外部实体,那说明你默认该系统不在本项目范围内。上下文图一出,相关方能立刻看到自己关心的数据有没有被遗漏。外部实体画错了,后面所有0层图、1层图全都跟着歪。上下文图不要怕少画,外部实体一般很难超过二十个,如果一大堆,说明系统边界可能划小了,或者你把系统内部的某子系统又当成了外部。
3.2 从0层图开始,按“高内聚”原则逐级展开
上下文图下面的0层图,是把上下文图里的系统加工,分解成若干个主要加工。外部实体不变,数据流不丢失,此时可以开始出现数据存储。0层图的任务是把系统最大的几个业务域划分出来,比如“读者管理”“借阅管理”“馆藏管理”“罚款管理”。0层图切忌一下画出几十个加工,最好控制在7个上下,超过9个就要停下来思考是否聚合得不够。
0层图再往下,每个加工根据内部复杂度展开成子图。每次展开时,“父图加工”就像变成一个小系统的边界,子图是这个边界的内部实现。子图只画父图加工的输入输出上对应的数据流,而不能突然冒出父图加工本来没有的数据流。这就是分层DFD模型一致性的核心。逐层分解保证模型的可读性:每一层的细节复杂度控制在人类心智能承载的范围内。
3.3 一个可以照抄的分解实例:图书借阅系统
用文字来拆一个常见案例。假设项目叫“图书借阅管理”,上下文图里,外部实体是读者、图书管理员;系统与读者之间有借书请求、还书请求、查询请求、查询结果、逾期通知等数据流;系统与管理员之间有图书入库信息、借阅报表请求等数据流。
0层图里,我把系统拆成“1 借书登记”“2 还书处理”“3 馆藏管理”“4 逾期罚款管理”四个加工。这里出现三个数据存储:“读者库”“图书库”“借阅记录库”。读者发来“借书请求”,进入加工1;加工1需要检查读者身份,那就从“读者库”读数据;还需要看某本书是否可借,那就读“图书库”;最后写“借阅记录库”,向读者输出“借书结果”。这是0层图的基本面貌。
现在把加工1“借书登记”再展开成1层子图。子图里可以继续拆成“1.1 读者资格校验”“1.2 图书可借性检查”“1.3 登记借阅信息”。子图的输入还是“借书请求”,输出还是“借书结果”,与父图完全一致。子图内部可以有读者库和图书库的读取箭头,也可以有写入借阅记录库的信息流。但你要记住:父图加工1只有“借书请求”和“借书结果”两条主流,它没有“馆际互借请求”“读者投诉”之类的进出。如果子图里画出了父图根本没有的流,那就要么把父图改掉,在0层图上为加工1增加对应流,要么承认子图画错了。这一条说起来理所应当,但实际项目里子图擅自多一条流的次数,比你想象的多得多。
3.4 什么时候停止分解:没有边界的一层层展开,是烂图之源
有人会问:一个加工能不能无限往下分解?实际操作中会有几个停止条件。第一,加工的内部逻辑可以用一个结构化的决策过程说清楚,不需要再拆分,比如“资格校验”如果只是查一个表看状态,就直接写加工说明,不用再拆。第二,加工已经对应到单一的、内聚的业务动作,比如“打印借书单”这种一次性动作,再拆就变成画程序流程图了。第三,子图预计只有两三个加工,再拆会导致图和代码几乎一一对应,这种粒度放到设计阶段再细化就可以了。
DFD分层不是越细越好。系统分析阶段,DFD的使命是把业务需求结构化,而不是替代详细设计。我见过有人把0层图里的某个加工一路展开到5层,每层只画三四个泡泡,评审会上一屋子人盯着第5层图,谁也讲不清业务主线了。合适的做法是:上下文图1张,0层图1张,业务复杂域每个域给1层就够,个别核心域给两层。也就是说整套DFD大概控制在6到10张图以内。层数一多,父图子图一致性检查的负担会指数上升,甚至会造成模型本身不可维护。
4. 从需求描述到一张合格DFD的完整操作步骤
四条规则和分层理念讲完了,你可能更关心:假如我现在拿到一段手写的业务描述,我该按什么顺序把一张合格的DFD“生产”出来?接下来这部分,是我的标准动作。
4.1 第一步:圈定系统边界和外部实体,不急着画箭头
无论需求描述是长是短,先过一遍全文,把所有出现在系统之外但是需要和系统协作的参与者找出来。这里有个小技巧:关注描述里的“人”和“外部系统”名词,例如用户、管理员、银行、短信平台、仓库系统。把它们列在纸上,不要急着判断它们的职责,因为你在上下文图阶段要的是系统与外界的交互对象。
列完外部实体后,紧接着就要给每个外部实体和系统之间的所有输入输出命名。这时候你还没有必要打开绘图工具,拿一张表格列出来就够。你可以把表头设计成:外部实体、流入系统的数据流、从系统流出的数据流、大概的数据字段说明。这张表就是上下文图的底稿。很多新手急着画泡泡和箭头,结果画到一半发现某个外部实体没有流,或者某条流没有任何意义,就是因为底稿不扎实。
4.2 第二步:识别系统主流程,由描述中的动词牵出加工
底稿完成后再进入0层图。这一步的任务是找主流程,通常藏在业务描述里的动词中:借书、还书、入库、逾期罚款、统计报表……每个动词都可能是候选加工。加工名字建议统一用“动词+宾语”的结构,如“提交订单”“审核资质”,这能避免把加工名写成部门名或状态名。
把动词聚合,同一组内聚业务动作合并成一个0层加工,将外部实体和这些加工之间的数据流拉通。如果某些加工需要保存数据,把数据存储加进来。0层图是整组DFD里最需要花时间打磨的一张,因为它决定后续分解的骨架。如果你在这里把“借书”和“还书”合并成一个加工,底层描述就会很别扭,因为借书和还书虽然都在操作借阅记录,但它们在输入输出和业务规则上的差异很大。0层图的加工边界应该尽量做到相互独立,避免两个加工共享太多内部细节。
4.3 第三步:逐层细化时,把数据字典和父图记在手上
从0层图往下分解时,确保每个被选中分解的加工都有明确的父图编号。具体做法是:给每个待分解加工建一个子图文档,文档最开始贴出父图中该加工的边界截图或完整流清单,然后在这个清单约束下细化内部。子图出来的结果,必须能在这个清单里一笔一笔打勾。
与此同时,数据字典要同步建立。很多画DFD的团队,图画了一大堆,但从来没有数据字典,这很不健康。数据字典记录的是图里每个元素的精确含义。流要写明组成字段和数据类型;存储要写明字段清单;加工要写明简要的业务规则。缺少数据字典的DFD,就是只有骨架没有血肉。
下面给一个数据流定义的参考格式:
txt复制数据流名称:借书请求
编号:DF_1.1
来源:外部实体_读者
去向:加工1_借书登记
组成:读者证号 + ISBN + 借书日期 + 期望归还日期
备注:读者在终端上提交借书申请时产生
txt复制数据存储名称:读者库
编号:DS_002
组成:读者证号 + 姓名 + 证件类型 + 证件号码 + 联系电话 + 累计借阅数 + 状态
写入者:加工1.1(读者资格校验)、加工2.2(读者信息维护)
读取者:加工1.2(图书可借性检查)、加工4.1(罚款金额计算)
有这份字典之后,前面说的数据守恒规则(规则二)就好查验多了。你只要顺着输出流的组成看它需要哪些字段,再反查加工有没有对应输入能派生出这些字段,马上能定位到缺哪条流。
4.4 第四步:静态检查这五项,画完别急着发
画完图不急着“保存并交付”,先执行一轮静态检查。这里分享我的检查次序:
第一,按第二条规则检查所有加工,给每个输出流找数据源,找不到就补输入流或说明来源。第二,按第一条规则清点有没有加工只有入没有出、只有出没有入,黑洞和奇迹是高频错误。第三,按第三条规则,检查所有连接数据存储的数据流,起点或终点是否是某种加工。第四,检查父子平衡:拿子图和父图的边界流清单逐条对照,看看是不是每个外部出入都一一对应。第五,检查命名和编号,流名是否唯一,加工编号是否符合父子规则,存储是否都有读写者。
这五步做完,一张图的质量基本稳了。你会发现一个很有趣的现象:真正动手画图本身可能只要二十多分钟,但底稿整理和静态检查至少要一小时。这是正常的,DFD的价值恰恰在那个“磨”的过程中产生。
4.5 工具选型:真的不是只有Visio可选
工欲善其事,必先利其器。DFD工具不需要太贵,但最好能满足三个要求:分层管理方便、能自由画文本标注、便于多人评审。这里说说我这些年常用工具的优缺点,你可以按团队条件选。
draw.io(现在也叫diagrams.net)最接地气,免费、免安装,浏览器直接开,支持Git存储,适合小团队快速建模。微软Visio是老牌绘图工具,模板丰富、形状规范,适合客户和领导在场时投影讲解,但在多人协作和数据字典联动上偏弱。如果做大型结构化建模、还要跟需求库绑定,可以考虑Enterprise Architect,它不只是画图,还能做数据流和对象之间的追溯,但学习成本高,对普通业务团队偏重。
有人喜欢用PlantUML写代码生成DFD,书面表达很酷,适合程序员,但碰一个非技术背景的业务分析师时,就不太友好,因为业务评审不是看代码,是看图。我的建议是:团队如果跨角色,draw.io最平衡;如果是个人爱好或极客风格,PlantUML也能接受;如果公司采购了正规建模平台,用平台内建的DFD组件最省事。工具本身不决定图的质量,决定质量的是符号规范和检查清单。
还有个小技巧:用draw.io做DFD时,可以把加工画成带编号框的圆角矩形,然后在同图层下方加一个半透明文本框,写上“父图加工编号:1.3,本层为图1.3”,这样评审时每个人都能快速定位这套图在模型树上的位置。
5. 常见问题与排查技巧:都是现场踩过的坑
接下来这部分是实操中一定会遇到的坑。哪怕你把四条规则背得滚瓜烂熟,画的时候还是会犯,关键是出了问题怎么快速揪出来。
5.1 加工黑洞、奇迹加工和灰洞加工
这三类错误的名字很有意思,也非常直观。黑洞加工指只有输入流没有输出流,数据进去就没了,现实中是不可能的;奇迹加工指只有输出流没有输入流,数据凭空变出来,同样不可能;灰洞加工指有输入也有输出,但输入和数据不足,比如只传了一个身份证号进来,却想输出一份50个字段的档案详情,其中显眼地包含若干从来没输入过的历史借阅记录。这类问题如果等到编码阶段才发现,对应模块八成要返工,因为上下游的数据边界从一开始就是错的。
排查方法也很固定:拿到加工后,按词典里的输出字段逐个向上游倒推。我要生成“借阅详情”,需要“读者证号”“当前借书列表”“历史逾期记录”,那这些字段只能来自输入流“读者证号”和数据存储。如果当前加工既没有对应的输入流也没有读取存储的流,就是数据来源缺失。趁早补上,别往需求文档里写“系统应当自动获取”,那不是给机器看的,是给自己挖坑。
5.2 父图子图平衡检查,为什么永远排在所有检查第一位
父图子图平衡之所以重要,在于它是整套分层DFD语义一致性的立命之本。父图加工是一个“封装”,它只暴露输入输出;子图是封装的内部实现。如果子图内部有父图没暴露的数据流,那要么是父图漏了这个外部交互,要么是子图擅自扩大了系统范围。两种情况在评审里都意味着返工。
实际项目里我见过一位分析师的子图里,某加工向外部实体“省图书馆”发送了一个查询流,但0层图上下文图都没有这个外部实体。查下去才发现,他画到一层细节时,临时想起系统会调一个外部查询接口,于是直接加在子图里。这个做法的隐患非常大,因为它会让项目成员误以为0层图已经覆盖了所有系统边界,等开发排期时发现漏排了与省图书馆的接口对接,那问题就大了。所以正确的做法是:新流如果只属于子图,回到0层图补外部实体和数据流,再让子图继承;如果确认不是系统范围,把它从子图删掉并注明原因。
5.3 把控制流/时序当成数据流,是最常见的跑偏
前面在基础部分提过,但这里必须单独拿出来当案例讲,因为很多人真的会在DFD里画“点击确认”“保存”“下一步”。这些是控制流,不是数据流。数据流里流动的是“订单数据”“表单填写结果”“库存状态”,它们是会加工处理的素材;而“点击按钮”“跳转页面”是控制命令或事件,它们在流程建模里表达,不该出现在DFD中。
举一个实际场景用户下单,你如果需要表达“用户提交订单”这个动作,正确的画法是:外部实体用户向加工1发送“订单信息”,这条流上流动的是具体字段内容,而不是“点击提交”这个指令。控制触发可以被描述为这条数据流产生的背景,但不应作为DFD里的唯一元素。画DFD时如果总是忍不住想画时序,可以换个方法:先把功能分解完成后,再用系统时序图另外建模,让两种视图各自发挥作用。
5.4 数据存储只出现在低层导致的不一致
这个坑有两种表现。一种是我前面提到的,子图里忽然多出一个数据存储,但父图里没有任何加工访问过该存储。另一种是同一个数据存储,在0层图里叫“图书库”,到了1层图里却叫“馆藏档案”,虽然你内心清楚它们是一个东西,但在模型里它就是不一致。第四条规定了名字要唯一,跨层引用时尤其要守住这条。
给存储命名时,我一般建议用“业务实体名+库/表/文件”的形式,一旦定了就不要随便改。比如“图书库”,子图里也要继续叫“图书库”,不要叫“书籍数据源”。写数据字典时最好给存储分配一个稳定的编号,如DS_002,这样评审时即使某次命名混乱,还能按编号定位到同一个存储。数据存储也是模型资产,它跟外部实体和加工一样值得认真编号。
| 问题类型 | 典型表现 | 快速排查方法 |
|---|---|---|
| 黑洞加工 | 有输入无输出 | 输出流清单遗漏,或者加工逻辑只写不读 |
| 奇迹加工 | 有输出无输入 | 输入数据源缺失,通常漏画流或漏连存储 |
| 灰洞加工 | 输入不足以支持输出 | 按输出字段逐项反推数据来源 |
| 父图子图不平衡 | 子图出现父图没有的流 | 导出发边界的流清单逐条对比 |
| 存储直连外部实体 | 存储和外部实体之间拉箭头 | 加一个加工负责读写存储 |
| 流命名重复或模糊 | 多个流叫“数据”或“结果” | 统一修订数据字典并做全局重命名 |
| 编号断层或重复 | 子图编号无法对应父图 | 分层时写清父图加工号,再定义子图 |
6. 实操总结与经验体会,几条不一定写进教科书的心得
最后分享几个我自己的使用心得。
第一个心得:四条规则最好打印出来贴在工位旁边。你不需要背得很熟,画完图后按照四个维度检查一遍,比任何建模高手“感觉不对”的灵性判断都要可靠。很多需求文档写得很漂亮,一但转成DFD就漏洞百出,原因就是描述性语言本身有歧义,而DFD是结构化的,它能逼你把没说清的东西补上。
第二个心得:DFD一定要“带人评审”,不要自己闷头画。哪怕你特别清楚每一条流的意思,另一双眼睛往往能发现上下文图里漏掉的某个关键外部实体。评审时你的任务不是讲解图有多漂亮,而是按照四条规则带着别人逐条勾选:大家请看,加工4只有输入没有输出?这确实是一个问题。这样的评审现场通常效率非常高,参会者不会陷入业务细节争论,因为规则已经帮大家划定了讨论边界。
第三个心得,也是最重要的:把DFD当成对话工具,而不是交付文件。四条规则的最终目的不是让你“造出合规的DFD图”,而是让你通过DFD想清楚系统边界、职责划分、数据来源和消费关系。数据流图画得不完美没关系,只要对着规则把逻辑漏洞补上,这个补洞的过程就是需求分析最值钱的部分。
