1、为何故事拆分很重要
2、什么样的用户故事才算是恰当的故事?
2.1 用户故事格式
2.2 恰当的故事应遵循INVEST原则
2.3 用户故事是垂直切片
3、故事拆分流程图
步骤1:准备好要拆分的故事/特性
步骤2:套用拆分模式
3.3 步骤3:评估拆分效果
4、Cynefin和故事拆分
5、练习故事拆分
6、垂直切片和规模化
6.1 是否应该让100+的人去开发一个产品?
6.2 规模化垂直切片的基线数据库
从优先级最高的、工做量较小的用户故事开始开发,可让产品团队持续输出高价值的产物,并得到高质量的反馈。许多团队都在努力将较大的用户故事和特性(feature)拆分红恰当的小故事,可是他们没有从业务的垂直切片来拆分,而是从整个技术架构的的角度,拆分出了不少看起来更像研发任务(Task)或组件(Component)的故事,最终致使他们未能体验到小故事应有的价值或反馈。编程
幸运的是,故事拆分是一种能够在较短的时间内学会的技能。咱们已经看到,团队仅需几个小时的练习和一些简单的工具,就能够从挣扎中解脱出来,快速地拆分故事。稍后,咱们将介绍如何组织这种练习。segmentfault
在讨论拆分用户故事以前,咱们须要确保咱们对什么样的用户故事才算是恰当的故事、以及能够将哪些内容拆分为故事有一个共同的理解。后端
首先,让咱们看下用户故事的定义:用户故事是从用户的角度描述系统行为的变化。它描述的是用户想经过系统作的事情,或者但愿系统为他们作的事情,而这些事情如今的系统里尚未。性能优化
顺便说一下,请注意,用户故事位于方案域(solution space)而不是问题域(problem space)。它不是一我的想在某个地方完成一个任务的描述(就像JTBD[Job to be Done,待完成的工做]同样),而是一我的想要在你的系统中完成某件事情的描述。JTBD在问题域中能够与客户产生很好的共鸣,而用户故事能够很好地将客户的共鸣转化为对软件系统的一系列改变,同时在整个交付过程当中保持客户的视角。架构
你可能常常会看到以以下特定格式书写的用户故事:dom
或者有的是这样:工具
该模板的优势在于它要求你回答用户故事中的三个问题:性能
不过,重要的不是模板,而是回答这三个问题。学习
实际上,咱们不多会用完整的模板来写故事。不管是在便签纸的顶部仍是在在线项目管理工具的标题字段里,一个写着“WHAT”的简短标题都会是比较好的选择。“WHAT”由标题提供,而“WHO”一般由产品愿景或版本目标提供,它描述了核心目标客户。若是故事是为该目标客户准备的,咱们就不重复撰写了,咱们只有在为非核心目标客户撰写用户故事时,才把“WHO”加上。最后,咱们将确保在在线工具的“详细描述”或相似的字段中,或者在便签纸上用较浅的字体写明“WHY”。
所以,若是咱们要作一个公共图书馆的网站,而且图书馆的读者是咱们的默认用户,则咱们不会这样来书写用户故事:
咱们会这样来写:
有时咱们会遇到将单独的研发任务或架构组件假装成用户故事的状况。即便你使用了诸如“做为开发人员,我想要一份数据库关系图,以便我能了解数据库的结构”这样的神奇描述,它仍然只是一个开发任务。
几年前,极限编程先驱Bill Wake提出了一个很好的首字母缩略词,用来表示一个恰当的用户故事应具备的6个关键属性:INVEST。让咱们来挨个看一下:
(故事并不须要单独提供足够的价值来直接发布。你可能须要积累多个故事,才能从有价值转变为可销售。我喜欢最小可销售特性(MMF,Minimum Marketable Features)做为故事的容器。)
固然,这些属性之间存在着必定的互斥关系。好比说,随着故事的规模变小,使其变得独立且有价值的难度就会变大;随着故事的可协商性变大,其可估算和可测试的难度就会变大。
不过幸运的是,不一样的属性在不一样的时间起主要做用。例如在进入Sprint计划后,更重要的是故事要短小、可估算和可测试。这时咱们仍然须要故事有必定的独立性、可协商性和有价值,但这些属性这时已经变得不那么重要了。而在Product Backlog中的故事,状况偏偏相反。
在提到恰当的故事时,你常常会听到垂直切片(vertical slice)这个词。这是恰当的故事在软件架构方面的要求。
咱们来看一个很是简单的系统架构,这里有UI层、业务逻辑层和持久层。你的系统可能比这更复杂,但它可能至少包含这三层。
(系统架构示意图)
要想得到INVEST的大部分属性,故事必然会涉及这3个架构层级。若是不进行某些UI的改变、逻辑的改变、持久存储的改变,咱们可能就没法交付价值。所以,故事就是系统的一个垂直切片。
有时候,这些垂直切片很是宽。当咱们进行故事拆分时,咱们将讨论如何在较宽的垂直切片中找到较薄的垂直切片。可是到目前为止,咱们只须要知道故事应该在必要时跨越架构层级来提供价值就足够了。
许多刚组建的敏捷团队会尝试按照架构层级来拆分故事:一个故事用来实现UI,另外一个故事用于更新数据库等等。虽然这个故事可能也很小,但在独立性和价值交付上是失败的。当团队以垂直切片的方式拆分时,他们将会获得以下收益:
咱们还能够继续说下去,但这些应该已经能够给你一些启发了。当咱们一块儿坐下来,写下咱们在成功的敏捷团队中看到的各类习惯,以及各个习惯之间的关系时,咱们发现垂直切片几乎与全部其余习惯有关,或至少与部分习惯有关。
看看Product Backlog中的故事,有些是你最近完成的,有些是未来要作的。根据INVEST标准评估每个故事,找出垂直切片和非垂直切片的故事。而后,看看你是否能够改进这些故事。
为了方便咱们更好地指导团队,Richard建立了一个故事拆分流程图,该流程图介绍了咱们在帮助团队拆分故事时要问的问题。
(用户故事拆分流程缩略图)
让咱们分别看一下图中的三个步骤:
(准备待拆分的故事)
首先要确保你要拆分的故事/特性知足INVEST标准(短小的(Small)除外)。大多数状况下,有价值的(Valuable)是问题所在。当人们把他们认为是“不可拆分”的故事带给咱们时,它们实际上是假装成故事的开发任务或架构组件。若是你不从增长价值的角度入手,就没法将其拆分并得到价值增量。在这种状况下,下一步就是将非故事(non-story)与其余水平切片结合起来,这样,它们才能够共同表明一个价值增量。接下来,是否是切片太大了?若是是的话,就能够开始拆分了。
(套用拆分模式)
(按工做流程步骤拆分)
这是个人客户在建立一个内容管理系统的故事:
做为内容管理员,我能够将新闻发布到公司网站。
听起来故事并不大——直到咱们深刻研究了发布新闻的工做流程。结果发现,仅仅是把一个几句话的新闻发布到公司网站上,就须要编辑和法律部门的批准,以及在预发布网站上作发布前的最终审核。像这样的6-10个故事不可能在一次迭代中完成。
在这样的工做流程中,最大的价值每每来自于开头和结尾。中间的步骤会增长增量价值,但并不独立。因此先构建简单的端到端案例,而后再添加中间步骤和特殊案例,效果会很好。
新的故事包括:
…我能够将一篇新闻报道从预发布网站发布到正式网站。
但有时,整个工做流程都很重要,你不能只从开头和结尾开始。在这些状况下,寻找一个贯穿整个工做流的薄薄的切片。也许它支持最多见的状况;也许你能够硬编码或以其余方式简化工做流中最容易理解的部分,而后你才能探索更复杂的部分。
不管哪一种方式,最明显的拆分——从头至尾按功能模块一步一步执行——都是错误的方式。查看个人80/20产品全部权课程的这段摘录,了解更多关于为何这种拆分是错误的,以及如何使用其余两种方法。
(按不一样的业务规则拆分)
这个故事中隐藏着一些一样复杂的故事,这些故事使用不一样的业务规则来完成同一件事:
做为一个用户,我可使用灵活的日期规则搜索航班。
深刻研究“灵活的日期规则”,会发现有好几种不一样的业务规则,每一个规则均可以单独成为一个恰当的故事:
(按主要工做拆分)
有时,一个故事能够拆分为几个部分,其中大部分的精力会去实现第一个部分。例如这个信用卡支付的故事:
做为用户,我能够用VISA、MasterCard、Diners Club或American Express支付机票费用。
这个故事能够再拆分为四个故事,每种信用卡一个故事。可是,在处理第一个故事的时候就要创建起信用卡交易的基础架构;增长更多的信用卡类型时这方面的工做就会相对较小了。咱们能够估算第一个故事的规模大于其余三个故事,可是若是产品负责人后来改变了优先级,咱们就必须记得要改变咱们的估算。相反,咱们能够以下述所示,推迟决定哪一种卡的类型先被实现:
这两个新的故事仍然不是独立的,但依赖性会比为每一种信用卡类型编写一个故事要清晰得多。
(按简单/复杂拆分)
当你在计划会上讨论一个故事时,故事彷佛愈来愈大("X怎么办?"、"你考虑过Y吗?"),这时候你应该停下来,询问下你们:“最简单的版本是什么?”把这个简单的版本写成用户故事。你可能必须在现场定义一些验收标准以保持简单。而后,把全部的变化和复杂性拆分红其它的故事。好比这个故事:
做为用户,我能够搜索两个目的地之间的航班。
经过像下面的方式拆分变化来保持简单:
(按不一样类型的数据拆分)
故事中的复杂性可能来自于处理数据的变化。例如,我当前正在开发的系统须要对运输服务提供商所服务的地理区域进行建模。仅仅是处理复杂的服务区域的地理学知识,咱们就可能烧掉整个项目的预算。当我讲完这个故过后:
做为用户,我能够根据行程的始发地和目的地来搜索运输服务提供商。
与产品负责人讨论后发现,虽然咱们不须要成熟的GIS,但对地理环境进行建模仍然很是复杂。咱们停下来反思:“什么是‘足够好’的地理建模方案,以便咱们如今就能够构建其余高价值的功能?”咱们选择了:
做为用户,我能够按行程的始发地(市)和目的地(市)搜索运输服务提供商。
这在一段时间内是没问题的,直到咱们收集了更多的数据,发现有些服务提供商只服务于某些县城甚至乡镇。因而一个新的故事出现了:
做为用户,我能够按行程的始发地(如市、县、乡/镇、街道)和目的地(如市、县、乡/镇、街道)搜索运输服务提供商。
在查看新的服务提供商数据时,咱们还发现,有些服务提供商会支持出发地为单一城市,但终点为周边任意多个城市的行程。这就引出了下面这个故事:
服务提供商能够为行程的始发地和目的地提供不一样的地理区域。
这三个故事都是从原来的地理故事中拆分出来的。这里的区别是,咱们在构建最简单的版本后,及时添加了新的故事。但有些状况下,你在项目前期就能知道数据的变化。典型的例子是系统的本地化:
做为内容管理员,我能够用如下语言建立新闻:
英语
日语
阿拉伯语
等等……
(按不一样界面拆分)
有时,故事的复杂性在于用户界面而非功能。在这种状况下,故事的拆分要从最简单的UI开始,而后再构建更易用或更华丽的UI。固然,这些并非独立的——若是你先作第二个故事的话,第二个故事实际上就是初始故事——但它仍然能够是一种有用的故事拆分方式。
做为用户,我能够搜索两个目的地之间的航班。
...使用简单的日期输入。
...带有精美的日历界面。
(延迟性能优化)
有时,一个故事的基础功能实现可能并不难,可是须要花不少时间在性能的优化上。若是你能够从较差性能的基础功能中学到不少知识,而且它对用户有必定的价值(好比没有这个功能用户就没法完成故事中的动做),在这种状况下,你能够把故事拆分为“使其能用”和“使其好用”:
做为用户,我能够搜索两个目的地之间的航班。
...(只要功能完成就好,加载时显示一个“搜索中……”的动画。)
...(加载时间限制在5秒之内)。
(按不一样的业务规则拆分)
用户故事中的“管理”会涵盖故事的多个操做。这就为故事的拆分提供了一种天然的方式。好比说:
做为用户,我能够管理个人账户。
...我能够注册一个帐户。
...我能够编辑个人帐户设置。
...我能够注销个人帐户。
(拆分出一个探针)
一个故事之因此被你们认为工做量很大,可能并非由于它的业务有多复杂,也有多是由于开发团队对其技术实现不太了解。在这种状况下,不管你怎么澄清故事的业务部分,都没法将其拆分。先拆分一个有时间盒限制的探针故事,以便解决开发过程当中的不肯定性,而后咱们能够决定是直接实现,仍是使用上述的8种模式来拆分它。假如咱们不知道下面的故事如何实现:
做为用户,我能够用信用卡付款。
那么,就把它分解成:
在“调研”故事中,验收标准应该是你须要回答的问题。调研要点到为止,能回答问题便可,作调研很容易走火入魔。
探针拆分模式放在最后讲解,是由于它应该是你最后的选择。你目前已知的知识可能已经能够用来构建一些功能了,按照你已知的知识直接开始开发吧,随着项目的推动,这些问题颇有可能会不攻自破。所以,在求助于探针模式以前,请尽一切努力使用前面八个模式之一。
在咱们指导团队更有效地拆分故事的过程当中,咱们发现了这些模式共有的元模式:关注复杂性,并经过它减小变化。使用元模式的方法以下:
大多数故事拆分模式只是肯定变化的来源并将其减小到一个的例子。
这种方法对于一个新事物的第一个切片特别好用,由于它直奔核心复杂性,并避免了任何可能会让工做变得更大的内容。
(评估拆分效果)
你可能会发现,有时你可使用好几种模式来拆分同一个故事。那咱们应该选择哪一种拆分方式呢?我通常经过如下两个经验法则来判断:
选择能让你下降优先级或扔掉一个故事的拆分方式。80/20法则代表,用户故事的大部分价值来自于一小部分功能。当一种拆分方式揭示了低价值的功能,而另外一种拆分方式没有揭示,这说明后一个拆分方式在每一个小故事里面都隐藏着浪费。选择能让你扔掉低价值功能的拆分方式。
选择能让你获得更多同等大小的小故事的拆分方式。把一个8点的故事变成四个2点的故事的拆分方式比产生一个5点和一个3点的拆分方式更有用,由于它能让产品负责人有更多的自由来分别对这些拆分后的故事进行优先级排序。
可能须要屡次尝试才能找到最适合你的故事拆分模式——你可能须要不断地试验才能找到正确的模式。
(Cynefin)
Dave Snowden的Cynefin模型是一种根据问题的复杂程度来思考问题最优策略的有用方法。咱们发现Cynefin很是有用,几乎全部的工做坊都使用了它,有的是做为先决条件,有的是做为工做坊自己。若是你还不熟悉这个模型,请查看咱们的概述。
Cynefin每一个领域的故事拆分看起来都不同。下面是具体拆分方法:
最重要的细微差异在复杂域(complex domain),从这里开始工做会让你快速了解工做的内容。在这种状况下,试图找到构成原始大故事的全部小故事是没有意义的。找到一两个能够当即开始学习的故事会更有效率。
有些人不喜欢这种方法,他但愿把全部的故事都列举出来,并肯定大小,以便可以把故事记录到Backlog并估算时间。但若是你真的是处于复杂域(complex domain),这样作只会给你带来可预测性的错觉——实际的故事极可能会随着工做的推动而发生变化。最好对复杂工做中固有的不肯定性保持透明。
就像咱们以前说过的那样,在较薄的垂直切片中工做是敏捷软件开发的关键习惯。不少人都在努力寻找垂直切片,但其实这是一项很是容易习得的技能。团队只需2.5-3个小时的练习,就能够从苦苦挣扎到快速地识别出其领域中的特性和大故事的切片。固然,练习的质量很重要。下面是我推荐的作法:
当你有100+人在同一个产品上工做时,可使用垂直切片吗?
当你有多个敏捷团队开发同一个产品时,能够采用这两种组织方式:特性团队(feature team)或组件团队(component team)。
特性团队的组织方式是,每一个团队都有足够多的跨功能成员,以即可以在部分或所有产品上提供完整的价值切片(即“垂直切片”)。根据产品的规模,特性团队可能会专一于产品的某些部分,有效地建立子产品,或者他们可能会完成整个产品中最重要的部分。
组件团队的组织方式是,每一个团队专一于一个特定的组件、架构层次或技术方向。要想交付一个完整的价值片断,须要协调多个团队的工做。
让咱们看一个大型商业软件的具体例子:淘宝。(注:我不知道淘宝的实际组织方式或技术是什么样的,可是这并不重要,我只是须要一个你们都熟悉的软件产品来进行推理)。
淘宝有一个APP。它经过某种通信协议与某种语言编写的后端进行通信。后端有一些流程处理的程序,好比搜索商品、生成订单、支付订单以及跟踪物流信息等。
若是采用组件团队结构,你会有APP团队,例如,他们能够对APP界面进行修改,但他们极可能依赖于后端团队对其系统部分进行相应的修改。各个团队之间的协调将集中在确保他们的工做同步推动,以最终可以提供价值。
在特性团队的结构下,你可能会有一个团队或一组团队负责商品的搜索模块,另外一个负责订单模块,第三个负责支付模块等。这些团队中的每个都拥有APP和后端技能。在这种状况下,各团队之间的协调将集中于确保整个产品的设计和架构一致。
相同的产品,团队以两种不一样的组织方式,将获得两套不一样的结果和协调方案。
因此,有关“垂直切片是否与规模相关”这个问题,答案取决于你的组织方式。组件团队是不以垂直切片的方式工做的。但组件团队能够围绕更大的垂直切片(如MMF)协调工做,但在具体的工做项层面,组件团队没法完成垂直切片所需的所有功能。构建组件团队没法独立交付价值,但这种组织方式能够针对其余方面进行优化(一般是更容易进行架构调整或更高的研发人员利用率)。
特性团队与组建团队的收益恰好相反。他们旨在独立提供垂直切片,以便更快速的交付价值、获取反馈,代价是须要明确地协调架构一致性。
特性团队与组件团队是2种主要的组织方法。固然,有些组织可能有细微的差异或混合,而且会随着时间的推移而变化。我之前写过这方面的文章,特别是在改造一个拥有大型遗留产品的组织的状况下。
如今,咱们心中还有一个更重要的问题,那就是:无论咱们是否能够在大型产品/项目中使用垂直切片(正如咱们所展现的那样,若是咱们以特性团队来组织,咱们是能够的),这么多人蜂拥而上,是否真的有效?
为单个产品/项目添加人员或团队,都会带来一些生产力和协调的开销:项目若是只有一我的,那么这我的的生产力几乎是100%;再增长一我的的话,咱们不会获得2倍的生产力,可能只会获得1.8倍的生产力(平均每一个人提供90%的生产力),由于这两我的须要花时间用来进行工做的协调(每一个人消耗10%的生产力用于协调);增长到3我的的时候,生产力会获得再次提高,此次有可能会提升到2.4倍(平均每一个人提供80%的生产力),相应的,协调的开销也会随着上升(每一个人消耗20%的生产力用于协调)。并且,这种协调的开销会随着人与人之间联系的数量呈指数增加。
经过组建小规模团队,使每一个人只须要与少数人协调工做细节,并尝试在团队之间进行分工,尽可能减小依赖性,从而能在必定程度上减小协调的开销。但工做越复杂,依赖关系就越难以预测,团队之间须要协调的可能性就越大。
所以,在某些时候,在项目/产品中再增长一我的或一个团队,不只不能提高生产力,还会给整个系统带来协调开销的增长,最终致使总体生产力的降低。
(团队规模、价值增长和协调开销之间的关系)
团队规模的临界点到底落在哪里,在很大程度上取决于项目/产品的具体状况。但抛物线的形状至少应该让咱们对大型团队产生怀疑,并慎重考虑人员或团队的增长。
对于复杂的工做来讲尤为如此,由于极可能须要咱们在一个项目/产品上工做一段时间后才能了解真正的问题和解决方案。而在软件开发过程当中,复杂性彷佛与价值高度相关。越是高价值的特性,项目/产品前期越可能发现不了。若是是一个新项目/产品,咱们在工做中颇有可能会学到一些新知识,从而改善咱们交付的价值。
是的,你能够在每一个细节层面和各类规模的工做上进行垂直切片,这样作颇有价值。但在大规模的交付中,你须要特殊定的方式进行组织:以特性团队的方式,或者以某种强调功能交付的混合方式。并且,当你使用它时,须要考虑一下,你的需求是否真的须要如此大的规模。
来源:小船哥说敏捷
做者:adoudou
声明:文章得到做者受权在IDCF社区公众号(devopshub)转发。优质内容共享给思否平台的技术同伴,如原做者有其余考虑请联系小编删除,致谢。
5月每周四晚8点,【冬哥有话说】质量与测试专场。公众号留言“质量”可获取地址