持续交付2.0

用户故事的5个常见错误

Image

  • 什么是用户故事?

  • 人们经常犯的关于用户故事的错误有哪些?

  • 我们如何写出更好的用户故事,并避免这些常见的错误?

  • 需求(Requirement)与用户故事需求,是相同的吗?

  • 用户故事与需求是同一个东西吗?

  • ......

构建软件实际上只有三个步骤:先有一个想要解决的问题并且有一些想法或解决思路、然后构建软件来解决问题、最后检查软件是否做到了我们想要的。用户故事专注于第一步,但如果我们这一步做对了,它会让后面两步变得容易得多。

本文将探讨用户故事的5个常见错误,这些错误会令软件开发和持续交付变得更加困难。在探讨这些错误的同时,我也会描述更好、更有用的用户故事的特性,以及它们之所以更好的原因。

如果想要构建软件系统,我们需要知道“我们希望它能做什么”,但对于某些类型的系统,我们经常会混淆“我们希望它做什么”,以及“它到底做了什么”,用户也可能看起来离它们很远。

那么,什么是用户故事?好的和坏的用户故事之间的区别是什么?本文将介绍我看到的人们在使用用户故事时经常犯的5个错误。

Image

在我看来,软件开发基本上是关于三件事:

1、知道我们要解决的问题;

2、编写解决问题的代码;

3、检查问题是否确实得到了解决。

有些类型的需求,开发或测试所需时间可能很长。可能是由于我们是技术人员,所以时常倾向于跳过第 1 项工作,或者有时会跳过第 2 项工作。但是要想做好软件,帮助客户解决问题,我们就需要把这三件事都做好。

而且,我认为将第3项工作融合到开发中是做好第2项工作的最佳方法之一,系统的设计和编码也是如此。

那么,第一步“了解我们的系统”,到底是什么意思?了解和描述问题本身的最佳方法是什么?事实证明,在这方面做得好,就会对我们编写代码的质量产生巨大影响,而这也是我看到的软件开发团队遇到的最常见的摩擦点之一。

下面介绍我发现的使用用户故事的5个常见错误。我们将探讨如何编写好的用户故事,并讨论一些真正有助于解决这些错误的技巧。

1

对用户故事这一工具的错误定位

这是一个非常常见的问题,完全误解了用户故事到底是什么。如果你在使用传统开发方法的IT组织工作,你可能已经知道一种叫做“需求(requirement)”的东西。当有人和你谈论奇怪的“敏捷”的东西时,似乎很容易地将“需求”翻译成敏捷版本的“用户故事”。

然而,真正的“用户故事”不是传统意义上的“需求”,用户故事不会告诉开发人员应该编写什么代码,或应该设计什么解决方案,而是试图描述我们要解决什么业务问题。

这是一件不同寻常的事。好的故事根本没有说明应该如何解决问题。传统需求过程往往采取需求(requirement)的形式,非常专注于指定具体的解决方案。它通常只说明应该如何对系统进行变更,例如,添加一个包含xxx条目的新的列表框、在主页上添加一个新的按钮等。这些肯定不是用户故事,它们在详细说明问题的解决方案,而不是问题本身。

这反映出以下几个问题:

首先,它完全抑制了创新。当我们了解一个问题时,不管是什么问题,我们可以想到世界上最好的解决方案。在第一个iPod引入旋转轮之前,没人能想得到,而它极大地改善了处理大量歌曲时的可用性,它比列表框要好得多,也不是一组按钮能实现的。如果史蒂夫·乔布斯一开始说我们需要一个列表框来显示歌曲列表,没人会有自由的想象空间去提出更好的解决办法。如果有,那就错了,因为这不是需求所提出的“一个列表框”。所以,我们的需求讨论更应该遵循下面这样的思路:“我们希望人们能够轻松地找到和选择他们想要的歌曲”,这才是一个用户故事。

其次,如果我们专注于规定解决方案而不是客户需求,往往会导致开发团队完全脱离他们真正需要处理的问题。如果你不真正理解你正在处理的问题,无论你的编码技巧有多好,你都无法做好这个工作。作为软件开发人员,我们的工作不是编写代码,而是解决问题,而想要解决问题,首先需要了解它。

