Skip to content

把需求切成可验证的小块:按业务结果切,而不是按技术层切 ​

一个「会员积分」需求拆成了四个任务:建表、写后端接口、写前端页面、联调。每个任务都按时完成,三周后联调时才发现:积分的计算口径和运营理解的不一样,接口少了一个字段,页面的交互要重做。前三周的进度都是「完成」,可没有一样东西能给业务方看。

把一个需求拆成小任务,几乎每个团队都在做。差别在于怎么拆:按技术层拆(数据库、后端、前端),每一块都完成不了一件业务上的事,必须全部做完才能第一次验证;按业务结果拆,每一块都是一个从界面到数据库都打通的小功能,做完就能给人看、能验证对不对。后者常被称为纵向切片。

本文说明为什么纵向切片能缩短反馈距离、怎样从一个需求里切出切片,以及它的边界在哪里。这是一篇方法文,没有配套实验。

按技术层拆分按业务结果纵向切片建表后端接口前端页面联调:第一次看到完整功能切片 1界面接口存储可演示切片 2界面接口存储可演示切片 3界面接口存储可演示切片 4界面接口存储可演示切片 5界面接口存储可演示第一次业务反馈:所有任务完成之后第一次业务反馈:切片 1 完成之后切片 1 刻意极简(固定倍率、没有过期),只为尽早跑通链路、验证最核心的假设完成的标准是业务方确认结果,而不是代码写完;确认中发现的问题进入下一个切片
图 1 · 示意:按技术层拆分时,每一块都完成不了一件业务上的事,第一次完整反馈要等联调之后;纵向切片的每一片都穿过界面、接口与存储,第一片几天内就能给业务方演示,口径不对在这时改代价最小。

一、反馈距离:从做出决定到知道它对不对 ​

每一个开发决定(积分怎么算、接口返回什么、页面怎么交互)都是一个假设,要等到有人用上它才知道对不对。从做出决定到得到反馈之间的时间,就是反馈距离。

按技术层拆分时,最早的完整反馈出现在联调之后:数据库的设计对不对,要等后端用上才知道;后端接口对不对,要等前端用上才知道;整个功能对不对,要等业务方看到才知道。所有的错误都堆到了最后。

纵向切片让第一个切片在几天内就走完全程:一个最简单的积分规则、一个最简单的页面、一张最简单的表。业务方看到它,立刻就能指出「口径不对」,这时改动的代价是几小时,而不是三周。

二、怎样切:每一片都是一个业务结果 ​

以「会员积分」为例,按业务结果切:

切片用户能做什么验证的是什么
1下单成功后,在「我的积分」里看到这一单获得的积分(固定每元 1 分)积分的口径、从订单到积分的数据链路
2退款后积分被扣回逆向流程、积分不能为负的规则
3不同会员等级的积分倍率规则的配置方式
4积分即将过期的提醒有效期规则、定时任务
5用积分抵扣订单金额与支付的集成、并发扣减

每一片都穿过界面、接口、存储,都能单独演示和验收。切片 1 刻意做得极简(固定倍率、没有过期),它的目的是让整条链路尽早跑通,并验证最核心的假设:积分到底怎么算。

几种常用的切法:

  • 按业务规则的复杂度:先做最简单的规则,再一条条加上例外。规则怎样用例子谈清楚,见用例子把规则谈清楚。
  • 按流程的步骤:先做正向流程,再做逆向(退款、取消)和异常。
  • 按用户群体或数据范围:先支持一种会员、一个地区、一类商品。
  • 先手动、后自动:过期提醒先由运营手动导出名单,自动化放到后面的切片。

判断一个切片切得好不好:它完成之后,能不能给业务方演示一件他们关心的事,并且得到「对」或者「不对」的回答。

期限固定时,范围是调节项 ​

需求在交付中途变化很常见。期限、人手、范围三者通常有一两个是固定的,讨论变更时先说清楚哪个固定、哪个能动,再给出具体的选项:把新需求拆成后续切片、用新切片替换一个还没开始的切片、推迟期限、接入现成的服务代替自研。「加人」也是一个选项,但新加入的人要先熟悉代码和业务,而且关键路径上的工作不会因为人多而变短(关键路径的概念见依赖图执行),它不是默认的答案。

无论选哪一项,正确性、安全与数据完整性这类底线不在可调节的范围里。把底线写进每个切片的验收条件或完成的定义,而不是在赶期限时临时商量。

需求有多少不确定,也决定了反馈要多频繁。探索性的问题(用户到底需不需要这个功能)用最短的循环去验证,可能只是一个原型;需求清楚、风险在集成与数据迁移上的工作,则把验证集中在那些风险点上。不要因为团队用了某个流程名称,就对所有工作套用同样的节奏。

三、切片的验收 ​

每个切片在开始前写下它的验收条件,形式和从行为到场景到断言里的例子一致:给定什么情况、做了什么、应该看到什么。验收条件来自业务方,而不是开发团队对需求的理解。

写验收条件时有两个常见的缺口。一是角色:「操作的人」和「受益的人」常常不是同一个,例如老师录入成绩、学生查看成绩、教务导出报表,切片要说清楚这一片让谁得到了什么,否则验收时各方的期望对不上。二是可观察性:「然后用户能看到进度」不是一个可以判断对错的结果,要写成「然后列表中这一项显示为已提交,提交时间为 9:05」。还没有答案的问题单独记下来,带编号和负责回答的人,不要在验收条件里替业务方补一个看似合理的答案。

