使用哪种模式好呢?
经常你会发现,你可以使用几种模式拆分一个故事。你应该选择哪种拆分模式呢?我有两条经验:
1. 选择可以让你分辨出优先级高低甚至可以直接丢弃故事的拆分模式。80 / 20定律表明大部分有价值的用户故事来自于一小部分功能。一种拆分模式揭示了低价值的功能时,而另一个没有,这表明,后面这种拆分方式隐藏了在每一个小故事里的浪费。使用可以让你丢弃的低价值的东西的拆分模式。
2. 选择可让你把大故事拆分成多个差不多大小的小故事的模式。把一个8个故事点的的故事拆分成4个2个故事点模式比把8个故事点的故事拆分成5个故事点和3个故事点的模式更好。这让PO能轻松的逐个考虑部分功能的优先级。
模式#1:工作流步骤
这是我一个客户创建的内容管理系统的用户故事。
作为内容管理员,我可以在企业网站上发布新闻故事。
这听起来不太大——直到我们深入了解发布一个新闻的工作流程。原来只是为了在公司网站上发布几句话的新闻,都需要通过编辑审核以及法律审核,并且还需要在测试站点上做最终评审。没有办法在一个迭代里用6-10个故事完成所有这些事。
在这样的一个工作流中,最大的价值往往来自于开始和结束。中间步骤可以增值,但不要独立。因此它适用于构建简单的端到端的案例,然后添加中间步骤和特殊情况。
新故事包括:
我可以直接在企业网站发布新闻故事。
我可以发布经过编辑评审的新闻故事。
我可以发布经过法律评审的新闻报道。
我可以查看测试站点上的新闻故事。
…我可以将测试站点的新闻报道发布到产品站点。
模式# 2:业务规则变化
这个故事有一些隐藏在它里面的几个同样复杂的故事,用不同的业务规则来完成同样的事情:
作为用户,我可以搜索灵活的日期航班
深入挖掘“灵活的日期”揭示了几个不同的业务规则,每个里面都包含一个好故事
…像“在x和y之间的n天。”
…像“在12月的一个周末。”
…像“在x和y之间的n天前后。”
模式#3:主要工作
有时一个故事可以分为几个部分,大部分的工作将用于实现第一个。例如,这张信用卡处理的故事:
作为一个用户,我可以用VISA,MasterCard,Diners Club or American Express等支付航班费用。
可以分成四个故事,每个卡型作为一个故事。但信用卡处理基础设施将建立在支持第一个故事的基础上,增加更多的卡型是相对有些繁琐。我们可以估计第一个故事比其他三个故事更大,如果PO以后改变优先级,我们必须记得要改变我们的估算。相反,我们应该推迟关于哪种卡型得到最先执行的决定,像这样:
…我可以用一种信用卡类型支付(VISA,MC,DC,AMEX)。
…我可以用四种信用卡类型支付 (VISA,MC,DC,AMEX)(给定一个卡型已经实现)。
这两个新的故事仍然不是独立的,但要比为每个卡型写一个故事依赖关系更清晰。
模式#4:简单/复杂
当你在计划会议上讨论一个故事的时候,会让这个故事变得越来越大(“x怎么样呢?”;“你考虑y 情况了么?”)停下来,然后问这样一个问题,“最简单的版本是什么?”捕获简单版本作为故事。当然你可能要立刻定义一些验收标准使之保持简单。然后,打破所有的变化和复杂的故事。例如,这个故事:
作为一个用户,我可以搜索两个目的地之间的航班。
拆分不多样性使之保持简单,如,
……指定一个经停的最大数目。
……包括附近的机场。
……使用灵活的日期。
……等等)
模式#5:数据的变化
一个故事中的复杂性可能来自处理数据的变化。例如,我目前正在工作的一个系统需要模拟运输供应商服务的地理区域。在处理地理问题的时候我们可能会把整个项目的预算都燃尽了,这可能很复杂。当我和PO讨论这个故事的时候,
作为用户,我可以通过旅行的出发地和目的地寻找交通运输商。
我发现,虽然我们不需要成熟的GIS,但地理建模仍然是相当复杂的。我们停下来,问:有“足够好”的方式来模拟地理位置以至于现在我们可以建立其他高价值的功能吗?“我们决定,
作为一个用户,我可以以县为范围按照旅行的出发地和目的地寻找交通运输商。
工作了一段时间后,直到我们收集到更多的数据发现一些供应商只提供某些城市或只是社区服务。于是一个新的故事出现了:
作为一个用户,我可以以县,城市,镇或者社区为范围通过旅行的出发地和目的地搜索运输提供商。
看了新的供应商数据,我们也发现一些供应商支持从单个城市出发但可以到达任意数量的周边城市。这就产生了新故事:
供应商可以提供不同的地理区域为出发地和目的地的旅行。
所有这三个故事都是从原始的地理故事中细化的。这里的区别是,我们在建立最简单的版本后,增加了故事。但有时你提前知道数据变化。经典的例子是本地化:
作为内容管理负责人,我可以创建新闻故事。
……用英语。
……用日本。
用阿拉伯语。
……等等
模式#6:数据输入法
复杂性有时是在用户界面,而不是在功能本身。在这种情况下,拆分故事以尽可能简单的UI来构建它,然后建立更多有用的或华丽的UI。当然,这些并不是独立的故事——如果你首先做第二个故事,那么第二个故事实际上是原始的故事——但它仍然可以是一个有用的细化故事。
作为一个用户,我可以搜索两个目的地之间的航班。
使用简单的日期输入…。
…用漂亮的日历界面。
模式#7:延迟性能
有时,大部分的努力是为了让功能工作的更快——初步实施并不是都那么困难。但是你可以从慢速执行中学习到很多东西,而且它对一个不能够在故事中做出行动的用户有一定的价值。在这种情况下,把故事分成“能够工作”和“能够快速工作”:
作为一个用户,我可以搜索两个目的地之间的航班。
…(慢——仅仅完成功能,显示“搜索”动画画面)。
…(在5秒内)。
模式#8:操作(例如:CRUD)
“管理”这个词在用户故事中是一种暗示,表明这个故事涵盖了多个操作的。这提供了一个自然的方式细化故事。例如:
作为一个用户,我可以管理我的帐户。
…我可以注册一个帐户。
…我可以编辑我的帐户设置。
…我可以取消我的帐户。
模式#9:拆分出一个探针
一个故事可能比较大不一定因为它是复杂的而是由于对实施知之甚少。在这种情况下,再多的对这个故事业务部分的讨论也不能让你了解如何拆分它。在一定时间内针对怎么实施先做个探针试验。然后,你可以执行或有一个更好的指导如何拆分它。不知道如何实现下面的故事吗?
作为用户,我可以用信用卡支付。
然后,把它分成:
调查信用卡数据处理。
实施信用卡处理。
在“调查”的故事中,验收标准应该是你需要回答的问题。做刚好能回答问题的调查即可;做研究时很容易过于投入而花费太多时间。
探针模式放在最后因为它应该是你的最后手段。你可能知道可以去构建了。去做吧,你就会知道更多。所以,在采取探针模式之前尽一切努力去使用前八种模式。
结论
抵制通过架构层拆分庞大的用户故事诱惑。相反,尝试这些模式将你的故事分割成更小的故事并且仍然满足INVEST模式。请务必让我知道这些模式是如何为你工作的,或者你已经遇到不可拆分的故事了(我喜欢挑战!)。