Skip to content

📖 第2章 结构化分析:结构化需求分析核心工具与 AI 映射

🎯 【教学目标与核心降难策略】

教学目标:针对初学者,彻底扫除抽象概念的认知障碍。掌握结构化分析的四大核心工具,学会将模糊的业务需求转化为规范的图形模型,并学会将这些模型作为高级指令(Prompt),驱动 Trae IDE 生成严谨的企业级代码。

核心工具的生活隐喻与 AI 映射(基于图书系统)

  • 🧮 数据流图 (DFD) = 图书馆的自动分拣传送带(看借阅请求和图书怎么流转) ➔ 约束 AI 的函数调用与参数传递
  • 🗺️ 实体联系图 (ER) = 图书馆的楼层索引与书架布局图(看藏书和读者数据怎么存放关联) ➔ 约束 AI 的数据库表结构与主外键关联
  • 🚦 状态转换图 (STD) = 一本书的“奇幻漂流”日记(记录从入库、被借走、超期到报废的过程) ➔ 约束 AI 的状态机流转与枚举类
  • 📖 数据字典 (DD) = 图书馆极其严苛的《图书编目规范》(精确规定条形码必须是13位等) ➔ 消除 AI 幻觉,锁定字段类型与边界

🌍 【贯穿本课的实战项目背景:高校图书借阅系统】

为了避免知识点碎片化,本节课的所有图表推演与 Trae 实操,将统一围绕以下详细的业务场景展开。请同学们在阅读时,尝试在脑海中提取出“谁在操作”、“产生了什么数据”、“经历了哪些检查”

1. 身份认证与拦截模块读者(本科生或教师)来到自助借还机前,首先需要刷校园一卡通。系统接收到卡号后,会向外部的校园一卡通系统发送校验请求。如果卡片有效,系统接着会查询本地的读者信息表,检查该读者是否处于“挂失”或“冻结”状态(例如存在未缴清的罚款)。如果有异常,系统立刻终止流程并弹出“拒绝服务提示”。

2. 核心借阅流转模块 身份校验通过后,读者将欲借的图书放置在扫描区,系统读取图书条码。此时系统需要执行两步核心加工:第一步,查询图书库存表,确认该书当前状态为“在馆可借”;第二步,查询该读者的借阅历史流水表,核对当前已借数量。业务规则严格规定:本科生最多同时借阅 5 本,教师最多借阅 10 本。所有条件满足后,系统将图书状态更新为“已借出”,在流水表中新增一条包含“应还日期”的借阅记录,最后向读者输出一张借阅成功凭条

3. 归还与违约清算模块 读者还书时,系统扫描图书条码,从流水表中调出该书的借阅记录并比对当前日期。如果未超期,直接更新图书为“在馆可用”并闭环流水。如果已超期,系统将触发罚款计算逻辑:根据超期天数和读者类型计算违约金,生成超期罚款单。读者扫码缴费后,数据写入罚款财务表,方可完成最终的图书归还。


2.4 功能建模:数据流图 (DFD)

功能建模的核心思想是用抽象模型的概念,按照软件内部数据传递、变换的关系,自顶向下逐层分解。

初学者认知避坑:DFD 只反映系统必须完成的逻辑功能,绝对不涉及具体的物理实现。 换句话说,在画图时,我们毫不关心你是用 Java 还是 Python 写代码,是用 MySQL 还是 Redis 存数据。只要有数据的流入、处理和流出,它就是一个完整的逻辑闭环。

2.4.1 DFD 的四大基本符号 基础

DFD 故意使用极简的图形元素来剥离系统的复杂性,避免非技术人员看不懂。

  • 外部实体 (External Entity):系统的“边界”之外的人或事物。
    • 案例映射:借书的读者、提供鉴权接口的校园一卡通系统。用矩形表示。
  • 加工 (Process):对数据进行处理和变换的动作,必须使用动词性短语
    • 案例映射:系统执行的验证读者身份计算超期罚款。用圆形或圆角矩形表示。
  • 数据流 (Data Flow):运动中的数据,必须有名字。
    • 案例映射:读者提交的图书条码集合,或者系统返回的罚款单。用带有名字的箭头表示。
  • 数据存储 (Data Store):静止的数据,随时准备被读取或写入。
    • 案例映射:后台的图书库存表借阅历史流水表。用双横线或右开口长方形表示。