切片完成的标准是「业务方确认了这个结果」,而不是「代码写完了」或「测试通过了」。确认的过程中发现的问题(口径不对、漏了一种情况)正是切片要尽早暴露的东西,它们进入下一个切片,而不是被当作这个切片的失败。

验收结果属于哪一个版本 ​

「测试通过」「业务方确认了」这样的结论都有适用的对象。从需求到线上,每一跳都有自己的身份,任何一跳变了,后面的结论就要重新得出:

环节身份什么情况下之前的结论失效站内展开
需求需求的修订号口径或规则改了,旧的验收条件不再代表新需求本节
验收条件与判据判据的版本判据被改写;候选代码不能修改自己的判据判题结果对哪一组输入有效
测试运行被测的提交两个分支各自通过,合并后的提交没有人运行过两个分支的检查都通过了
构建产物产物摘要(镜像 digest)同一个标签指向了不同的镜像;按环境重新构建得到的是另一个产物同一个镜像 tag,跑的不是同一个镜像
部署部署修订与配置版本配置已下发但没有生效;回滚时数据结构已经变了配置中心显示已推送,线上行为没有变、能重新部署旧版本,不等于能回滚
运行观察指标对应的版本与时间窗口指标混合了新旧两个版本的流量可观测性

需求改了之后,旧修订上的绿色检查不能自动证明新需求已经满足。验收记录里写上它针对的需求修订、提交和产物摘要,变化之后就能看出哪些结论要重新得出;只写「已通过」,就只能凭记忆判断。

一次需求修订在这条链上的传播:

需求r3 → r4验收条件按 r3 写的测试运行提交 a1b2构建产物digest 9f…部署修订 17运行观察新旧流量混合变化发生在这里之后的绿色结论都只针对旧修订,需要重新得出每一跳都有自己的身份:修订号、判据版本、提交、产物摘要、部署修订、时间窗口
图 2 · 示意:结论都有适用的对象。需求从 r3 改到 r4 后,按 r3 写的验收条件、在旧提交上跑通的测试、由它构建的产物与部署、混着旧版本流量的观察,都只证明了 r3。验收记录写明需求修订、提交与产物摘要,变化之后就能看出哪些结论要重做;只写「已通过」,只能凭记忆判断

状态要让依赖方能采取行动 ​

切片的状态不只给自己看。一条只写着「进行中」的记录,依赖它的人无法据此做任何决定。有用的状态还要说明:

  • 卡在哪里:是验收条件没通过、在等另一个团队的接口,还是有一个问题等业务方决定;三种情况要找的人不同。
  • 依据是什么:失败的验收条件、错误日志或者测试结果的链接,而不是「好像有问题」。
  • 谁在处理,下次什么时候更新:给依赖方一个可以安排自己工作的时间点。
  • 对依赖方的影响:例如「接口字段会改名,你们的调用方要在下周三前调整」。

风险越早让依赖方知道,他们能选择的应对就越多;到验收时才说延期,留给所有人的只剩加班。反馈的另一端也要有人回应:只增加汇报的频率,而没有人根据它调整计划,消息再多也不起作用。

在一个新系统里落地领域模型时,第一个切片的选择标准和做法,见在真实项目里落地 DDD:精益切片与遗留改造。

四、术语:Sprint、产品目标与完成的定义 ​

如果团队使用 Scrum,纵向切片和它的几个概念直接对应。按 2020 版 Scrum Guide:

  • 产品目标(Product Goal):产品的长期目标,例如「会员复购率提升」。
  • Sprint 目标(Sprint Goal):这一个 Sprint 要实现的价值,通常是一个或几个切片的组合,例如「会员能在下单后看到并使用积分」。
  • 完成的定义(Definition of Done):每个增量都要满足的质量标准,例如「通过验收测试、已部署到预发环境、业务方已确认」。
  • 增量(Increment):每个 Sprint 结束时可用的产品。按技术层拆分时,Sprint 结束得到的往往不是一个可用的增量。

Scrum Guide 2020 版删去了旧版中的部分规定性内容(例如每日站会必须回答的三个问题),把重点放在目标与增量上;引用 Scrum 的说法时,以最新版本为准。

五、什么时候按技术层拆分是合理的 ​

纵向切片不是绝对规则。下面这些情况,横向的技术任务是合理的:

  • 基础设施的一次性投入:搭建部署流水线、引入一个新的数据库。但要尽快用一个最小的纵向切片验证它。
  • 高风险的技术验证:不确定某个技术方案是否可行时,先做一个技术原型(spike),明确它是为了回答一个问题,做完就丢弃或重写。
  • 团队按技术分工且无法调整:这时至少让各层的任务按同一个切片的顺序推进,让第一个切片尽早端到端跑通。

六、检查清单 ​

  • 每个任务完成后,能不能给业务方演示一件他们关心的事?
  • 第一个切片是否刻意做到最简,尽早跑通整条链路?
  • 每个切片开始前有来自业务方的验收条件。
  • 切片完成的标准是业务方确认,而不是代码写完。
  • 必须做的技术任务,尽快用一个纵向切片验证。
  • 需求变更时说清哪项固定、哪项可调,底线写进验收条件。
  • 验收记录写明针对的需求修订、提交与产物摘要。
  • 状态记录说明卡在哪里、依据、负责人与下次更新时间。

参考资料

文章以 CC BY-NC-SA 4.0 授权 · 代码片段以 MIT 授权