一件用户通过系统完成他一个有价值的目标(买一罐饮料)的事。这样的过程就叫“用户案例(user case)”或者“用户故事(user story)”。本文描述了敏捷开发的技巧:如何以用户故事管理项目.
敏捷开发技巧:以用户故事管理项目
Wingel 发表于 2007-02-12 08:08:13
作者:Wingel 来源:Wingel' blog
摘自:Matrix
什么是用户故事(user story)
假定这个项目的客户是个饮料自动售货机的制造商。他们要求我们为他们的售货机开发一款软件。我们可以找他们的市场经理了解这个软件的需求。
因此,我们的客户就是他们的市场经理。谈需求的时候,有一回他这样说:“用户往售货机每塞一个硬币,售货机都要显示当前该客户已经投了多少钱。当用户投的钱够买某一款饮料时,代表这款饮料的按钮的灯就会亮。如果那个用户按了这个按钮,售货机就放一罐饮料到出口,然后找零钱给他。”
上面的话描述的是一件事情,一件用户通过系统完成他一个有价值的目标(买一罐饮料)的事。这样的过程就叫“用户案例(user case)”或者“用户故事(user story)”。也就是说,上面我们的客户所说的话,就是在描述一个用户故事(user story)。
(我解释一下为什么用故事这个词,没兴趣也可以忽略。在一个系统面前,每个用户要完成同样的目标,都要做这个系统设定的例行的事,这件事情不是一个例子,所以不叫事例,这也不是故事,也不能算一段历程,而是一个例行的事。)
如果我们想要记下这段用户故事,我们可能会用这样的格式:
名称:卖饮料
事件:
1. 用户投入一些钱。
2. 售货机显示用户已经投了多少钱。
3. 如果投入的钱足够买某种饮料,这种饮料对应的按钮的灯就会亮。
4. 用户按了某个亮了的按钮。
5. 售货机卖出一罐饮料给他。
6. 售货机找零钱给他。
注意到,一个用户故事里面的事件可以这样描述:
1. 用户做XX。
2. 系统做YY。
3. 用户做ZZ。
4. 系统做TT。
5. ...
用户故事只是描述系统的外在行为
一个用户故事只是以客户能够明白的方式,描述了一个系统的外在行为,它完全忽略了系统的内部动作。比如,下面有下划线的那些文字,就属于不应该出现在用户故事中的系统内部动作:
1. 用户投入一些钱。
2. 售货机将塞进来的钱存在钱箱里,然后发送一条命令给屏幕,屏幕显示目前已经投入的金额。
3. 售货机查询数据库里面所有饮料的价格,判定钱足够买哪些饮料,对于钱足够买的那些饮料,对应的按钮的灯就会亮起来。
4. 用户按下一个亮起来的按钮。
5. 售货机卖出一罐饮料给用户,然后将数据库里面该饮料的存货数量减1。
6. 售货机找零钱给用户。
不管是口头描述的,还是书面形式,这样的内容是描述用户故事时一个很常见的错误。特别的,千万不要提及任何有关数据库,记录,字段之类的对客户一点意义都没有的东西。
评估发布时间
用户故事是用来干嘛的?假定客户希望在50天内递交这个系统。我们做得了吗?为了解答这个问题,我们就要在项目开始的阶段,试着找出所有的用户故事,然后评估一下,每一项历程需要多长的开发时间。可是,怎么评估呢?
比如,我们现在收集了下面这些用户故事:
卖饮料:如上面所说的。
取消购买:在投入了一些钱后,用户可以取消购买。
输入管理密码:授权的人可以输入管理密码,然后增加存货,设定价格,拿走里面的钱等等。
补充饮料:授权的人可以在输入管理密码后增加存货。
取出钱箱里的钱:授权的人在输入管理密码后,可以取出钱箱里的钱箱里面的钱。
安全警报:有些事情经常发生的话,系统会自动打开安全警报。
打印月销售报表:授权的人可以打印出月销售报表。
然后找出里面最简单的用户故事(这里的“简单”,意思是说实现周期最短)。我们不一定非常精准的判断哪个最简单。只要挑出你觉得最简单的就行了。比如,我们觉得“输入管理密码”是最简单的用户故事。然后我们判断说,这个用户故事算1个“故事点(story point)”。
用户故事 故事点
卖饮料
取消购买
输入管理密码 1
补充饮料
取出钱箱里的钱
安全警报
打印月销售报表
不过一般我们不会列出清单,而是做出一堆卡片贴在墙上,每张卡片记录一个用户故事,然后将故事点写在卡片上面:
(见附件1)
这样的一张卡片就叫“故事卡(story card)”。
然后开始考虑其他用户故事。比如,对于“取出钱箱里的钱”这个故事,我们认为它跟“输入管理密码”这个故事一样简单,所以它应该也是算1个故事点。我们在列表里面标上。当然,实际操作的时候,我们是在“取出钱箱里的钱”的故事卡上填上故事点。
用户故事 故事点
卖饮料
取消购买
输入管理密码 1
补充饮料
取出钱箱里的钱 1
安全警报
打印月销售报表
对于“取消购买”,我们认为它应该是“取出钱箱里的钱”的两倍的工作量,所以它算2个故事点。
用户故事 故事点
卖饮料
取消购买 2
输入管理密码 1
补充饮料
取出钱箱里的钱 1
安全警报
打印月销售报表
对于“卖饮料”,我们认为它应该是“取消购买”两倍的复杂度,所以它应该算4个故事点。
用户故事 故事点
卖饮料 4
取消购买 2
输入管理密码 1
补充饮料
取出钱箱里的钱 1
安全警报
打印月销售报表
对于“补充饮料”,我们又认为它比“取出钱箱里的钱”复杂,但又比“卖饮料”简单,然后它又应该比“取消购买(2个故事点)”复杂,所以我们认为它应该是3个故事点:
用户故事 故事点
卖饮料 4
取消购买 2
输入管理密码 1
补充饮料 3
取出钱箱里的钱 1
安全警报
打印月销售报表
类似的,我们认为“安全警报”应该比“补充饮料”简单一些,所以应该是2个故事点:
用户故事 故事点
卖饮料 4
取消购买 2
输入管理密码 1
补充饮料 3
取出钱箱里的钱 1
安全警报 2
打印月销售报表
“打印月销售报表”应该跟“卖饮料”一样复杂,所以应该是算4个故事点,这样的话,我们总共有17个故事点:
用户故事 故事点
卖饮料 4
取消购买 2
输入管理密码 1
补充饮料 3
取出钱箱里的钱 1
安全警报 2
打印月销售报表 4
总计 17
现在挑出任意一个用户故事,估计一下它要花(你一个人)多少时间来完成。假设我们之前做过跟“取出钱箱里的钱”类似的功能,所以我们就挑这个来计算,估计它要花5天的时间。也就是说,一个故事点要花5天的时间来完成。现在我们有17个故事点,也就是说,我们需要17×5=85天来完成这个项目(如果只是一个开发人员来做的话)。假设现在我们的团队里面有两个开发人员,所以我们就需要85÷2=43天来完成。
从目前的估计来看,我们可以在50天的期限里面做完这个项目。但现在说这个还太早了!这样的评估,更多的是猜测。通常开发人员在工作量上的估算都很差。事实上,人们经常会低估了工作量。那我们应该怎么估计得更准?
我们实际的开发速度是多少
为了做到更准的估计,我们就让客户先给我们两周的时间做一些实际的开发,来测量一下我们在这两周里面可以做多少的用户故事。我们叫这两周的时间为“迭代周期”。
哪些用户故事应该放在第一个迭代周期里面做?这可能完全是客户决定的,也可能是大家讨论以后决定的。不过挑出的这些用户故事的故事点不应该超过这两周的承受能力。因为一个迭代周期有10天(假设我们周末不工作),然后我们估计一个开发人员5天可以完成一个故事点。现在我们有两个开发人员,所以我们应该可以在这个迭代周期中完成(10÷5)×2=4个故事点。
然后客户可以在总故事点不超过4的前提下,挑出一些用户故事在这个迭代周期里实现。他们可能会尽量挑选他们觉得最重要的故事。比如,对他们来说,销售报表跟找零钱最重要,所以他们就挑出这两个:
用户故事 故事点
取出钱箱里的钱 1
打印月销售报表 2
总计 3
假设两周的迭代周期过去了,我们完成了“取出钱箱里的钱”,不过“打印月销售报表”没有完成,还剩0.5个故事点没有完成。也就是说,我们在这个迭代周期内完成了3-0.5=2.5个故事点(比原来的预计要差一些)。
2.5个故事点这样的数值,就是我们现在的参考值。也就是说,这个团队每个迭代周期可以完成2.5个故事点。这个参考值对我们很有用。它有两个用处:
首先,我们可以假定我们在下个迭代周期也可以完成2.5个故事点,然后客户选择的用户故事的故事点总和不能超过2.5。
其次,在从第一个迭代周期取得参考值以后,我们可以重新估算我们的发布时间了。本来我们估算我们每个开发人员完成1个故事点的时间是5天,现在我们有了实践后的数据了,我们的团队(两个开发人员)可以在一个迭代周期(10天)内完成2.5个故事点。现在总的故事点是17,计算一下,我们需要17÷2.5= 7个迭代周期来完成。14周,也就是70天。也就是说,我们满足不了客户提出的期限(50天内)!怎么办?
预计不能如期完成时怎么办?
很明显,现在我们完成不了全部的用户故事。在这50天里面,我们只能完成50÷10×2.5=12.5个用户故事。因为现在有17个故事点,我们应该让客户挑出总计4.5个故事点的用户故事,推迟到下一个发布周期去。客户应该选择那些比较次要的用户故事。比如,客户可以推迟“打印月销售报表”这个用户故事。
(这只是开发不能如期完成时的解决方法之一,这种方法应该是在客户比较有诚意合作的前提下使用。)
用户故事 故事点
卖饮料 4
取消购买 2
输入管理密码 1
补充饮料 3
取出钱箱里的钱 1
安全警报 2
总计 13
然后他还要挑出总和至少为0.5个故事点的故事。
但是如果“月销售报表”这个用户故事对客户来说也是非常重要,而且其他的故事也不能推迟,这时怎么办?这时我们就要试着简化这些用户故事。比如,原来“月销售报表”是要用一个第三方报表库来实现的,而且还要画出饼状统计图,如果我们只是生成简单的文本格式的报表的话(这格式应该可以被Excel导入,以便日后的处理)。那么这个用户故事的故事点就会从4减少到2,节省了2个故事点。如果客户同意的话,我们就可以将“打印月销售报表”分成两个用户故事“生成月销售文本报表”和“生成图形报表”,然后将后者推迟到下一个发布。
现在新的故事卡片出来了:
用户故事 故事点
卖饮料 4
取消购买 2
输入管理密码 1
补充饮料 3
取出钱箱里的钱 1
安全警报 2
打印月销售文本报表 2
总计 15
还有其他的2.5个故事点要推迟,我们可以简化“卖饮料”。假设本来我们可以卖不同价格不同类别的饮料。如果现在我们只是简单支持一种价格一种类别的饮料的话,那这个用户故事的故事点可以从4减到2了。客户如果同意的话,我们就可以将“卖饮料”分割为“卖单一饮料”和“卖多种饮料”,然后将后者推迟到下个周期发布:
用户故事 故事点
卖单一饮料 2
取消购买 2
输入管理密码 1
补充饮料 3
取出钱箱里的钱 1
安全警报 2
打印月销售文本报表 2
总计 13
现在还剩0.5个故事点,我们再考虑一下“安全警报”。假设本来这个故事是要同时触发本机上的警报,跟通知附近的一个警察局的。如果现在我们只是触发本机的警报,那所花的故事点就可以从2减到1了。于是在客户同意的情况下,我们将“安全警报”分割为“本机安全警报”和“通知警察”,然后将后者推迟到下个发布:
用户故事 故事点
卖单一饮料 2
取消购买 2
输入管理密码 1
补充饮料 3
取出钱箱里的钱 1
本机安全警报 1
打印月销售文本报表 2
总计 12
现在我们总计有12个故事点要做了(<=12.5)。上面这个筛选在本次发布的用户故事的过程,叫“发布计划编制”。
增加开发人员来满足发布期限
在上面的例子中,我们以推迟部分用户故事到下个发布周期的办法来解决问题。这种“控制开发范围”通常是最好的解决办法。不过,这种解决办法实施不了的情况下,那你就只好保留所有的用户故事,然后增加更多的开发人员了。在这个例子中,假定我们需要“n”个开发人员,才能在50天内完成17个故事点。50÷ 10×2.5×n÷2.算出来,n=2.7,我们需要3个开发人员,也就是多加一个开发人员进来。不过注意:
团队人数加倍并不等于开发周期的减半。它可能只会缩短1/3。如果团队超过10个人的话,增加更多的人员可能反而会延缓项目的进度。
而且项目开发周期越长,团队内的成员对整个项目代码的熟悉度就越少,加上不确定的人员流动,新来人员的业务不熟等其他可能性,这项目会越来越复杂。
总的意思就是,项目人数不能太多,周期不能太长。
根据参考值来掌控项目
每个迭代周期2.5个故事点的这个参考值,只是第一个迭代周期的数据,第二个迭代周期可能会变成2或者3(一般是不会变动得太大)。假设是2的情况下,那对于第三个迭代周期,我们就要将参考值设为2,然后让客户以2为故事点总数来挑选用户故事。
对于大多数项目,参考值很快就会稳定下来(比如在几个迭代周期后)。当这个值稳定下来后,我们就要重新估计开发周期,重新进行“发布计划编制”了。如果这个参考值告诉我们,我们每个迭代周期可以做3个故事点的话,我们就要让客户挑选更多的用户故事放在这次的发布计划中。相反如果这个参考值是2的话,我们就要让客户减少用户故事(需要的话可以分割一些用户故事),如果团队人员还不多的话,可以增加更多的开发人员。
这是项目的初始阶段绝对要注意的。
发布计划编制,估算每个用户故事时要考虑哪些细节,忽略哪些细节?
在项目初始,我们要找出这个发布周期内所有主要的用户故事,评估每个故事的故事点。可是要怎么评估里面的细节呢?比如对于“卖饮料”, “卖饮料”这个简单的标题,省略了很多的细节:用户会投入什么样的钱?纸币可以吗?人民币可以吗?按钮的灯的亮度要多少?可不可以多个按钮对应一种饮料?按钮被按下以后,要不要变暗?找零钱是不是全部找10分的面额?
我们是不是要考虑上面所有的细节?对于按钮灯的亮度,我们就不用考虑了,它对我们的工作量没影响。不过,零钱的面额就对我们的工作量很有影响,我们要认真考虑一下(找一堆10分的零钱就很容易实现;如果要尽量减少零钱的个数就比较麻烦了)。处理不同币种也要考虑。
一般情况,我们不用太担心会漏过什么细节。对于每个用户故事,只要考虑一些“重要”问题就行了。当然,这里面的“重要”,就要根据经验以及客户的观点来决定了。
如果我们不好估算的话怎么做
如果我们觉得,这个用户故事不好估算,那可能的原因就是:
1. 这个用户故事太大。这种情况我们就可以将这个用户故事分割出若干个新的用户故事,比如:
将“卖饮料”分割出:
1:显示总投入金额。
2:金额够买的饮料对应的按钮灯亮起来。
3:按下亮灯的按钮,可以买到对应的饮料。
2. 我们之前从没开发过自动售货机的程序。因此,我们不知道开发这样的程序有多复杂。这样的话,我们就要做一些实验了,比如做一个让售货机找钱的小程序。这种试验就叫“spike”(翻译不出来)。
迭代周期内的计划编制
对于这个迭代周期内选择的所有用户故事,不像在发布计划编制那样,只是考虑一些重要的细节,现在我们要从客户那里调查到所有的细节。比如对于“卖饮料”,我们可能会在白板上画出用户交互的草图,然后跟客户一起讨论:
这是一台自动售货机……
用户投入硬币……
假设他投入的是50分,而价格是40分,那么按钮就会亮起(别忘了我们现在做的只卖单一饮料)
用户按一个亮起的按钮,一罐饮料会掉到售货机的出口
找零钱……
在跟客户详细讨论完,了解了足够的细节以后,我们才发现,事实上这个用户故事“卖饮料(只卖单一的)”的故事点远远比我们预计的要麻烦,这时候应该类似前面的发布计划编制那样,1、分割出小的用户故事,挑出一些放在下一个迭代周期内;或者2、挑出这个迭代周期内的一些用户故事放在下一个迭代周期。反之,如果发现这个用户故事比我们想像的还要简单,那我们就要增加更多的用户故事到这个迭代周期内。
用户故事只是跟用户交流的开始,而不是全部
假想现在已经从客户那边得到足够详细的需求了,我们可以开始实现了。注意,我们不用把所有用户提供的细节都记录下来。为什么呢?假设以后,你有点忘记用户故事,而客户又在你旁边,你是直接问客户,还是去找看需求文档找到你要的东西?当然是直接问客户了。客户可以提示更准确,更完整的需求给你。特别要注意的是,以后只要你一完成一个用户故事,你就要让客户看一下,或者实际的操作一下,因为客户对已经做的的东西了解得越多,那他就可以提供越准确越完整的需求。
用户挑选完用户故事以后,在之后的两个星期内,我们就要将这些用户故事逐个完成。每个用户故事我们都会设计结构,编码,测试等等。每做完一个用户故事,我们都要让客户验证一下系统是不是他所想的那样。
在这两个星期内,如果我们提早完成了用户故事,我们就要让客户挑更多的用户故事。相反的,如果我们不能及时完成,我们就要让客户知道当前的进度。
总结
我觉得这章的内容跟其他的软件工程书一样,看看,参考参考,具体的情况还是要具体的分析,不过这里面的用户故事(user story)跟故事卡片的概念就很不错,可以引用。
- 大小: 8.1 KB
分享到:
相关推荐
《敏捷软件开发:原则、模式与实践》是一本深度探讨敏捷...通过阅读《敏捷软件开发:原则、模式与实践》,读者不仅可以理解敏捷开发的理念,还能掌握实施敏捷的具体策略和工具,提升项目管理与软件开发的效率和质量。
敏捷开发回顾:使团队更强大敏捷开发回顾:使团队更强大
书中深入探讨了软件开发人员、项目经理以及软件项目领导在面临预算和时间限制时应如何采用敏捷开发方式来完成项目。作者通过真实案例详细讲解了如何运用极限编程技术进行设计、测试、重构及结对编程,并提供了大量可...
本书《轻松Scrum之旅:敏捷开发故事》就是基于敏捷开发思想的实践经验,讲述了一个外企的一个新团队如何从零开始实施敏捷,经历挫折、失败、进步、成长,直到项目成功结束的故事。本书的创作完全是由 4 位作者共同...
Martin(也被业界称为Uncle Bob)的经典著作,这本书深入探讨了敏捷开发的核心理念,并通过实际案例介绍了如何在项目中运用这些原则、模式和最佳实践。这本书分为两部分,第一部分阐述了敏捷开发的基本原则和价值观...
3. **实践技巧**:书中涵盖了测试驱动开发(TDD)、重构、结对编程等敏捷实践,这些技巧有助于确保代码质量,减少缺陷,并促进团队协作。 4. **源码示例**:附带的源码文件,可能是为了便于读者理解和应用书中的...
敏捷软件开发:原则、模式与实践(高清PDF)
敏捷软件开发:原则、模式与实践(全) 敏捷软件开发:原则、模式与实践(全) 敏捷软件开发:原则、模式与实践(全) 敏捷软件开发:原则、模式与实践(全) 敏捷软件开发:原则、模式与实践(全)
敏捷软件开发:原则、模式与实践.pdf 敏捷软件开发:原则、模式与实践.pdf 敏捷软件开发:原则、模式与实践.pdf
敏捷软件开发:原则、模式与设计.pdf敏捷软件开发:原则、模式与设计.pdf
它不仅是高校计算机专业本科生、研究生和软件学院的软件工程相关课程的优秀教材或参考书,同时也适合软件开发和管理人员用以提高自身技能的学习材料。 作者Robert C. Martin(通常称为“Uncle Bob”),是软件开发...
敏捷软件开发是一种注重快速反应和持续交付价值的软件开发方法论。这种方法论强调人、软件、合作和灵活性比过程和工具更为重要。敏捷开发的流行得益于其适应性和高效性,尤其在需求频繁变更、市场竞争激烈和技术快速...
“Agile Project Management.pdf”这篇文章很可能涵盖了以上所述的多个方面,详细阐述了如何在实践中应用敏捷开发原则和技巧进行项目管理。通过深入阅读和学习,无论是项目经理还是开发人员,都能获得提升项目成功率...
《敏捷软件开发:原则模式与实践》是由著名软件开发专家、软件工程大师Robert C. Martin(别名Uncle Bob)所著的指导书籍,旨在为软件开发人员、项目经理以及软件项目领导提供解决实际问题的方法和策略。本书将敏捷...
在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征。简言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于...
软件工程经典书籍之——敏捷软件开发:原则、模式与实践
3. **模式与实践**:作者介绍了多种敏捷实践,如每日站立会议、用户故事、持续集成、测试驱动开发(TDD)和重构。这些实践帮助团队有效地协作,提高代码质量,并确保软件始终保持可用状态。 4. **Scrum框架**:作为...
4. 用户故事与计划游戏:敏捷开发中的用户故事是从用户角度描述需求的一种方式,它们是产品待办事项列表的基本单元。计划游戏中,团队成员一起估算用户故事的工作量,制定迭代计划。 5. 持续集成:为了保持代码的...