值得收藏!万字长文详解用户故事拆分流程和方法 | IDCF
更新:HHH   时间:2023-1-7



用户故事拆分是敏捷交付团队的日常做法。但是以我的经验,执行起来真的很困难。在本文中,我将所学到的有关故事拆分的所有内容汇总在一起。

这会是一篇很长的文章,所以您可能要在开始之前先喝杯热腾腾的茶。




一、什么是用户故事


我认为用户故事是范围的单位,是交付的单位

重要的是,用户故事向他人传递了有用的(或有价值的)信息。在IT环境中,“他人”通常指的是使用系统的人(尽管有时是另一个利益相关者,想以某种方式限制用户,例如保护系统免受未经授权的访问)。

因此,通常从用户角度以“作为……我可以……以便于……”格式描述用户故事,从而迫使交付团队始终专注于用户正在试图达成的目标及其原因。

注意:术语“用户故事”通常用于两个有微妙差异的场景。

  • 如上所述,我通常用它来表示要交付的范围单位,例如“我们已经在此Sprint中交付了故事X,Y和Z”。

  • 但是,它也广泛地被用来指代这些范围单位的描述 -“ 尽可能……我可以……如此……”范式。

在本文中,我使用术语用户故事来指代范围本身,而术语用户故事描述则指的是这些范围单元的说明。当我谈论故事拆分时,我说的是将范围项拆分为较小的范围项,而不是将范围项的描述拆分为较小的说明!

1.1 用户故事的属性和INVEST准则

根据INVEST 准则https://en.wikipedia.org/wiki/INVEST_(mnemonic)用户故事应为:

  • 独立 - 不依赖其他故事
  • 可协商 - 并非一成不变,可以进行讨论
  • 有价值 - 对某些利益相关者(通常是最终用户)
  • 可估计的 - 足够清晰,交付团队可以很好地知道它有多大
  • 足够小 - 小到足以在一个sprint /迭代中传递多个故事
  • 可测试 - 如果无法测试,则显然对任何用户都无济于事

以我的经验,这通常没有那么简单 -  拆分故事以使它们“足够小”通常会在故事之间引入依赖关系,而单个故事往往本身并没有价值,只有一定数量的相关故事一起,它们才有价值去交付。

因此,我倾向于将INVEST属性视为准则,而不是无可争议的法律。一些属性更适用于史诗(大故事),而另一些属性更适用于小故事。

对于所有故事而言,我的一条规则是:无论故事多大,它们都必须提供用户可见的内容。这等同于垂直故事切分,后面会详细介绍。


二、为什么要拆分故事?


拆分故事最典型的原因是将它们分成几小块 - 足够小以在一次冲刺中交付其中的几个。你怎么吃大象?一次一小块。

