软件分析与设计笔记 07:用户故事:把需求写成可验收的一句话
用户故事的三段结构,怎么从用户画像和数据地图里把它提取出来,一条故事多大算合适、时序为什么也是需求的一部分,以及验收标准怎么写才算真的可验收。
本文是 《软件分析与设计笔记》 系列的第 7 篇,共 28 篇
这是我在学习软件分析与设计时整理的系列笔记。概念部分是我按自己的理解写的,示例与图示都是自己编、自己画的。理解有偏差的地方欢迎指出。
贯穿案例:片区家电维修派单系统。04 预习、05 划范围、06 校验数据,这一篇把结论写成一条条可验收的用户故事 —— 它们是 08 篇用例图的原料。
0 一条写了等于没写的需求
需求清单里经常出现这样的条目:
「系统应该提供一个功能强大的管理后台,方便管理员管理各类数据。」
这句话不算错,但它没法用来做事。谁在管理?管理哪些数据?「强大」到什么程度算够?做完之后,怎么判断它达到了要求?
放到贯穿案例里,这类话通常是:「要让派单更高效。」 —— 更高效是几分?从几天到几小时?谁来算?
用户故事(user story)就是给这类模糊需求套一个可验收的壳。
1 三段结构
1.1 三段各自的作用
用户故事的标准句式是三段:
As a 〈角色〉, I want 〈目标〉, so that 〈价值〉
三段各自的作用不一样:
| 段落 | 回答的问题 | 写不好会怎样 |
|---|---|---|
| 角色 | 谁在操作 | 无法取样验证,也没法判断优先级 |
| 目标 | 他要达成什么 | 不可验收,做完也不知道算不算完成 |
| 价值 | 为什么想要 | 无法判断这条故事值不值得做 |
1.2 第三段最容易被省掉
第三段最容易被当成客套话省掉,但它其实是唯一能用来做优先级排序的信息。两条工作量相近的故事,价值说得清的那条明显更该先做。
拿本例对比一下:
| 写法 | 价值段 | 能不能排序 |
|---|---|---|
| A | 「……这样系统功能更完整」 | ❌ 排不了 |
| B | 「……这样我不用再逐个打电话,每天能省下两小时」 | ✅ 能,而且给出了度量口径 |
B 的写法还有个额外好处:它顺手把验收指标也给了 —— 上线后去看客服每天打电话的时长有没有真的降下来。
2 从哪里提取故事
用户故事不是凭空想出来的,它有两个主要来源。
2.1 来源一:用户画像
来源一:用户画像(persona)。 笔记 05 里那份画像的每一栏都能推出一批故事:
| 画像的栏 | 推出的故事 |
|---|---|
| 目标(一天结束不留下未派的单) | 作为客服,我想看到所有待派单的清单,这样我不会漏单 |
| 行为(翻便签本逐个打电话) | 作为客服,我想一次看到所有工程师的当日空闲时段,这样我不用挨个问 |
| 痛点(不知道谁有空) | 作为客服,我想按「技能 + 时段」筛选工程师,这样我能快速匹配 |
| 限制(不能排太满) | 作为客服,我想在排单时看到某人当天已有几单,这样我不会压垮一个人 |
2.2 来源二:数据地图
来源二:数据地图(application map)。 笔记 06 里那些「需要新增采集的数据」,每一条都对应一个故事:
作为片区经理,我想看到每个片区的缺料率,这样我知道该先改善哪个片区的备货。
这条故事的来源很明确 —— 06 篇应用地图里那一行「缺料率从 11% 降到 3%」。没有那一行,这条故事根本不会被想到。
2.3 一条判断标准
判断标准很简单:每一条故事,都应该能指回画像的某一栏或数据地图的某一行。指不回去的,多半是「我自己想做的功能」。
这条标准在考场上也管用。当你不确定某个用例该不该画进用例图时,回问一句「它对应谁的哪个痛点」—— 答不上来就删掉。
2.4 本例的一组故事(10 条)
把上面两个来源合起来,就是本例第一版的故事清单:
| # | 故事 |
|---|---|
| 1 | 作为客户,我想在线上提交报修并看到预计上门时段,这样我不用请假干等 |
| 2 | 作为客户,我想看到工程师已出发 / 已到达,这样我知道还要等多久 |
| 3 | 作为客服,我想一次看到所有工程师当日空闲时段,这样我不用逐个打电话 |
| 4 | 作为客服,我想按技能与片区筛选工程师,这样我能找到能修这个型号的人 |
| 5 | 作为客服,我想一键把工单派给某人并自动通知他,这样我不用再打电话 |
| 6 | 作为工程师,我想在手机上看到今天的派单与地址,这样我不用回办公室拿单 |
| 7 | 作为工程师,我想在出发前看到该型号常见的故障与所需配件,这样我少跑空趟 |
| 8 | 作为工程师,我想现场申请配件并看到仓库有没有货,这样我不用白跑 |
| 9 | 作为仓管,我想收到缺料预警并一键生成补货申请,这样我不会等工程师来了才发现没货 |
| 10 | 作为片区经理,我想看到实时看板(完成率、缺料率、平均时长),这样我不用月底手工汇总 |
注意这 10 条正好是按角色分的四组 + 一条经理的。08 篇画用例图时,这个分组会原样保留 —— 因为每条故事的角色,基本就是一个 actor。
3 一条故事多大算合适
3.1 太大与太小
用户故事不是需求唯一的粒度。往上,多条相关的故事可以归成一个 theme(主题);大到必须拆开的故事叫 epic(史诗)。往下,从系统角度描述的一块能力叫 feature(功能特性)—— 它和用户故事是两种视角,别混着写。
粒度(size)是用户故事最容易失控的地方。
- 太大(「作为客服,我想管理所有工单」)—— 一个迭代做不完,也没法验收;
- 太小(「作为客服,我想让按钮是蓝色的」)—— 这是实现细节,不该出现在需求里。
一个常用的判断尺度是:一条故事应该能在一个迭代内完成,并且能由用户自己判断「做到了没有」。
上面第 5 条(一键派单并通知)是合适的粒度;第 3 条和第 4 条如果合成一条「帮我快速派单」,就太大了 —— 它其实包含「看空闲」「筛技能」「选人」三个动作。
3.2 怎么拆:三种依据
story splitting(故事拆分)按什么切,有三种常见依据:
- 按流程步骤切 —— 提交 / 分派 / 上门 / 回填;
- 按角色切 —— 同一个功能,客户看到的和客服看到的拆开;
- 按数据范围切 —— 先支持空调,再支持冰箱洗衣机。
本例里第 7 条(出发前看故障与配件)很适合按数据范围拆:第一版只显示「该型号近 90 天最常见的三个故障」,第二版再做「所需配件库存查询」。
4 时序也是需求的一部分
这一条经常被漏掉。看这两条故事:
- 「作为工程师,我想收到派单提醒。」
- 「作为工程师,我想在派单后 1 分钟内、且距上门时间还有 2 小时以上时收到提醒。」
第二条多了两个触发条件:时延和提前量。而正是这两个条件决定了整个实现的复杂度 —— 要不要实时推送?半夜派单要不要叫醒人?
所以「什么时候提醒」这个问题问的就是这件事。
还有一条更隐蔽的时序:
- 「作为客户,我想看到工程师位置。」 —— 多久刷新一次?实时(每秒)还是每 5 分钟?
实时和每 5 分钟的差别,可能是几万块的服务器成本。如果不写进故事,开发要么按最省的做法(客户抱怨不实时),要么按最贵的做法(成本超预算)。两种都是失败。
所以写故事时,凡是带时间、频次、条件的,都要写进「目标」那一段,而不是留给开发自己猜。
5 什么样的故事是坏的
| 坏法 | 例子 | 问题 |
|---|---|---|
| 角色是泛称 | 「作为用户…」 | 无法确定取样对象,需求可能谁都不满足 |
| 目标不可验收 | 「…想要更好的体验」 | 无法写验收标准 |
| 价值为空 | 「…这样系统更完善」 | 无法判断优先级 |
| 混进实现细节 | 「…想要一个下拉框来选工程师」 | 把方案写成了需求,堵死了更好的做法 |
最后一条尤其值得警惕:它看起来最具体、最像需求,但它其实是你提前替用户做了决定。
本例里有个典型:如果有人把第 4 条写成「作为客服,我想有一个下拉框按技能筛选」,那就排除了「在地图上点选工程师」这类可能更好的做法 —— 而后者恰恰可能是客服真正想要的。
6 验收标准
一条故事只有配上验收标准(acceptance criteria),才真正可验收。验收标准写的是「怎么算做到了」,通常 2–5 条。
拿本例第 3 条(看到所有工程师空闲时段)写一遍:
作为客服,我想一次看到所有工程师当日空闲时段,这样我不用逐个打电话。
- 一屏内显示所有在职工程师的当日时段,无需滚动超过一屏;
- 每个时段标注「空闲 / 已排 / 满档」三态;
- 数据延迟不超过 1 分钟;
- 无排班数据的工程师单独列出,不隐藏。
写验收标准有个副作用:它会逼你发现故事里的漏洞。比如第四条,就是因为写到「没有排班数据怎么办」才发现原来还有这种情况。这类非正常路径通常叫负面场景(negative scenario);取值极端的情况则叫边界情况(edge case)。它们往往比主流程更值得写清楚。
本例里还有几个值得写进验收标准的负面场景:
- 同一个工单被两个客服同时派给不同的人 —— 怎么处理?
- 工程师临时请假,已派的单怎么回退?
- 客户改约到工程师已满档的时段 —— 允许还是拒绝?
这三条不写清,开发上线后一定出问题。而它们全都不是主流程。
7 Lean UX 与设计思维在这里的位置
7.1 一场「做—量—学」的循环
前面几篇的方法(设计思维、数据知情、用户画像、故事)在整体上是一套循环:
Build → Measure → Learn(build-measure-learn,做出来 → 量一量 → 学到东西),这也是 Lean UX 的基本节奏。而被拿去测量的那个最小版本,就叫 MVP(最小可行产品)。用户故事是这套循环里最小的工作单元:它既是开发要做的条目,也是下一轮里要被验证的假设。
放到本例,MVP 的定义很具体:只做第 3、5、8 三条(看空闲、一键派单、申请配件)。这三条合起来就能验证核心假设 ——「把排期可见之后,客服的电话会减少」。其他七条都等这一轮验证完再说。
反过来看,如果没有这条循环,用户故事就退化成一张任务清单 —— 做完就打勾,没人回头看它有没有解决问题。
7.2 一条合格故事的自查清单
顺带记一个自查清单:一条合格的故事通常满足 INVEST —— 独立(Independent)、可协商(Negotiable)、有价值(Valuable)、可估算(Estimable)、小(Small)、可测试(Testable)。
用上面那张 10 条的表过一遍,最容易不达标的是独立:第 8 条(现场申请配件)依赖第 9 条(仓管看到缺料)。这种依赖不可怕,但要显式写出来,否则排期时会发现「做完 8 却用不了」。
本节自测
- 用户故事的三段里,哪一段决定了优先级排序?为什么?
- 「作为用户,我想要一个下拉框」这条故事有哪两个问题?
- 把「作为工程师,我想收到派单提醒」补全成一条可验收的故事,需要加上什么?
- 验收标准通常写几条?它的副作用是什么?
- 用户故事在整个「做出来—量一量—学到东西」的循环里扮演什么角色?本例的 MVP 是哪几条?
- 本例中「客户想看到工程师位置」这条故事,为什么必须写明刷新频率?
- 举出本例中三个值得写进验收标准的负面场景。
参考答案
- 第三段(价值 so that)。因为它是唯一能用来做优先级排序的信息 —— 两条工作量相近的故事,价值说得清的那条更该先做;它同时给出了验收指标(§1.2)。
- ①角色是泛称「用户」,无法确定取样对象;②混进了实现细节「下拉框」,把方案写成需求,堵死了「地图点选」这类可能更好的做法(§5)。
- 要加上时序条件:例如「在派单后 1 分钟内、且距上门时间还有 2 小时以上时收到提醒」。这两个条件决定了实现复杂度(要不要实时推送、半夜要不要叫醒人)(§4)。
- 通常 2–5 条。副作用是会逼你发现故事里的漏洞 —— 写到「数据不够时怎么办」这类情况,才发现原来还有负面场景没考虑(§6)。
- 用户故事是这套循环里最小的工作单元,既是开发条目,也是下一轮要验证的假设。本例 MVP 是第 3、5、8 三条(看空闲、一键派单、申请配件),用来验证「排期可见后客服电话会减少」(§7.1)。
- 因为实时和每 5 分钟的差别可能是几万块的服务器成本。不写清,开发要么按最省的做法(客户抱怨不实时),要么按最贵的做法(超预算),两种都是失败(§4)。
- ①同一工单被两个客服同时派给不同的人;②工程师临时请假,已派的单怎么回退;③客户改约到工程师已满档的时段。三条全都不是主流程(§6)。
术语表
| 术语 | 中文 | 一句话解释 |
|---|---|---|
| user story | 用户故事 | 用「角色 / 目标 / 价值」三段描述一条需求 |
| epic | 史诗 | 太大、需要拆分成多条用户故事的需求 |
| theme | 主题 | 一组相关用户故事的集合,用于组织 backlog |
| acceptance criteria | 验收标准 | 判断一条故事「算不算做到」的检验条件 |
| feature | 功能特性 | 从系统角度描述的一块能力 |
| story splitting | 故事拆分 | 把过大的故事按流程、角色或数据范围切开 |
| negative scenario | 负面场景 | 非正常路径下的情况,如失败、异常、数据缺失 |
| edge case | 边界情况 | 极端取值下的情况,常在验收标准里补上 |
| Lean UX | 精益用户体验 | 以「做—量—学」循环推进设计的做法 |
| build-measure-learn | 做—量—学 | 先做出最小版本、再测量、再调整的循环 |
| MVP | 最小可行产品 | 能验证核心假设的最小版本 |
| INVEST | INVEST 原则 | 判断故事质量的六条标准:独立、可协商、有价值、可估算、小、可测试 |