2.4.2 DFD 的分层拆解艺术:从宏观到微观 核心

面对动辄几十万行代码的工业级系统,直接画出一张图会引发视觉灾难。因此,我们采用“自顶向下,逐层分解”策略。

1. 顶层图(0层图:环境图) 将整个“图书借阅系统”视为一个不可见的黑盒。初学者只需思考:

  • “系统从外界接受什么数据?”(如:一卡通物理卡号、图书条码)
  • “系统向外界送出什么数据?”(如:借书成功凭条、罚款支付二维码)

2. 第一层图(系统主干) 把黑盒砸碎,暴露出最核心的几个大业务模块。根据我们上文的【业务背景】,系统可拆解为:1.0 身份与权限校验2.0 图书库存与额度检查3.0 归还与罚款清算 等主线。 (注:给加工打上编号极其重要,这方便我们在几十张图纸中追踪层级关系。)

⚠️ 【工业级核心坑点:子父图平衡与数据守恒】

初学者(以及盲目写代码的 AI)最容易犯的逻辑错误,被称为“黑洞”与“奇迹”:

  • 黑洞 (Black Hole):一个加工如果只有输入没有输出。比如输入了“读者一卡通号”,经过“借阅加工”后,什么数据也没流出,数据凭空消失了。
  • 奇迹 (Miracle):如果只有输出没有输入。比如没有任何还书请求输入,“计算罚款”加工却直接输出了“20元罚款单”,成了无源之水。(AI 经常在这里产生幻觉,伪造假数据)。
  • 子父图平衡 (Balancing):当你把一个“父加工”拆解成多个“子加工”时,父加工的输入输出箭头,必须和子图总体的输入输出箭头完全一致
🚀 【Trae AI 联合实战:从逻辑审查到代码架构拆分】

第一步:让 AI 审查方案可行性(逻辑排雷) “Trae,针对图书借阅系统的‘核心借阅流转模块’,我已经梳理了初步的 DFD 逻辑:输入读者学号和图书条码 -> 加工1:检查图书是否在馆 -> 加工2:检查读者额度是否超限 -> 加工3:生成借阅流水并扣减库存。 请帮我分析当前的数据流和加工设计是否合理?有没有遗漏关键的异常分支或业务漏洞?(注意:先不要写代码,只做软件工程层面的逻辑评审)”

第二步:基于确认的方案,驱动 AI 划分代码结构 “(假设与 AI 探讨后,补充了‘并发防超借验证’逻辑)非常棒,就按完善后的 DFD 逻辑流。现在请为我生成 BorrowService 类的代码骨架。要求:每一个加工步骤必须封装为一个独立的 private 方法,避免出现面条代码,并严防‘黑洞’效应,确保核心的 borrowBook() 方法最终能返回明确的凭证对象。”


2.5 数据建模:实体联系图 (ER图)

如果 DFD 描述的是数据的“流动过程”,那么数据建模 (ER图) 就是描述系统究竟需要永久存储哪些数据,以及这些数据之间有什么千丝万缕的联系。它是后续开发人员(以及 AI)建立数据库表结构的直接依据。

2.5.1 ER 图的核心元素与降难策略 建模

对于零基础学生,请牢记以下“词性转换法”:

  • 实体 (Entity):用矩形表示。降难口诀:“名词即实体”。只要是系统中客观存在且能相互区别的事物,就是实体。如“读者”、“图书”、“罚款单”。
  • 属性 (Attribute):用椭圆表示。降难口诀:“形容词/细节即属性”。描述实体具体长什么样。例如,“读者”实体拥有“姓名”、“学号”、“读者类型”等属性。
  • 联系 (Relationship):用菱形表示。降难口诀:“动词即联系”。实体之间是怎么产生交互的?比如学生“借阅”图书,系统“生成”罚款单。

