那么,需要做多少前置分析呢?在开始开发一个用户故事之前,我们只关心三件事:
交付用户故事的marginal value是什么?
交付用户故事的marginal成本是什么?
我们是否有足够的信息开始开发用户故事?
前两个问题是很重要的,这样当有交付能力时,我们就可以决定我们应该做哪个用户故事。为了做到这一点,需要找到哪个用户故事会让经济产出最大化。而后两个问题是紧密相关的,因为评估某个用户故事的成本所需信息的数量通常要比你开始实现它所需的信息量多。但是,象我的同事Peter Gillard-Moss曾经和我说的:至少需要一个验收条件。
“刚好够用的分析”这个纪律需要在整个项目生命周期持续进行,并要强调创建小的、增量式的用户故事。这会把我们带到下一个实践: doing less。
Do Less
“[如果]你发现自己没有空间放卡片,就使用更小的卡片.” PhlIp (see “Re: [XP] Re: Token definition in User Stories”).
在敏捷分析中,也许最流行的短语就是Bill Wake的INVEST原则。Wake认为,好的用户故事是独立的(independent),可协商的(negotiable), 有价值的(valuable),可估计的(estimable),小的( small),和可测试的(testable)。我想说的是:“小的(small)”。
大家常常认为,特性 features 和 stories 是可以互换的。有时候人们认为一个特性就是需要花两星期完成的工作。我记得在某个项目里,一个用户故事就是一个几页长的word文档。
XP让人们把用户故事写在一个3 [ts] 5的索引卡片上,这是有原因的。用户故事不应该几天内还做不完。超过一个星期的工作就是太长了,应该被分成更小的工作。为什么呢?
为了确保我们可以从用户那里得到对我们工作产出的瞬时反馈,以便我们可以发现我们做的事情是否有价值。
为了验证我们是否做完了——不只是“开发完成”,而是可发布——以便我们可以展示我们真实的工作进度。
为了避免完成大块工作后再集成、测试和发布带来的痛苦。
为了确保我们不断地测试并改进我们的交付过程
常见听到的反对意见是,我们不能在几天内就完成有价值的事儿。我认为,这说明了两件事儿。一是缺乏想象力,二是没有理解“哪些东西组成了价值”。正如我之前提到的,只有通过向用户展示,一个用户故事的价值才能被衡量。的确,你无法在一两天之内就完成整个特性。是,你可以完成该特性的一个很小的部分,并得到反馈。比如说,你正在做一个网上订酒店的网站,打算增加一个特性,让人们能选择他们是否需要早餐。你不必为所有的酒店或所有的合作方创建这个功能。相反,最开始的一个用户故事只是为某个酒店增加这样的特性,而且也不需要什么配置选项,然后在进行下一步时,为这种特性的可行性收集一些反馈。
无论你做什么,都不要把特性按照解决方案中的那些分层概念来划分用户故事,比如一个故事是实现持久层,另一个故事是实现业务逻辑,还有一个是实现UI。用户故事应该总是很小的纵向切分。如果你不得不做一些集成工作,也要聚焦于让这种切片尽可能薄。比如,假如作为功能的一部分,你要传递一系列信息的消息给另外一个系统,那么你第一个用户故事应该是传递那个最简单的消息,以便第一次实现就做到“端到端”的集成。
通过不断对功能的分解,直到找到你可以向用户展示的功能最小集,来强迫自己找到某个特性的真正价值(并从中学习)是一个很困难,但也极其有价值的学问。你可以使用得到的反馈来决定下一步(两三天的工作)的工作是什么,或者是否不要再按当前的样式开发这个特性,因为它并没有象你想的那么有价值。
时刻牢记一点,即软件开发中,最大的浪费就是无用的功能——超过50%的功能从来没有或很少被使用(详见这里)。
不要问下面这类问题:“我们还要加点什么放在这个特性里,才能确保大家喜欢它?”或者“我们还要在当前这个版本中增加哪些功能,才能算一个真正伟大的产品?”。相反,需要问这样的问题:“我们现在就能交付我们手里的东西吗?如果不能,那是为什么呢?”少做点儿,你就不再太关注你付出的努力,而是关注于从你的用户那里学到了什么。
你可能想做一堆用户故事之后才把某个特性展示给所有人。但总是要在发布和确保发布内容满足质量要求(由用户决定)之间做出平衡。所以你需要feature toggles。
Include Feature Toggles in Your Stories
“现在,在Facebook.com网站上的代码中,已经包含了后六个月后将要发布的特性了。” Chuck Rossi (see TechCrunch discussion about Rossi’s May 26, 2011 “Facebook Tech Talk”).
如果你想提高发布的频率,将应用的部署和特性的发布解耦是关键。特性开关是一种模式,用于控制谁可以使用哪个特性。这样,即使软件中包含一两个故事,还不想公开的未完成特性,你也可以发布新版本。
Facebook的工具Gatekeeper让它可以动态控制谁能看到哪个特性。比如,将某个特性仅开放给10%的Facebook用户, 或者那些在Facebook工作的人,或者25岁以下的女性用户,或者是英国居民,等等。(Gatekeeper甚至有这样一个开关,可以让除了TechCrunch员工以外的所有人使用某个特性)。这使得Facebook的开发人员可以仅在某类人群中试验某个特性,并逐步向更多的人群扩展。
在将特性分解成多个用户故事时,特性开关是一种非常重要的约束条件。对于使用开关来说,常见的反对意见是: ”有些用户故事会涉及所有的用户界面。如果对其使用特性开关的话,需要增加很多工作。” 答案是:以一种非常容易增加特性开关的方式将特性分解成用户故事。
特性开关应该是用户故事中的一等公民。Orbitz的一个团队在其用户故事中有特性开关,那么他们在实现这个用户故事时的第一个任务就是加一个开关。特性开关是用户故事价值的一部分,当然,由于增加开关所带来的开发成本也在估算时考虑了。如果增加开关的成本太高了,这就是一个信号,你的用户故事分解的不好。