2. 文档体系全景:需求文档、概要设计、详细设计、测试文档、用户手册的层级关系
做嵌入式开发这么多年,我见过太多团队在文档上栽跟头。要么是文档堆成山却没人看,要么是代码写完了才发现缺这缺那。说白了,文档不是写给领导看的,是写给未来的自己看的。
今天咱们就把这五类文档的层级关系捋清楚。你想想看,盖房子需要什么?先有设计图,再有施工图,最后还有验收报告。嵌入式软件也是一样的道理。
2.1 五类文档的定位与职责
我把这五类文档比作一个倒三角结构。需求文档在最上面,用户手册在最下面。每一层都承上启下,缺一不可。
核心观点:文档不是写完了就完事,每一份文档都要能追溯到上一级,也要能指导下一级。这叫「双向追溯」。我在项目中吃过亏,需求改了但设计没同步,结果代码跑飞了三天才找到原因。
| 文档类型 | 核心职责 | 读者对象 | 产出阶段 |
|---|---|---|---|
| 需求文档 | 定义「做什么」 | 产品经理、架构师、测试 | 项目启动期 |
| 概要设计 | 定义「怎么做」的宏观方案 | 架构师、开发组长 | 需求评审后 |
| 详细设计 | 定义「具体怎么实现」 | 开发工程师 | 概要设计评审后 |
| 测试文档 | 验证「做对了没有」 | 测试工程师 | 设计与编码并行 |
| 用户手册 | 告诉用户「怎么用」 | 最终用户、运维 | 产品发布前 |
我的习惯:每次写文档前,先问自己三个问题——这份文档给谁看?他需要知道什么?他看完能做什么?想清楚这三点,文档结构自然就出来了。
2.2 层级关系:从抽象到具体
这五类文档不是平级的,它们有严格的层级关系。我画了一张图,你看一眼就明白了。
从上往下看,需求文档最抽象,用户手册最具体。但注意,测试文档和用户手册是并行关系,它们都基于详细设计来产出。
2.3 需求文档:一切的开端
需求文档是所有文档的源头。它要是写歪了,后面全白干。我个人习惯把需求文档分成两部分:功能需求和非功能需求。
- 功能需求:系统要做什么。比如「按键按下后LED亮2秒」。
- 非功能需求:系统要做到什么程度。比如「响应时间不超过50ms」、「功耗低于100mW」。
我曾经踩过的坑:有一次需求文档里只写了「系统支持OTA升级」,没写升级失败怎么回滚。结果现场升级到一半网络断了,设备变砖。后来我要求所有需求文档必须包含异常场景和边界条件。
2.4 概要设计:架构师的战场
概要设计是架构师的主场。这里不写具体代码,只画大图。模块怎么划分?任务怎么调度?通信协议用什么?这些都在概要设计里定下来。
我一般用下面这个模板来组织概要设计:
1. 系统架构图(模块划分与接口)
2. 任务/线程划分与优先级
3. 关键数据流与控制流
4. 硬件资源分配(Flash、RAM、外设)
5. 通信协议选型与设计
6. 安全与可靠性策略
一个小技巧:概要设计里不要写超过一页的流程图。如果一张图画不下,说明模块划分有问题。我习惯用「高内聚、低耦合」来检验模块边界是否合理。
2.5 详细设计:开发者的施工图
详细设计是把概要设计里的每个模块拆开,写到函数级别。这里要回答的问题是:每个函数怎么实现?数据结构怎么定义?状态机怎么跳转?
举个例子,概要设计里说「系统有一个按键扫描任务」,详细设计就要写清楚:
- 按键扫描周期是多少(10ms还是20ms)
- 消抖算法用延时消抖还是状态机消抖
- 按键事件怎么传递给上层(消息队列还是回调函数)
嗯,这里要注意。详细设计不是把代码抄一遍,而是把设计思路写清楚。代码会变,但设计思路不会轻易变。
2.6 测试文档:质量的守门员
测试文档和详细设计是并行的。我见过很多团队等代码写完了才写测试用例,这其实晚了。测试文档应该在详细设计阶段就开始写。
测试文档包含三个层次:
- 单元测试:针对每个函数,验证边界条件和异常输入
- 集成测试:验证模块之间的接口和交互
- 系统测试:验证整个系统是否满足需求
我的经验:测试文档里最容易被忽略的是「负向测试」。比如一个函数要求输入参数范围是0-100,那测试用例里一定要有-1、101、空指针这些情况。我曾经因为没测空指针,在客户现场蓝屏了两次。
2.7 用户手册:最后的脸面
用户手册是产品交付的最后一环。说实话,很多嵌入式团队不重视用户手册,觉得「用户自己看看就会了」。但你想过没有,用户遇到问题第一个找的就是手册。
用户手册要写清楚三件事:
- 怎么安装/部署:接线图、配置步骤
- 怎么操作:界面说明、按键功能
- 出问题了怎么办:常见故障排查、指示灯含义
避坑指南:用户手册里不要写技术术语。比如不要说「系统采用I²C总线与传感器通信」,要说「系统自动检测传感器连接状态」。用户不关心你用什么协议,他只关心好不好用。
2.8 文档之间的追溯关系
最后说一个关键点:文档之间要有追溯关系。什么意思?就是需求文档里的每一条需求,都能在概要设计里找到对应的设计,在测试文档里找到对应的测试用例。
我习惯用编号来建立追溯:
| 需求编号 | 需求描述 | 概要设计对应 | 详细设计对应 | 测试用例对应 |
|---|---|---|---|---|
| REQ-001 | 系统启动时间 < 3s | SDD-01 启动流程 | DD-01.1 初始化函数 | TC-001 ~ TC-005 |
| REQ-002 | 支持OTA升级 | SDD-02 OTA模块 | DD-02.1 ~ DD-02.5 | TC-010 ~ TC-020 |
| REQ-003 | 功耗 < 50mW | SDD-03 电源管理 | DD-03.1 休眠策略 | TC-021 ~ TC-025 |
有了这张表,需求变更的时候你就能快速定位到哪些设计要改、哪些测试要重跑。没有追溯的文档,说白了就是一堆废纸。
最后说一句:文档体系不是一天建成的。刚开始可以只写需求文档和详细设计,慢慢再把概要设计和测试文档补上。关键是先跑起来,再优化。别想着一步到位,那反而容易把自己吓住。