4. 需求分析与建模:用例图、活动图、状态机图、需求优先级排序
好,咱们进入第四章。需求分析,这个词听起来有点虚,对吧?很多工程师觉得,不就是把客户说的话记下来吗?我刚开始也这么想。直到有一次,我把客户一句「刹车响应要快」直接写进了需求文档,结果测试阶段吵得不可开交——到底多快算快?50ms还是200ms?
所以,需求分析不是记录,是建模。你得把模糊的、口语化的想法,变成结构化的、可验证的模型。今天我就带你走一遍我常用的四板斧:用例图、活动图、状态机图,再加上需求优先级排序。
4.1 用例图:谁在用,用来干嘛
用例图,说白了就是画清楚「谁」和「系统」之间有哪些交互。我习惯先画这个,因为它能快速对齐所有干系人的认知。
举个例子,一个车窗控制器ECU。谁在用?驾驶员、乘客、还有诊断工程师。驾驶员要一键升降、防夹;乘客可能只想降到底;诊断工程师要读故障码。这些就是不同的「用例」。
核心要素:
- 参与者(Actor):人、其他系统、硬件设备。比如驾驶员、CAN总线、BMS。
- 用例(Use Case):一个完整的功能目标。比如「一键升窗」、「读取故障码」。
- 关系:包含(include)、扩展(extend)、泛化(generalization)。
我在项目中遇到过最典型的坑:把「系统启动」也画成用例。其实系统启动是内部流程,不是用户直接关心的目标。用例图要聚焦在「用户价值」上,别画成内部流程图。
我的小技巧:每个用例的名字,用「动词+名词」结构。比如「设置车窗位置」、「请求软件版本」。这样一看就懂,不会产生歧义。
4.2 活动图:流程怎么走
用例图画完了,接下来要细化每个用例内部的流程。活动图就是干这个的。它有点像流程图,但更强调并发和分支。
你想想看,一个「一键升窗」用例,里面有多少分支?正常升窗、遇到障碍物防夹、车窗卡滞、电机过热保护……这些都得画清楚。
// 伪代码:一键升窗活动图逻辑
开始 -> 检测车窗位置
-> 如果位置在顶部 -> 结束
-> 如果位置不在顶部 -> 启动电机
-> 同时检测电流(防夹)
-> 如果电流超过阈值 -> 反转电机 -> 停止
-> 如果电流正常 -> 继续升窗
-> 检测到顶部 -> 停止电机 -> 结束
嗯,这里要注意:活动图里的「泳道」概念。我习惯把不同角色或模块放在不同泳道里。比如「驾驶员操作」一个泳道,「BCM(车身控制器)」一个泳道,「电机驱动」一个泳道。这样谁负责什么,一目了然。
我曾经踩过的坑:把活动图画得太细,连「延时5ms」这种实现细节都画进去了。活动图是给系统架构师和测试看的,不是给底层驱动工程师看的。保持抽象层次一致,别跳进代码细节里出不来。
4.3 状态机图:系统怎么变
活动图画的是流程,状态机图画的是「状态」和「状态之间的转换」。对于ECU开发来说,状态机图是重中之重。为什么?因为ECU本质上就是一个有限状态机。
举个例子,一个车窗控制器ECU的状态:上电初始化、待机、工作、休眠、故障。每个状态下,能做什么事,不能做什么事,都是严格定义的。
// 状态机图示例:车窗控制器状态
状态: 待机 (Idle)
- 进入动作: 关闭所有输出,等待CAN消息
- 事件: 收到升窗指令 -> 转换到 工作状态
状态: 工作 (Active)
- 进入动作: 启动电机驱动,开始检测电流
- 事件: 升窗完成 -> 转换到 待机状态
- 事件: 电流过载 -> 转换到 故障状态
状态: 故障 (Fault)
- 进入动作: 停止电机,记录故障码
- 事件: 收到复位指令 -> 转换到 待机状态
我个人习惯,每个状态机图都要标注清楚:
- 状态:用圆角矩形表示,名字要唯一。
- 转换:用箭头表示,上面标注触发事件和条件。
- 动作:进入状态时做什么,离开状态时做什么。
关键点:状态机图一定要覆盖所有异常路径。比如「电机堵转」、「通信超时」、「电源掉电」。很多bug就出在「我以为这个状态永远不会发生」的地方。
4.4 需求优先级排序:先做哪个
模型画完了,需求也列出来了。但资源有限,时间更有限。先做哪个?这就得排优先级了。
我常用的方法是MoSCoW法,简单粗暴:
| 优先级 | 含义 | ECU开发中的例子 |
|---|---|---|
| M (Must have) | 必须有,没有就不能交付 | 安全功能(如防夹)、基本通信(CAN报文收发) |
| S (Should have) | 应该有,但可以延迟 | 车窗一键升降带记忆功能 |
| C (Could have) | 可以有,锦上添花 | 车窗缓升缓降效果 |
| W (Won't have) | 这次不做,以后再说 | 语音控制车窗 |
你可能会问,怎么判断一个需求是M还是S?我有个经验法则:如果这个需求缺失,会导致项目无法通过法规认证或安全评审,那它就是M。比如ISO 26262要求的功能安全机制,必须是M。
我的排序小技巧:把每个需求写在一张便签上,贴在白板上。然后和团队一起,按照「如果不做这个,客户会骂娘吗?」来分类。骂得最凶的,就是M。这个方法虽然土,但特别有效。
另外,别忘了技术依赖关系。有些需求虽然优先级不高,但它是其他高优先级需求的前置条件。比如「诊断功能」可能只是S,但「读取故障码」是M,因为它是诊断功能的基础。所以排序时,要画一张依赖图。
我曾经犯过的错:把「车窗防夹功能」排成了S,觉得可以后面再补。结果测试时发现,没有防夹功能,车窗根本过不了ECE R21法规。最后不得不紧急返工,加班加点。从那以后,法规相关的需求,我全部标成M,没有任何商量余地。
4.5 总结一下
需求分析与建模,不是写文档,是建模型。用例图帮你理清边界,活动图帮你走通流程,状态机图帮你管好状态,优先级排序帮你砍掉废话。
我个人习惯,每次项目启动前,先花一周时间把这四样东西做扎实。磨刀不误砍柴工,后面开发、测试、验收都会顺畅很多。你想想看,如果需求都没对齐,后面返工的成本,可不是一周能补回来的。
好,这一章就到这儿。下一章我们聊聊需求管理工具和版本控制,那又是另一个有意思的话题了。