我认为,还有另一个原因同等重要(如果不是更重要的话),并且可能不太为人理解,就是与帕累托原理(也称为80:20法则https://en.wikipedia.org/wiki/Pareto_principle)有关。

80:20法则基本是说你可以在20%的时间内完成80%的工作。换句话说,完成最后20%的工作需要80%的时间。它反映了一个事实,即大多数工作都涉及许多“花哨的工作”,这些工作需要很长时间才能完成,因此尽管感觉您快要完成了,但实际上并不是。

在软件交付领域,工作的最后20%通常代表替代流程 - 异常,意外或错误情况。通常,这些高付出的“怪异碎片”中的相当部分都是价值很低的 - 它们处理的神秘场景通常会在蓝色月光下偶尔出现一次。

拆分故事使我们有机会将高价值的东西与低价值(高付出)的东西分开。一旦故事被拆分,并且子故事被放置在产品待办事项列表中,则在重新确定优先级的对话期间,低价值故事会自然地过滤到待办事项列表的底部。

这样做的好处是,我永远不需要与产品负责人就是否应该处理某个特殊情况争论不休。我可以将其放在待办事项列表上,并让他们相应地对其进行优先级排序。项目发起人迟早会花费时间在项目时间分配上,低价值的东西将永远无法交付(也称为“修剪尾巴”)。

拆分故事时,我会尽量牢记这两个目标:将它们缩小,然后剥离低价值的部分。


三、故事层次和史诗


通常会将大型故事称为史诗。

我的经验是,可能有必要对史诗(大故事)进行多次拆分,然后才能找到适合开发团队的“大小适中”的故事。这取决于原始(史诗)故事的大小,开发团队希望这些故事的大小,以及我需要拆分多少次才能分离出所有低价值内容。

因此,我将故事拆分视为一种迭代活动 – 一个大故事拆分为两个或多个子故事,然后可以进一步将每个子故事拆分为多个子故事,依此类推,直到每个故事都变得足够小为止。这并不是说我需要事先拆分所有的故事。我只在适当的时候拆故事,以后在需要时再拆。关键是最终会有故事的层次结构,层次结构可以有很多层,并且并非所有分支都具有相同的深度。例如:

一些团队/方法/工具定义了故事的分类法,在层次结构中具有固定数量的级别。例如:

  • 第1级:史诗 Epic
  • 第2级:功能 Feature
  • 第3级:能力 Capability
  • 第4级:故事 Story

我不喜欢这种方式。我的经验是,故事层次结构并不总是整齐地落入固定的层级,因此团队需要花太多时间思考,“这个故事是史诗级的还是仅仅是功能性?”事实上是哪个层级并没有关系。

我更喜欢遵从迈克·科恩(Mike Cohn)的建议(https://www.mountaingoatsoftware.com/blog/you-dont-need-a-complicated-story-hierarchy)一切都是故事。如果我分解一个故事,我会得到……一些故事。如果我有一个故事,感觉有点大,可以拆分,或者已经拆分了,可以将其称为史诗,但这仍然是一个故事。

一个史诗 是一个用户故事,感觉大到足以进行分割,或已经被分割。

重要的是,如上所述,无论故事大小如何,它仍然提供用户可见且对利益相关者有用的内容,因此我仍可以用“作为……我可以……这样……”的格式来编写其摘要。


四、要拆多小


您如何知道故事“足够小”?

我的经验是,这取决于你的交付团队以及冲刺周期。最近,我一直在两周一个冲刺的团队中工作,开发人员希望故事小到可以在每个冲刺中交付8-12个故事。他们希望能够最多用几天来发布一个故事。

较小的故事可以提高工作效率和动力 – 团队成员可以一次专注于一件小事,并很快完成它 – 每天回家时都可以完成某件事,或者是有希望结束。小的故事还有助于更好地进行资源计划 - 故事可以更轻松地在团队成员之间分配,并且更容易解决团队成员的缺席/离开。

将故事拆到如此程度通常意味着将其分解到可以被视为或者是独立的,或者是对最终用户有价值的程度 – 用户价值通常只有在交付了许多相关的、相互依赖的故事时才能得到。正如我上面提到的,很难让一个故事同时具备所有INVEST属性。

在我工作的每个团队中,我们都通过反复试验找到了理想的故事大小。方法如下:我会准备一些故事(已经有了BDD草案,并在适当的创建了一些线框或HTML原型)。我会安排一次三方会议,与团队一起逐一地过故事。对于每个故事,在我要求他们进行估算之前,我先询问他们是否认为故事足够小。如果没有,我们会去找一种拆分方法。经过几次这样的讨论后,我会感觉到什么是一个故事的“合适大小”,并且通常会以适当大小的故事进入三方会谈。具有讽刺意味的是,随着团队的成熟和工作效率的提高,他们有时会觉得现在的故事太小了,最终可能会合并以前拆开的故事!


五、何时拆分故事


对此的简单答案是:Just In Time。

我需要大小适中的故事来进入下一个冲刺/增量。或者,如果我正在用看板,则只需要大小适中的故事来让所有开发人员忙起来。

我按优先顺序分析故事,包括拆分。因此,如果故事的优先级较低,那么它可能仍然很大,因为我尚未对其进行任何分析。

因此,我希望产品积压的顶部附近的故事很小,而底端附近的故事会较大。我的待办事项应如下所示:

(顺便感谢Ken Rubin的图:https://innolution.com/)

其实真实情况并非如此。请记住,我拆分故事的动机之一是拆分低价值的,并让它们过滤到待办事项的底部。每次我分解一个故事时,重要的是要将子故事与其余待办事项重新排序,请确保这种过滤效果的真实发生。因此,在我的待办列表底部可能还会有一些小故事 – 这些是我已经分解的那些低优先级故事。

5.1 首先做一些分析

在分解故事之前,我首先需要做一些分析工作来理解这个故事。否则,我对它的了解不足以支撑如何拆分它。

实际上,我有一个相当结构化的流程来进行分析工作。实际上,它是如此结构化,我给它起了一个名字:Business Analysis Designer Method(BADMhttp://www.its-all-design.com/business-analyst-designer-method/)。下图总结了这一过程:

不要上当,BADM 不是瀑布方法。相反,每个阶段依次针对要传递的单个故事执行。

  • 在“请求”阶段,需要一个故事,但是在那个阶段,我们还不知道目标是什么,或者实现目标的最佳方法是什么。

  • 在“定义”阶段,BA业务分析师会识别利益相关者,了解机会空间,提出建议如何实现机会并与产品所有者PO和其他利益相关者达成共识。BA还会在适当的情况下将故事拆分为子故事。

  • 子故事将被添加到产品待办事项列表中,并对其进行优先级排序,该方法将在子故事上持续进行迭代,直到它们“足够小”为止。

  • 最后,在“设计”阶段,BA交付所需的更详细的分析 - 接受标准和/或行动方案(又称用例),线框(或UI原型),数据模型等。

我并不是建议每个人都应该使用BADM,但是在拆分故事之前花一些时间来理解故事的范围绝对是一个好主意。


六、垂直故事切片


如上所述,我仅有一个分割故事的黄金法则。当我拆分故事,每个子故事都必须提供一些用户可见的内容。当我说“用户可见”时,我的意思是在系统的一个用户或系统界面上可以观察到(一个用户当然可以是另一个系统)。

这才是问题所在。当出现“太大”的用户故事时,开发团队的第一个直觉通常是按照体系结构划分,一名开发人员进行数据库架构更改,另一个编写中间层业务或控制器逻辑,第三个人变更用户界面。

这个故事被“水平地”切分到了架构的各个层次。这种方法存在一些问题:

  • 在所有相关故事完成之前,你看不到明显的用户收益
  • 在所有相关故事完成之前,我们无法测试系统
  • 在所有相关故事完成之前,我们不会发现任何体系结构问题
  • 我们错过了将高强度,低价值的部分分割出来留作未来交付的机会

因此,首选的方法是“垂直”分割故事,每个故事通过每个(相关)架构层传递一小段变更。这样,我们在每个故事交付后都有一些(较小的)用户收益,我们可以测试每个故事,并且可以更快地确定任何体系架构问题。

垂直切片故事时,请注意:

  • 某些故事可能仅影响表示层(例如,更改字段或按钮标签),而不是对所有架构层进行切片。
  • 有些故事会更改系统界面,而不是用户界面。它们仍然是“用户可见的”,但是在这种情况下,系统的用户是另一个系统,而不是人类用户。
  • 一些故事是无功能的,例如性能或安全性增强。没关系,响应时间的改善是用户可见的。
  • 有些故事是事件触发的(批处理)过程,它们会影响系统状态(即它们会更改数据库中的数据),但在发生时却无法通过任何用户或系统界面看到(尽管稍后会看到其效果,下次查询数据)。这是“用户可见”规则的一个特殊例外,允许用户佩戴X射线眼镜以观察系统状态的变化!同样,故事是可以测试的,但是测试人员需要在数据库中探测一下才能看到更改。

还要注意,一旦故事“足够小”,开发团队可能仍会决定将其分为“水平”部分:数据库变更,UI修改等。这完全没问题,将故事分解为任务  (特别是开发任务),有些团队会在冲刺计划时这样做,以帮助他们估算故事的工作量和/或在团队成员之间分配工作。不同之处在于,你需要理解并且有预期,除非所有开发任务都完成,故事才算完成(甚至才能进行测试)。范围或交付的单位是故事,而不是任务。

我只在这里提供了垂直故事切片的摘要。有很多非常好的文章更详细地进行了介绍,例如Ned Kremic撰写的这篇文章:http://www.deltamatrix.com/horizontal-and-vertical-user-stories-slicing-the-cake/。


七、用户目标分解


如上所述,垂直故事切片就是将故事分成越来越小的用户可见的更改。每个故事,无论多么小,都会为用户带来有价值的东西,这有助于他们实现某些目标。垂直故事切片的另一种方法是用户目标分解。通过拆分故事,我将用户目标拆分为子目标。

我们用一个例子来说明。假设我有一个用户故事,如下所示:

  • 注册
  • 作为不需要的东西的所有者,
  • 我可以注册在线拍卖网站
  • ,以便可以出售不需要的东西

该故事的用户目标是 注册在线拍卖网站。好处是  卖掉我的东西。但是这个故事太大了,我想把它分开。所以我这样分割它:

  • 注册–输入详细信息
  • 作为不需要的物品的所有者,
  • 我可以输入我的注册详细信息(姓名,电子邮件地址等)
  • 以便可以注册在线拍卖网站
  • 注册–提交详细信息
  • 作为不需要的物品的所有者,
  • 我可以提交我的注册详细信息
  • ,以便可以注册在线拍卖网站

我创建了两个子目标– 输入我的注册详细信息并提交我的注册详细信息。在这种情况下,后者取决于前者-我必须输入我的详细信息,然后才能提交它们。更重要的是,一旦我同时达到了两个子目标,我就实现了我的初衷– 注册在线拍卖网站。然后,我可以进一步细分子故事,直到我的故事“足够小”为止。我最终会得到故事的层次结构和目标的层次结构。

尤其要注意的是,子故事的“ so that”陈述(利益)就是原始故事的“ I can”陈述(目标)。换句话说,收益确实是更高层次的目标。一旦意识到这一点,编写子故事的“so that”部分就变得容易得多,它们只是父故事(即父目标)的“I Can”部分。

最好这样解释用户故事描述模板:

  • 作为<用户>,
  • 我可以<目标>
  • ,以便<更高级别的目标>

也可以得出结论,我最初目标的利益– 销售我的东西  –实际上只是一个更高级别的目标。反过来,这又是更高级别目标的子目标,可以赚钱。反过来又是购买食物的一个子目标,然后是 供养我的家人,再然后 让我的家人活着。依此类推,直到您最终陷入上一级目标的无限循环,或者陷入诸如“我们存在的意义是什么”这样的哲学问题中……


八、三个命名的目标级别


由于用户目标的层次结构可能是无限的(向上和向下),因此确实存在迷失的风险。Alistair Cockburn 在其最出色的著作《写作有效用例》(https://www.amazon.co.uk/Writing-Effective-Crystal-Software-Development/dp/0201702258)很好地解释了目标分解,尤其是他通过识别和命名三个特定的目标等级来建立了隐喻锚。他在书中谈的是用例,但该理论同样适用于用户故事。

  • 最重要的目标级别是用户目标级别,也称为海平面或蓝色。在此级别上,一个用户可以在单个活动中实现(或未能实现)单一目标,例如“列出要出售的商品”。您可以通过询问目标是否通过“咖啡时间测试”来检查这个目标是否为用户目标:实现目标后,您是否有足够的理由来休息一下喝杯咖啡?
  • 高于用户目标级别的是摘要级别,也称为云/风筝级别或白色。摘要级别的用户目标是相关用户级别目标的集合,例如“管理窗口小部件”细分为“创建窗口小部件”,“视图窗口小部件”,“编辑窗口小部件”和“删除窗口小部件”。
  • 低于用户目标级别的是子功能级别,也称为水下级别或靛蓝。子功能级别的目标本身对用户无直接的价值,它们是实现用户级别目标的步骤,例如,“输入商品名称”是“列出待售商品”的子目标。“登录”是常见的子功能级别目标,登录本身并不能实现任何目的,它通常是实现其他目标的前提。

Cockburn非常有意地选择了海平面/云层/水下隐喻。天空很高,海洋很深,相应地有许多嵌套级别的云层目标和水下目标(并且有许多白色阴影和许多靛蓝阴影)。但是只有一个海平面——用户目标是用户目标,应该非常清晰地定义。需要澄清的是,我并不是在提倡三层固定的用户故事层次结构,我早些时候已经对此表示了反对。我只是说,识别海平面在用户故事层次结构中的位置对于跟踪交付用户价值很有用。


九、故事分割顺序


有许多久经考验的方式来垂直剖析故事。多年来,我注意到我倾向于按特定顺序应用各种技术。有些技术适用于较大的故事,而其他技术一旦当故事变小就变得更加趁手。因此,我将按通常应用它们的顺序来介绍各种技术。请注意,这不是一成不变的规则。对于给定的故事,并非所有技术都适用,并且不一定以相同的顺序使用。我可能还会多次使用某一种技术。

开始了…


十、拆分用户故事的技术


术1:拆分NFRs

对于任何给定的故事,我想做的第一件事就是将其分为两部分:一部分交付功能本身,另一部分交付该功能的NFR(非功能需求)。

拆分的主要目的是使团队专注于交付功能,而不会被NFR分散注意力。项目早期尤其重要,此时有很多尚未解决的架构问题,事先让他们都一一解答会让事情变慢。

以下是您可以考虑推迟来关注的NFR列表:

  • 性能:延迟使其快速
  • 可扩展性:推迟使其支持大量并发用户或大量数据
  • 并发:推迟使其支持多个并发用户(数据锁定,竞争条件等)
  • 可用性:推迟使其具有高可用性和容错能力
  • 安全性:推迟保护其免受攻击
  • 可用性/可访问性:推迟使其易于使用(适用于所有人)
  • UX:推迟使其美观
  • 跨浏览器/平台:推迟使其适用于各种客户端设备
  • 国际化:推迟支持多种语言/本地约定

所有这些事情都具有分散团队注意力的可能,使他们无法快速交付简单的东西(刚好可以正常工作),并且可以随后基于(重构)这些东西以在适当的时候交付各种NFR。拆分NFR并对团队说:“我们将研究NFR,但现在不必担心它们”。也许我们甚至可以在不(正式地)考虑所有NFR的情况下提供MVP。这取决于我的MVP是公开发行还是有限定向用户组的私人Beta版。

我通常一开始将NFR分解为一个单一的故事,称为“ Project X NFR”或“ Feature X NFR”。在适当的时候,当我们确实 需要更详细地研究NFR时,我才可能将这个NFR故事进一步细分为各个NFR类别(性能,可用性,安全性等),并一一列举,当然是按严格的优先级顺序。

最终,对于每个后续故事,我们可能会将相关的NFR纳入“完成的定义”中。但这是另一篇文章要说明的事情。

恰好在“适当时候”发生,是一个很好的平衡。我们不想太早地在体系架构上受挫,但是我们也不想太晚去考虑它,否则我们可能会承担过多的技术债务,而且还要承担体系架构风险。同样的,判断是伴随经验而来的,从来不会有一个唯一简单的答案,多年来,我见到的过度设计的系统和设计不完善的系统一样多。

技术2:按用户界面通道拆分

这是拆分NFR的特殊情况。我上面提到的NFR之一是跨浏览器/平台的支持,如果我的系统具有用户界面,并且打算支持多个渠道(例如,台式机,平板电脑,移动设备)或多个平台(例如,Windows,Mac,iOS,Android,各种智能电视),那么首先集中精力在这些渠道/平台其中的一个是更有意义的,显而易见应该选择我们认为大多数用户拥有的渠道/平台。

但是,与其他NFR一样,这又是一个平衡:在项目中的什么时候开始考虑其他平台?当然,没有正确的答案,这取决于具体情况。

我从事的一些项目具有公司(或政府)标准的UI框架,该框架已经被设计为可响应的(即在多个平台/设备上工作)。显然,从一开始就使用标准框架是有意义的,前提是它相对稳定并且不会增加过多的开销或学习曲线。即使我们不选择这样做,我们仍然可以选择推迟正式开始跨平台的合规性。这里有一个细微的差异:推迟正式合规,是说我们还不会进行跨平台系统测试。跨平台测试可能会非常耗费人力,通常最好在发布前不久进行一次,而不是在每个故事中都做一遍。我们的测试人员现在可以专注于功能测试,并且我们可以更快地进展。

技术3:按用户类型拆分

一些故事服务于多样化的用户社群。我在这里没有太多谈论国际化,而是在考虑用户类别。

例如,在最近的项目中,我们的用户分为以下几类:

  • 英国用户
  • 欧盟用户(但不包括英国)
  • 欧盟以外的用户(也称为“第三国”用户)

不要让我开始聊英国脱欧,这是另一个故事(呵呵)。

要点是,这三个类别的功能都不相同。英国用户必须采用一种方法进行注册,欧盟用户采用第二种方法进行注册,第三国用户则采用另一种方法进行注册。

因此,我们决定首先关注英国用户。然后我们发现了另一个分类:

  • 英国个人
  • 英国组织

同样,每个类别的功能都不同。因此,我们决定首先关注英国组织。然后我们发现了另一个分类:

  • 英国注册公司
  • 英国非法人公司
  • 英国伙伴关系

信不信由你,这些子类别的注册规则又再次不同。我们首先关注英国注册公司,并为他们提供了完整的注册过程(尽管我们用稍后将介绍的其他技术进一步简化了注册过程)。然后,我们开始按照业务优先级顺序添加其他用户类型。再次回到英国脱欧——如果英国很快退出欧盟,我们将不会区分欧盟还是第三国用户,因此我们将欧盟用户放在优先级较低的位置。

最后,我们将用户群细分为大约15个用户类型,并针对大约8个独特的用户旅程进行注册。为第一种用户类型交付功能需要大量工作,随后添加的每种额外用户类型变得越来越容易。但是,如果我们尝试一次全部完成这些任务,我认为任务将是无法达成的。

技术4:将摘要目标分为用户目标

到目前为止,我们已经拆分了各种NFR,因此我们可以先关注功能,然后再按用户类型进行拆分,以便专注于为单个用户组提供服务。

在接下来的拆分中,我们回到前面讨论的“三个命名的目标级别”的概念。具体来说,我们希望将故事分解成可以通过“咖啡时间测试”的单个用户目标(“海平面”目标),这些目标可以由一个用户一次活动就可以实现,而完成后则可以享受咖啡时间。

一个非常常见的例子是将数据维护故事分为其CRUD组件,例如:

  • 维护小部件

变成

  • 创建小部件
  • 查看小部件
  • 更新小部件
  • 删除小部件

另一个常见的例子是一个涉及多个角色的故事。例如:

  • 作为博客作者,我可以发表文章

可能成为:

  • 作为博客作者,我可以要求发布我的文章
  • 作为编辑,我可以批准发表文章

摘要级别目标还有无数其他类型,可以细分为用户目标。

子故事通常遵循逻辑顺序,你必须能够创建一个小控件才能查看它,并且您可能想先查看一个小控件,然后再对其进行更新或删除。您必须先请求发表文章才能获得批准。但这并不一定意味着故事必须按顺序交付,完全有可能通过后门来创建窗口小控件(通过直接数据库加载),因此,如果查看窗口小控件是价值最高的子故事,则可以这样做。

技术5:按场景/流程划分

到目前为止,我们的故事处于用户目标级别:可以由一个用户一次活动就可以实现。作为美好的一天,对我们的用户来说一切都会很美好。他们将执行操作、输入数据并实现他们的目标。这就是我们所说的Happy Path方案。会有许多方法来实现目标,因此可能会有多条快乐的路径。

但是事情可能不会那么顺利,他们可能输入了无效数据,或者他们执行了不适当的操作,或者他们找不到正在搜索的数据,并且他们可能未达到目标。在任何情况下,事情都可能会出错,因此我们将其称为替代流程

例如,

  • 创建小部件

可能成为

  • 创建小部件–成功
  • 创建小部件–小部件名称已存在

另一个例子:

  • 登入

可能成为

  • 登录–成功
  • 登录–无效的登录详细信息
  • 登录–失败3次(锁定帐户)
  • 登录–帐户已锁定

这里的关键点是,某些替代流程的优先级可能较低。例如,处理无效的用户ID或密码是高优先级,但是在三次失败尝试后锁定帐户可能不是很高。

对于给定的用户级别故事,并非总是很清楚所有替代流程是什么。为了找到它们,为主要的欢乐路径写出相应的步骤是一个非常好的主意。例如:

  • 1.用户要求登录
  • 2.系统询问用户其登录详细信息(用户标识和密码)
  • 3.用户输入登录详细信息
  • 4.系统验证登录详细信息对现有帐户有效
  • 5.系统验证帐户未锁定
  • 6.系统登录用户并显示主页

步骤4提出了一个问题:如果登录详细信息无效,该怎么办?我们找到了替代流程。

步骤5提出了一个问题:如果户被锁定怎么办?我们找到了另一种替代流程。

如果您在想拆分替代流程时束手无策,绝对应该阅读 Alistair Cockburn的书。

技术6:镀铜与镀金

在技巧5中,我将故事分为个人流程 - 欢乐路径和替代流程。我们很可能会先专注于交付主要的欢乐路径。但是在我们这样做之前,我将先看一下它,看看是否有我可以先做的更简单的版本。

例如,假设我们正在构建一个注册功能,而我们想要捕获的一个信息就是用户的生日。我们可以将其实现为日期选择器,并弹出一个漂亮的日历。但是我们也可以将其作为一个简单的文本输入字段来完成,这可能会更快,更容易构建。从而:

  • 寄存器

变成

  • 注册– DOB的简单日期字段
  • 注册– DOB日期选择器

我有时称其为“铜镀层”,而不是“金镀层”,对于MVP来说已经足够了。当然我们可以做得更好,如同前文阐述的,在待办事项优先级的驱动下,是否以及何时使它变得更好,取决于与其他的待办事项相比,我们对日期选择器的重视程度。

这是解决团队内部争执于如何准确交付特定功能的一个好技巧。您将流程分解为“最低限度的最低要求”(即MVP),然后为每个层次的要求分别建立一个故事。(产品负责人)可能会认为某些功能要求是必不可少的 - 没问题,我们在MVP故事之后不久就做。其他人会将其放进待办列表,以待日后完成,也许永远不做。有趣的是,我被多次告知某项功能“必不可少”,仅仅是因为发现该功能在待办列表的底部停留了六个月之久。显然,它上面的所有内容都更重要。

这是您可以使用的其他一些镀铜技巧:

  • 手动与自动。可以很容易地假设,因为您正在构建IT系统,所以一切都必须完全自动化,而有时手动处理可以用于处理少量任务或在MVP中使用。例如,除了webops团队运行的手动数据库脚本外,我当前正在使用的系统无法创建新的管理员用户。这是一种痛苦,但这种情况不会经常发生。
  • 硬编码与可配置。也许用户必须选择他们的标题(先生,太太等)。理想情况下,选项列表应该可以从可配置列表填充,该列表可由管理员用户轻松维护。但作为捷径,该列表可以在页面中硬编码。
  • 假设与要求。 与其允许用户在你的博客应用自行选择头像,你可以在第一个实例中自动为他们分配随机模式,自定义头像稍后再发布。
  • 简单与复杂的体系架构。函数的某些部分可能需要复杂的体系架构解决方案。例如,地址查找功能需要与第三方软件集成,因此是否有一个更简单的选项可以避免使用它,例如手动输入地址?但是要小心,有时你想尽早解决架构风险,因此,如果该概念行不通,您可以“快速失败”(请参阅下面的技术999)。当然这个问题没有统一的答案。

技术7:分步进行

因此,到目前为止,我已经为单个功能确定了一条快乐路径,并且将其缩减为对MVP有意义的最低限度……

…但是我的开发团队仍然希望将其分解成较小的功能进行交付,以便他们可以快速完成故事并查看进度。

这里的一种选择是告诉开发人员,在继续具有商业价值的同时,无法合理地分解故事。另一个选择是将其进一步分解,以使有价值的故事一次累积一点。

重要的是,我们仍然希望垂直分割故事,以便每个子故事都提供用户可见的内容。我们不想水平地分割故事,因为这只会给我们开发任务,而不是故事。

显而易见的事情是将功能分解为各个步骤。在第一种情况下,如果该功能涉及用户遍历多个屏幕,则可以在每个屏幕上拆分一个故事。然后,您可以将其拆分,以便逐步交付每一个屏幕。您的工作量取决于开发团队的偏好。我经常发现当团队还年轻时希望故事很小,而随着他们的成熟,可以应对更大的故事。

逐一步骤的一种变体是为该功能构建一个“骨架”。你从具有起点和终点但中间没有任何东西的功能开始。例如,一个“注册”按钮可通过“提交”按钮将用户带到空白页。当用户单击“提交”时,他们会收到一条消息,告知他们已成功注册。但是实际上什么也没发生。然后,逐个故事地填补空白,收集各种数据并实际创建注册。关键是您可以采用多种不同的方式对其进行分解,而不必按顺序进行。

骨架方法的另一个变体是先构建前端用户流,但不建立后端 - 所有后端调用都被插桩。这样的好处是,它可以让您尽早看到完整的用户流,并在不起作用时对其进行调整(尽管另一种方法是构建简单的HTML原型)。

顺便说一句,此技巧的另一种用途是将故事从用户目标级别(海平面)拆分为子功能级别(水下平面)。

技巧999

Spike探针是一个旨在传递知识而不是交付生产的故事。当遇到大小和/或架构不确定的故事时,团队通常会“尝试Spike”并花一些时间进行基本的研究,或者更可能是进行实际编码,以便更好地了解大小或方法。

从表面上看,这似乎是个好主意,但我曾经遇到过探针的问题:

  • 目标不明确 - 与商业故事相比,探针故事不太可能具有明确的接受标准。
  • 时间尺度不明确 – 理论上讲,应该对探针进行时间限制,但是如果任务未知,那么最简单的就是说“好吧,让我们看看它如何发展”。

范围不确定和时间有限的结合,就像我认识的许多开发人员来说圣诞节早到一月 – 这是一个随机探索并看看会发生什么的机会。即使是纪律严明的开发人员,也有被带走的严重风险。

例如,假设我们的团队正在构建API,并且我们决定使用RAML来说明那些API(RAML是目前非常流行的API标记语言)。我们希望在我们的网站上发布API文档,并且我们决定一种较好的方法是构建一个RAML到HTML的转换工具。

因此,我们进行探针,构建了一个RAML到HTML的转换工具。一个开发人员被分配到这个探针,然后开始。他们每天在站会上报告进展,应该很快能够完成。几周后,进展顺利,而且是个好消息 – 它完全符合RAML 1.0,并且可以从任何有效的RAML文件生成HTML!

但是,当我们查看实际想要构建的API时,我们发现我们只需要使用RAML 1.0的子集,他构造的一半是浪费的精力。

这个例子基于一个真实的故事,但实际上并没有那么糟糕。在构建的过程中,我们更改了方法。我们没有继续“ RAML到HTML转换器工具”的介绍,而是开始定义面向业务的故事,为真实的API提供实际文档,而我们专注于一次建立一点点RAML到HTML的转换,仅构建我们实际需要的。通过这种方法,我们避免了解决方案的过度设计,并且还更快地交付了一些实际的业务价值。

我的母亲总是告诉我不要用尖锐的铅笔四处走动,原因是如果我绊着而摔倒,可能会导致严重的事故并最终住院。换一种说法:

  • 小心探针。

通常,我会尽量避免探针。相反,我花时间与开发人员一起了解架构不确定性所在的位置,并尝试将一个故事分解为一些子故事,这些故事使他们可以一次了解一点儿架构,同时仍能始终提供业务价值。

将这项技巧编号为999,有两个原因。首先,这是不得已的方法,必须在所有其他技术之后使用;其次,(在英国)这是您拨打的呼叫救护车的电话号码,这似乎很适合使用具有潜在危险性的技术!


十一、故事拆分很难


当我着手撰写本文时,我并没有意识到会需要多长时间。具有讽刺意味的是,我写了一篇有关将史诗分解成故事的本身就是史诗的文章。

这篇文章的长度可以说明问题 - 故事拆分很复杂,以我的经验来说,做起来很难。我已经做了很多年了,但我仍在学习新的技巧。这是通过实践和经验而能变得更好的技能之一,因此,如果您在挣扎中,请不要放弃!


十二、结论


自从您开始阅读本文以来,可能已经过去了几十年,值得快速回顾一下:

  • 拆分故事不仅是要使故事变小,而且还要拆分低价值、高投入的部分,以便它们可以沉在待办事项底部。
  • 拆分故事是迭代的,并且没有固定的迭代次数,因此定义固定的层次结构“史诗/功能/故事/其他”是没有意义的。
  • 你编写的故事多小取决于你的团队是否满意。
  • 故事应“及时”拆分,但只有在进行足够的分析以便充分理解故事后,才能进行。定期重新确定优先级,以确保低价值的事项确实压在舱底。
  • 故事应垂直分割,即将用户目标分解为子目标。
  • Cockburn的三个命名目标级别对于跟踪你的目标非常有用,尤其是“海平面”目标,这可以由单个用户在单个会话中实现,因此可以在此后喝咖啡庆祝。
  • 有许多故事分解技术,而且我发现可以有一个一致的顺序来应用它们 - 随着故事从大到小。
  • 故事拆解很难!

参考文献

  • 比尔·韦克(Bill Wake)的文章,其中有很多关于如何拆分故事的想法,是为数不多的几篇文章之一让你认识到主要是为了将高价值的东西与低价值的东西分开。http://xp123.com/articles/twenty-ways-to-split-stories/ 
  • 理查德·劳伦斯(Richard Lawrence)的这篇文章也赞成80:20规则 – 并且它也有一些很好的模式来拆分故事。http://agileforall.com/patterns-for-splitting-user-stories/ 
  • 迈克·科恩(Mike Cohn)关于故事就是故事这一事实的文章。https://www.mountaingoatsoftware.com/blog/you-dont-need-a-complicated-story-hierarchy
  • Rachel Davies的一些更出色的模式,他还谈到了推迟低价故事的想法。http://agilecoach.typepad.com/agile-coaching/2010/09/ideas-for-slicing-user-stories.html
  • 由Alistair Cockburn 撰写的有效用例 – 描述了三个命名的目标级别,并列出了替代流程的停滞。
  • 敏捷和业务分析:Lynda Girvan和Debra Paul撰写的IT专业人员实用指南 – 特别是第8章,它讨论了目标分解,也感谢Lyn提供了关于目标分解的更多见解。
  • 对故事拆分技术的很好描述,以及很好的深入解释Christiaan Verwijs的垂直故事切片。http://blog.agilistic.nl/10-useful-strategies-for-breaking-down-large-user-stories-and-a-cheatsheet/

作者:Tony Heap

原文地址:http://www.its-all-design.com/how-to-split-user-stories/

译者:姚冬


返回开发技术教程...