2

将用户故事视为一份工作契约

第二个常见错误是将用户故事视为一份工作契约,这与第一个错误密切相关,但略有不同。

在受监管的行业中尤其常见,因为需要记录变化,人们常犯的一个错误是:将故事作为他们认为的变更的详细定义。他们希望故事不仅是对我们试图解决的问题的描述,而且应该对变更有一个简单的描述,详细的描述是作为稍后对话的一部分来建立的。它不是作为用户故事或需求故事来写的,而是作为对话的占位符。

如果我们的故事采取了某种契约的形式,在产品所有者和开发团队之间实行,那就错了。有几个原因:首先我们试图避免参与开发的人员之间的某种契约关系,由文档为媒介的开发人员在协作时更有创造力,因此,我们希望他们经常协作,并自行决定何时协作。

契约不能改善协作,相反,会使协作关系变得紧张。

书面文字是一种低带宽的交流形式,人们很容易对所写的内容产生误解。而通过对话,可以让人们更容易发现误解,然后进行互动讨论,以澄清并纠正错误。最好的团队经常在一起讨论,用户故事应该是以一场对话开始的。这是建立细节的第一步。这意味着你必须找到一种不同的工作方法,来记录对话中的内容。事实上,用户故事和随后的验收测试要比需求规范文档更擅长这一点。

用户故事通常被误解为由业务需求人员提供给软件交付团队的轻量级需求。这种误解导致在一个任务管理工具中收集记录这些需求,并由业务代表记录下大量细节。除极少数情况外,业务代表也是一名技术专家,对产品有着远大的愿景,这种工作分工阻止了组织从用户故事中获益。为了清楚地说明,如果团队在移交过程中被动地接收文档,无论这些文档被称为什么,无论它们是纸质文档、wiki文档还是票务系统文档,这实际上不适用于用户故事。具有这样一个过程的组织不会获得迭代交付的全部好处。

3

用户故事太大

一个好的用户故事确定了一个具有价值的工作单元,而高效地进行高质量工作的秘诀是小步快跑。因此,用户故事所代表的工作单元应该尽量小。对于最大的用户故事,我们也应该能够在一个Sprint或迭代中完成它,可能也就是一周或两周的时间。理想情况下,大多数用户故事都应该比这个要短得多,如果能在一两天内完成,那就更好了。

这就让我们在使用用户故事时,常常遇到一个更棘手的问题:如何将它们分解成足够小,以便我们可以快速完成每个用户故事,同时仍能向用户提供价值。用户故事的要点是,它代表了对用户有价值的东西,从用户的角度来看,这是系统行为的一个有价值的增量。

4

认为小的故事没办法对用户产生价值

人们关注的是对用户真正的价值,开发团队在这一点上经常犯另一个常见错误。对用户的价值意味着对用户有价值,一堆宝藏当然很值钱,但一分钱也有价值。就软件开发而言,用户故事只是一个较小的单元,而开发团队往往忽略了这些细小的单元所带来的价值,这通常表现在团队只对大的故事有感觉,认为用户故事做了客户可能想要的一切才具有价值,这是错误的,是软件开发中的一个大问题。

我见过一些团队在他们所谓的用户故事上工作,有时一次花一个月的时间,但这并不是我们追求的目标。从用户的角度来看,我们的想法是致力于推动软件向前演进,每个故事带给我们前进的距离可能很小,以小步骤工作更有效,更容易理解,也更容易回溯。在这个过程中,如果我们不小心犯了一个错误,风险也会低很多,因为每个变更都很小。

很多时候,当我们开始了解一个问题时,我们的想法可能太粗粒度了,故事也太大了。有些小技巧可以改进这一点,提升将故事分解为较小片段的能力。《改进用户故事的50个办法》这本书给出了一系列专注于小故事的方法。例如,针对普通用户,缩小客户群体,对运行框架的支持依赖,简化输出,这是他们提供的一些建议。

例如,我们想为某个伟大的产品添加登录功能。错误的做法是:想象所有与登录相关的功能。你可能认为你的用户想要它们,并将它们全部添加到一个庞大的登录故事中。正确的做法是:想象用户可以感知到的最小价值单位,这会让你朝着拥有所有好东西的方向前进。也许,我们可以从“为邮件列表注册用户”开始,或者简单地从收集电子邮件地址开始,这样我们就可以从“开发一个简单的注册表单”作为起点。

