3. 需求分析:功能需求与非功能需求、业务规则梳理、数据流图绘制、状态机建模

好,咱们进入第三章。这一章可以说是整个需求分析环节的「硬核」部分。很多新手写文档,容易把需求写得像「用户故事」一样松散。但真正的软件规格文档,必须把功能、非功能、规则、流程、状态这五样东西,像搭积木一样严丝合缝地拼起来。

我个人习惯,拿到一个需求后,先不急着写文档。我会先问自己三个问题:系统要做什么?做到什么程度?不能做什么? 这三个问题回答清楚了,后面的工作才有根基。

3.1 功能需求与非功能需求:一个都不能少

先说功能需求。说白了,就是「用户能用系统干什么」。比如登录、下单、导出报表。这些是显性的,客户通常能说清楚。

但非功能需求就麻烦了。客户往往说不出来,或者觉得「这还用说?」。比如系统响应时间、并发用户数、数据安全性。我在项目中遇到过,客户验收时突然说「怎么这么慢?」——结果一看,当初根本没约定响应时间。嗯,这就是非功能需求没写清楚的后果。

核心区别:

  • 功能需求:系统「做什么」—— 动词 + 名词(如:用户提交订单)
  • 非功能需求:系统「做得怎么样」—— 度量 + 约束(如:订单提交响应时间 < 2秒)

我建议,写非功能需求时,一定要带上可量化的指标。别写「系统要快」,要写「在100并发下,平均响应时间不超过1.5秒」。你想想看,没有数字的约束,开发人员怎么落地?测试人员怎么验收?

需求类型 示例(错误) 示例(正确)
功能需求 用户能查看订单 用户可按订单号、日期范围、状态筛选订单列表
非功能需求 系统要安全 用户密码需加密存储(SHA-256),传输使用HTTPS
非功能需求 系统要稳定 系统可用性 ≥ 99.9%,年宕机时间不超过8.76小时

我的小技巧: 写非功能需求时,可以对照一个检查清单——性能、安全、可用性、可维护性、可扩展性、兼容性。每项至少写一条,这样基本不会漏。

3.2 业务规则梳理:藏在流程里的「潜规则」

业务规则,是需求文档里最容易「打架」的地方。为什么?因为业务规则往往是「例外情况」。正常流程大家都懂,但「如果用户余额不足怎么办?」「如果商品库存为0怎么办?」——这些才是真正的坑。

我曾经在一个电商项目中,因为没写清楚「优惠券和满减能否叠加使用」,导致开发做了两版逻辑,最后上线前才发现冲突。嗯,那次教训挺深刻的。

梳理业务规则,我推荐用决策表规则矩阵。把条件列出来,把结果列出来,一目了然。

举个例子,一个简单的「订单取消规则」:

条件 规则1 规则2 规则3
订单状态 = 待支付
订单状态 = 已发货
距离下单时间 < 30分钟
结果:允许取消 是(需审核)

你看,三行规则就把所有情况覆盖了。开发看到这个,直接写if-else就行,不会产生歧义。

注意: 业务规则一定要和业务方逐条确认。别自己脑补。我曾经见过一个团队,把「会员折扣」规则写错了,结果上线后所有订单都打了8折,公司亏了一周才发现。

3.3 数据流图绘制:让数据「流动」起来

数据流图(DFD),说白了就是画清楚「数据从哪里来,到哪里去,经过谁处理」。很多分析师觉得这玩意儿过时了,但我认为它依然是沟通利器。为什么?因为它不涉及具体技术,业务人员也能看懂。

画DFD,我习惯分两层:

  • 上下文图(顶层):只画一个系统框,外面是外部实体(用户、第三方系统),箭头表示数据流向。这张图用来和客户确认「系统边界」。
  • 0层图:把系统框拆成几个主要功能模块,画出模块间的数据流动。这张图给开发看,让他们理解模块依赖。

举个例子,一个「在线书店」的上下文图:

+----------------+       +------------------+       +----------------+
|   顾客(外部)  | ----> |   在线书店系统    | ----> |   支付网关      |
|   (提交订单)    |       |   (处理订单)      |       |   (扣款)        |
+----------------+       +------------------+       +----------------+
        ^                        |
        |                        v
        |                 +----------------+
        +-----------------|   库存系统      |
          (查询库存)       |   (更新库存)    |
                          +----------------+

画图时,记住四个要素:外部实体、处理过程、数据存储、数据流。箭头方向别画反了,数据流是「数据在移动」,不是「控制流」。

我的经验: 画DFD时,尽量用工具(如Draw.io、Visio),别手画。手画改起来太痛苦了。而且,每张图一定要配上文字说明,解释每个数据流的含义。光看图,别人可能猜错。

3.4 状态机建模:把「状态变化」管起来

状态机,是处理「有状态」业务的神器。比如订单、工单、审批流程——这些对象都有明确的生命周期。状态机建模,就是画出状态、事件、转移这三者的关系。

我见过最惨的案例:一个工单系统,没有状态机,开发用一堆if-else硬写。结果后来加了「重新打开」功能,所有if-else都要改,改完又引入一堆bug。嗯,这就是没建模的代价。

状态机通常用状态转移图状态表来表示。我推荐两者都用:图给业务看,表给开发看。

一个「订单」的简化状态机:

[待支付] --(支付成功)--> [已支付] --(发货)--> [已发货] --(确认收货)--> [已完成]
    |                       |
    +--(取消)--> [已取消]   +--(退款)--> [退款中] --(退款完成)--> [已退款]

对应的状态表:

当前状态 事件 下一状态 前置条件
待支付 支付成功 已支付 支付金额 = 订单金额
待支付 取消 已取消
已支付 发货 已发货 库存充足
已支付 退款 退款中 未发货
已发货 确认收货 已完成
退款中 退款完成 已退款 退款处理成功

避坑指南: 我曾经漏掉了一个「超时未支付自动取消」的状态转移。结果上线后,大量待支付订单堆积,数据库都快炸了。所以,状态机一定要覆盖所有「时间触发」的事件,比如超时、定时任务。

好了,这一章的内容就这些。总结一下:功能需求和非功能需求要分开写,业务规则用决策表梳理,数据流图画清楚数据走向,状态机把生命周期管住。这四样东西写好了,你的需求文档就有了「骨架」。下一章,咱们聊聊如何把这些内容组织成一份完整的文档结构。