2.5.2 联系的三种基数 (Cardinality) 易错点

实体间的联系是错综复杂的,初学者经常在此处被绕晕:

  • 一对一(1:1)联系
    • 图书系统场景:一条具体的“超期借阅流水”与一张“罚款单”之间是 1:1 联系。
  • 一对多(1:m)联系
    • 图书系统场景读者借阅流水记录之间是 1:m 联系。一个学生可以产生多条历史借阅记录(多),但一条具体的流水记录只能属于某一个特定的学生(一)。
  • 多对多(m:n)联系
    • 图书系统场景读者图书之间是 m:n 联系。一个读者可以借多本不同的书;同一本《软件工程》(如果是多个馆藏副本),也可以被多名不同的读者借阅。
🚀 【Trae AI 联合实战:从模型审查到 DDL 生成】

第一步:让 AI 审查表结构与联系(架构排雷) “Trae,我初步设计了图书借阅系统的 ER 图。其中‘读者(Reader)’和‘借阅流水(BorrowRecord)’是 1对多(1:m)关系;‘图书(Book)’和‘借阅流水(BorrowRecord)’也是 1对多(1:m)关系。请帮我分析这种 ER 模型设计是否满足‘归还与违约清算’的需求?是否还需要增加扩展表或字段来应对复杂的超期情况?”

第二步:基于完善的 ER 图生成建表语句 “(与 AI 确认完毕后)逻辑清晰!现在请严格按照我们敲定的 ER 图关系,为我生成这三张核心表的 MySQL DDL 建表语句。要求:在记录表中正确设置外键指向,加上关联索引,并使用 Mybatis-Plus 或 Ruoyi 的常用表字段规范(如必须包含 create_time, update_time)。”


2.6 行为建模:状态转换图 (STD)

行为建模通过描绘系统的状态及引起状态转换的事件,来表示系统的动态行为。 你可以把系统里的数据想象成一个有生命周期的物体。STD 就是用来记录这个物体“在什么外界刺激下,会从当前状态变成另一种状态”。

2.6.1 场景推演:“一本书”的借阅生命周期 动态

实心圆表示初态,牛眼图形表示终态,带箭头的连线称为状态转换,线上标出触发转换的“事件”。

我们追踪一本新采购的图书在系统底层的流转:

  1. [初态] -> 在馆可用状态:图书管理员将新书录入系统(入库事件)。
  2. 在馆可用 -> 借阅中状态:学生在前台刷卡(事件:扫描借书证与条码),触发状态扭转。
    • 守卫条件:必须在“读者无欠款”且“未达到借阅上限”的条件下,动作才被允许。
  3. 借阅中 -> 超期未还状态:系统底层的定时任务(事件:触发每日零点巡检),发现该书已超出应还日期。
  4. 超期未还 -> 在馆可用状态:学生前往服务台缴纳罚款并归还图书(事件:人工处理还书与核销),状态重新恢复。
  5. 任意状态 -> [终态]:图书破损严重,管理员执行报废操作,该图书生命周期结束,归档入历史库。
🚀 【Trae AI 联合实战:从状态审查到枚举类生成】

第一步:让 AI 审查状态流转闭环(生命周期排雷) “Trae,我为借阅系统中的‘图书实体’设计了状态转换图(STD):包含‘在馆可用’、‘借阅中’、‘超期未还’、‘终态(报废)’四个状态。请结合图书管理的真实业务帮我审查:这些状态的流转事件是否构成了完整的闭环?有没有可能出现无法跳出的‘死锁状态’?”

第二步:基于确认的 STD 约束生成代码 “审查无误。现在请根据我们共同探讨的这段状态转换逻辑,为我生成 Java 的 BookStatusEnum 枚举类。要求:不仅要包含状态码和描述,还必须在枚举类中包含各个状态之间是否允许转换的业务校验方法(例如提供一个 canTransitionTo(BookStatusEnum nextStatus) 方法)。”


2.7 结构化框架核心:数据字典 (DD)