当然,这对我们的用户来说肯定有一定的价值,而不仅仅是一个正确的登录,它使我们能够将系统的框架放在适当的位置,并做一些有用的事情,这可能才是一个合理的工作量。

接下来,我们也许可以添加一些只有注册用户可以看到的功能,但其它功能现在还不能明显带来真正的好处。

现在,我们可以开始思考授权问题并解决这些问题,我们可以进一步添加密码,也许以后会通过密码规则来对密码进行增强。

我经常听到开发团队担心这些微小功能的用户价值。是的,他们会的,用户会更看重整个功能,但软件开发并不是这样,这需要时间。采取更渐进的方法可以让我们缩短价值实现的时间。即使价值更小,也有更多的机会了解真正适用于我们用户的内容。对于一个众所周知的登录系统来说,这可能不是必要的,但如果你正在开发一个新的系统,这种做法就是一个非常棒的工具。在这里做的每一步,用户都会得到比他们之前更多的东西。

用户故事是一种开发工具,它帮助我们建立一个对系统的外部视角,以便它能让我们面对真正进展(working code),并保持我们对真正重要的事情的关注。我认为,用户故事的主要价值是帮助我们把“系统做什么”和“它是如何做的”进行非常明确的分离。

回到前面提到的登录的例子。做完上面提到的小用户故事以后,我们可以想到各种各样的小且简单的故事,例如,添加一些功能来应对旧的未使用账户的密码过期问题,这些功能适用于更高级的用户组,每一个小的工作步骤都是重要而有价值的,好的用户故事应该有助于我们更好地实现价值。

5

故事依赖

故事之间的依赖会导致各种各样的问题,这是不可避免的,因为我们添加了新的故事,它们可能构建于我们为旧故事编写的代码之上。如果我们做得很好,那么,新故事往往比旧故事更容易编写。 由于一些工作已经完成,这里就有一个排序问题。

然而,假如我们试图操纵这些排序,以便能够优化开发过程,很可能会阻碍我们专注于我们所提供的价值,从而导致更大的危险,那就是我们最终会专注于大量的、过于复杂、我们认为必须有的东西,而从用户角度看来,这些东西很可能实际上并没有增加真正的价值。好的故事是有原子性的,也就是说:我们应该能够以我们喜欢的任何顺序来实现它们,无论以什么顺序实现它们所消耗的总成本是相同的。

一系列类似故事中的第一个故事有时会涉及较多的工作量,因为,我们可能需要建立一些支持性的基础设施,或创建一种新的测试框架,这些都只是必要的成本,而且无论我们从哪个用户故事开始,它们都大致相同。所以,当我们关注真正的目标软件时,不要担心顺序,它会为用户带来价值。但这并不意味着我们可以在质量上偷工减料,做坏事。

我们应该按照用户故事要求的那样做好,即使这意味着在一个特定的故事上多花一点时间。当然,我们也会尽可能快地专注于交付用户真正想要的东西。用户故事有助于让我们保持专注,避免过度设计。

用户故事确实在某种程度上取代了需求,但它是一种更巧妙的工具。它不是以一种不同的方式用来格式化给开发团队的指令列表,而是作为一个工具,使开发过程作为一个整体专注于真正重要的事情,为用户提供有用或有趣的软件和价值。

Image

乔梁老师开课啦~视频课程《持续部署训练营(Python版)》,原价1699元, 限时特价699元

你的软件开发效率够高吗?质量够好吗?你的团队多长时间才能向用户实时推送一个生产变更?你的软件在发布时,你是否因担心软件交付质量而感到压力倍增?你是否遇到过部署失败,甚至导致停机的情况?持续部署可以帮助你消除软件交付的痛苦,让你能专注于为客户高价值的需求,而不会因为这些交付执行类问题而花太多精力。本课程通过学练结合,理论结合实战,让你体验如何使用构建-测试-部署管道,进行持续部署。并练习如何在有效监控部署的同时,逐步发布功能特性,并作数据库结构变化。

Image

(扫码订阅)

Image