3. 需求分类与建模:功能需求、非功能需求、约束条件、使用UML用例图建模

好,咱们今天聊点实在的。需求分析这件事,说白了就是搞清楚「系统到底要干什么」。但很多新手容易犯一个毛病——拿到需求就急着写代码,结果做到一半发现「咦,这个功能怎么跑不起来?」或者「客户说这不是我要的」。

我个人的习惯是,先花30%的时间把需求分门别类理清楚。你想想看,连需求都没分清楚,后面的设计、开发、测试怎么可能不翻车?

3.1 功能需求:系统「做什么」

功能需求是最直观的。用户说「我要一个温度传感器能上报数据」,这就是功能需求。它描述的是系统对外提供的具体行为。

我在一个智能家居项目中遇到过这样的场景:客户说「我要一个远程开关灯的功能」。听起来很简单对吧?但真正做起来,你得拆解成:

  • 用户通过手机App发送开灯指令
  • 云端接收指令并转发给网关
  • 网关通过Zigbee协议控制灯泡
  • 灯泡状态变化后反馈给App

你看,一个「开灯」背后藏着这么多子功能。所以写功能需求时,我建议用「主语+动词+宾语」的句式,比如「系统应支持用户通过App远程控制灯光开关」。

我的小技巧: 功能需求一定要可验证。别写「系统应快速响应」,要写「系统应在200ms内响应」。这样测试人员才知道怎么测。

3.2 非功能需求:系统「做得怎么样」

非功能需求,很多人容易忽略。但它往往是项目成败的关键。说白了,功能需求决定你能不能做,非功能需求决定你做得好不好。

我记得有一次做工业网关项目,功能都跑通了,结果客户一测说「你这设备在70度环境下就死机了」。嗯,这就是非功能需求没写清楚——工作温度范围。

常见的非功能需求包括:

  • 性能: 响应时间、吞吐量、并发数
  • 可靠性: MTBF(平均无故障时间)、可用性99.9%
  • 安全性: 数据加密、访问控制、防篡改
  • 可维护性: 日志记录、远程升级、诊断接口
  • 功耗: 电池供电设备待机电流不超过10μA
避坑指南: 我曾经在一个项目中,非功能需求只写了「系统要稳定」。结果验收时客户说「你们系统一天重启一次,这叫稳定?」。从那以后,我所有非功能需求都写具体数值。

3.3 约束条件:系统「不能做什么」

约束条件,就是那些你没法改变的限制。比如客户指定了用STM32F4系列芯片,或者通信协议必须是MQTT v3.1.1,又或者开发周期只有3个月。

约束条件通常来自:

  • 技术约束: 必须使用某款MCU、某款传感器、某款操作系统
  • 业务约束: 必须符合某行业标准(如医疗设备的IEC 60601)
  • 时间约束: 必须在某个日期前交付
  • 成本约束: BOM成本不能超过50元

我个人习惯把约束条件单独列一个章节。为什么?因为约束条件直接影响技术选型和架构设计。你想想看,如果客户指定用8位MCU,那你就别想着跑Linux了。

3.4 使用UML用例图建模

好了,需求分类清楚了,接下来怎么把这些需求可视化?我推荐用UML用例图。它不复杂,但非常直观。

用例图的核心元素就三个:

  • 参与者(Actor): 谁在用系统?可以是人,也可以是其他系统
  • 用例(Use Case): 系统提供什么功能?
  • 关系: 参与者与用例之间的关联,以及用例之间的包含、扩展关系

举个例子,一个智能门锁系统的用例图可以这样画:

参与者:住户、管理员、云端服务器

用例:
- 住户:指纹开锁、密码开锁、查看开锁记录
- 管理员:添加住户、删除住户、设置权限
- 云端服务器:同步开锁记录、远程开锁

关系:
- 住户「指纹开锁」包含「验证指纹」
- 管理员「添加住户」扩展「发送通知」

我在项目中画用例图时,有个原则:一个用例就是一个完整的业务场景。别把「输入密码」和「验证密码」拆成两个用例,它们合起来才是「密码开锁」这个完整功能。

实战建议: 用例图不要画得太细。我见过有人把「点击按钮」也画成一个用例,那就过度设计了。用例图是给干系人看的,不是给程序员看代码的。保持简洁,一张图讲清楚系统边界和主要功能就行。

3.5 三种需求的协同关系

最后说一句,功能需求、非功能需求、约束条件不是孤立的。它们互相影响。比如:

  • 功能需求「实时视频传输」会驱动非功能需求「延迟小于100ms」
  • 约束条件「使用Wi-Fi模块」会影响非功能需求「功耗」
  • 非功能需求「支持OTA升级」会衍生出功能需求「固件下载、版本管理」

所以我的做法是:先列功能需求,再补充非功能需求,最后确认约束条件。三者都写完后,用用例图把核心功能串起来。这样一套组合拳下来,需求文档基本就稳了。

嗯,今天就聊到这儿。下一节咱们讲怎么把需求写成规范的文档,到时候我会分享一个我踩过的坑——需求描述模糊导致开发返工的故事。