如果只有前面的 DFD 和 ER 图,系统依然是一个模糊的空壳。为什么?因为你在 DFD 里画了一个数据流叫“借书请求”,前端开发工程师以为是“学号+书名”,后端开发工程师以为是“身份证号+图书条码”。如果不统一,写代码联调时必将引发灾难。 数据字典就是把功能、数据和行为模型黏合在一起的“黏合剂”。它以词条的方式,对系统中的每一个名词给出极其严密的文字定义,不留任何歧义。

2.7.1 数据字典的“数学公式”语法 规范

为了彻底消除自然语言的歧义,DD 借用了严格的数学符号来表达数据的构成:

符号含义详细解释与系统案例应用
=被定义为表示左边的名词,由右边的内容构成。
例:借阅请求 = 读者学号 + 图书条码
+与 (AND)连接符,表示前后两者“同时存在”,缺一不可。
例:借阅流水 = 借阅单号 + 借阅日期 + 应还日期
[...]或 (OR)互斥选择,方括号内的选项只能多选一。
例:流水状态 = [ "正常借阅" | "已超期" | "已归还" ]
{...}重复表示大括号内的数据可以出现多次。左侧写最少次数,右侧写最多次数。
例:借书操作 = 1{欲借书条码}10 (根据背景:一次最少借1本,教师最多借10本)

2.7.2 核心数据元素词条深度穿透

只有把概念定义到最底层的“数据元素”(不可再分的最小单位),测试工程师与 AI 才有干活的依据:

📝 【工业级词条定义规范示范:图书条码】

  • 词条名:图书条码 (Book Barcode)
  • 类型:字符型,长度固定为 13 字节
  • 取值范围["0000000000000"..."9999999999999"]
  • 业务含义:馆内每一本实体书的唯一物理标识。

【底层逻辑延伸:为什么要这么啰嗦?】 初学者可能会问:大家都知道条形码是数字,有必要写这么细吗?极其有必要! 这是后续黑盒边界值测试以及数据库字段长度设计的唯一合法源头。如果不在这里锁死边界,AI 写代码时漏掉了长度限制,就会导致恶意乱码刷库引发生产事故。


2.8 加工逻辑说明:处理复杂业务逻辑的利器

DFD 图最底层的基本加工,不能只画个圆圈就完事,必须清晰地描述它如何把输入的数据变成输出的数据。 当业务逻辑包含多重嵌套的条件判断时,用大段文字描述极易产生逻辑漏洞。此时必须使用判定表 (Decision Table) 或判定树 (Decision Tree)。

2.8.1 判定表实战与化简规则 逻辑

业务场景:归还与违约清算模块中的“超期罚款逻辑”。罚款金额受“超期天数 (D)”和“读者类型 (T)”两个条件的交叉影响。

规则1规则2规则3规则4
条件:超期天数 DD ≤ 7天D ≤ 7天D > 7天D > 7天
条件:读者类型 T本科生教师本科生教师
动作:每日罚款额度0.1 元豁免 (0元)0.5 元0.2 元

化简原则(降低代码复杂度):如果两条规则的执行动作完全相同,且某一个条件项不管取什么值都不影响最终结果,则可以将该条件项合并为“-”(无关项)。这样 AI 在生成代码时就可以少写几层冗余的 if 判断。

🚀 【Trae AI 联合实战:从规则审查到核心逻辑生成】

第一步:让 AI 审查判定表逻辑(防漏判与冲突) “Trae,针对图书系统的‘超期罚款逻辑’,我设计了如下判定表:[此处附上你在 Markdown 里画的表格]。请帮我审查:这 4 条规则是否穷举了所有可能的输入组合?规则之间是否存在逻辑冲突或冗余?如果不满足化简原则,请告诉我原因。”

第二步:驱动 AI 基于表格生成策略代码 “(根据 AI 的反馈确认表格无误后)现在,请根据这份严密的判定表,使用策略模式 (Strategy Pattern) 为我生成计算超期罚款的 Java 核心逻辑。确保每一种读者类型对应一个具体的策略实现类,消除代码中丑陋的多重 if-else。”