您的位置:知识库 » 软件工程

剖析“持续交付”:五个核心实践

作者: 乔梁  发布时间: 2012-10-01 10:47  阅读: 2185 次  推荐: 2   原文链接   [收藏]  

  原文发表于 InformIT

  持续交付是一种软件开发策略,用于优化软件交付流程,以尽快得到高质量、有价值的软件。这种方法让你能更快地验证业务想法,通过直接在用户那里进行试验,做到快速迭代。 尽管《持续交付》一书主要讲的是工程实践,但持续交付的概念对整个产品交付过程都有重大意义,包括对特性的”fuzzy front end”、设计和分析的意义。

  持续交付的一般性原则如下:

  与其设计一大堆特性,再策划一个持续数月的版本发布,不如持续不断地尝试新想法,并独立发布给用户。通过充分思考,即便很大的特性或者大范围的变更,也能够通过一系列小步骤得到更快反馈,而且一旦你认为有必要停下来的话,可以随时停下来。利用跨功能团队在几小时或几天内交付这些小且增量式的功能,就能比竞争者有更多的创新,将投资回报最大化。

  持续交付五个关键实践,为你建立一个从猜测到持续反馈的最有效途径,它们就是:

  • 从最小可行产品(MVP)开始——Start with a minimum viable product.
  • 衡量新特性的价值——Measure the value of your features.
  • 做恰好充分的预先分析——Perform just enough analysis up front.
  • 少做——Do less.
  • 用户故事中要包括特性开关——Include feature toggles in your stories.

  Start with a Minimum Viable Product (MVP)

  “假如你没有因产品首发版本的寒酸而感到尴尬,就说明该产品的发布实在是太晚了。 ” Reid Hoffman, cofounder and chairman of LinkedIn (参见“建立大公司的十大创业原则”)

  如果你的项目一启动,就有一大堆需求文档 放在项目经理的桌上,那你已经失败了。精益创业运动的核心思想中,关键的一个就是最小可行性产品(minimum viable product, 缩写为MVP), 即为验证你的业务猜想而需做出的最小工作量。

  当然,在制造业,MVP的概念已经有数十年的历史——它们被称作原型(prototypes)。在使用原型时,你不必把你的MVP展示给全世界的所有人,只要选择其中一组测试(beta)用户就行了。甚至用一个尚无法工作的软件都行——你可以创建一个pretotype,来收集信息,一行代码也不必写。

  假如对受众来说,第一个版本至关重要,你也完全可以向全范围的用户展示经过精心打造的更完美的产品。例如,某个公司用别的商标品牌发布了它的iPhone应用的一个MVP版本。只是为了得到具有统计意义的重要反馈,即它的业务规划是否能成功。而次要目标是验证一下该软件的交付流程。

  找到MVP如何运作至关重要的一点是,需要一个由业务人员和技术人员组成的跨功能团队(cross-functional team)。这个团队中的角色包括用户体验设计(User Experience Designer,UX),分析、测试、开发、运营和基础设施建设。当然,一个人可以承担多个角色,所以也不是非要很多人,才能完成一件事。

  由于一个小团队在数周内(而不是一两个月的时间里)就可以完成MVP,所以此时也不需要很多仪式,因为你不必象赌博一样,押上整个公司,或一大笔钱。

  Measure the Value of Your Features

“度量是产品的一部分” — John Allspaw, VP of Technical Operations, Etsy (参见“Building Resiliencein Web Development and Operations”).

  精益创业中另一个核心概念是验证性学习(validated learning),即通过收集产品被真正使用后的衡量指标,而不是通过对用户的提问来验证效果。正是电视剧《Dr. Gregory House》中,他喜欢说的那样,人们会说慌的——尽管更文雅一些,我们可以说他们不知道他们想要什么。把你的用户当做是试验对象,而不是那些聪明的代言人(intelligent agents)。

  你要能回答下面这样的问题:

  • 我们在产品上所做的这些修改是否让更多的人注册了,逗留时间增加了,还是增加了收入? Or is it time to pivot?
  • 在做A/B测试时,该特性在哪个版本的效果更好?
  • 所有的系统指标看上去都不错,一个用户说我们的网站不能用。难道是我们的网站坏了吗?
  • 我们产品中的哪些特性是收入的最大来源?

  你不必在Apache的日志中搜罗信息,也不必试图从那些辅助功能上回溯,或利用定制化查询,就应该能够回答这些问题。这些问题应该看一眼仪表盘(Dashboard)就能知道,而且,这些信息应该是完全可审计的。

  在Eric Rie的《精益创业》The Lean Startup: How Today’s Entrepreneurs Use Continuous Innovation to Create Radically Successful Businesses(Crown Business, 2011)一书中,他提到了 Grockit 的故事:

遵循精益制造中的 kanban 原则, […]Grockit改变了产品优先级评估流程。在这个新流程中, 直到验证性学习(validated learning)时,用户故事才算完成。所以,一个用户故事要经历四个阶段:在product backlog中,正在实现中,完成(从技术角度看特性是完成了),以及验证中。验证被定义为:“第一时间知道某个用户故事是不是一个好主意” 。这种验证通常是以某种隔离测试来展示客户行为的变化,当然也包括客户访谈或问卷调查。

  只有当度量项被放在用户故事中一起完成时,这种学习方式才有可能。

  看上去,这一原则可能是针对web应用的,事实上,对于嵌入式系统和用户自行安装的产品也是同样道理。为了远程调试和失败报警的目的,以及理解用户的使用模式,所有类型的系统需要收集这些度量项。

  Perform Just Enough Analysis Up Front

“你要知道,当团队在编码之前试图完成规格说明的收集时,你就不是在做迭代开发。” Bas Vodde, “History of Nokia Test.”

  一旦你想到了一个点子,是一个最小可行产品(minimum viable product),你就要开始交付软件了。第一步是分析。但是backlog中所有的用户故事不必被全面分析。因为那么做,这也是一种浪费。为了全面分析用户故事,你要从客户、开发人员、测试人员、用户体验设计和用户那里得到信息。如果团队在花大量时间去收集这些信息,那么他们的这些工作实际上还没有交付有价值的功能,也无法从那些使用该系统的用户中得到真正的反馈。

  那么,需要做多少前置分析呢?在开始开发一个用户故事之前,我们只关心三件事:

  • 交付用户故事的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的一个团队在其用户故事中有特性开关,那么他们在实现这个用户故事时的第一个任务就是加一个开关。特性开关是用户故事价值的一部分,当然,由于增加开关所带来的开发成本也在估算时考虑了。如果增加开关的成本太高了,这就是一个信号,你的用户故事分解的不好。

  除了能够做增量式地功能交付以外,特性开关还有另一个重要的用途。万一遇到未预期的负载过高,它们可以优雅地对在线服务进行降级(degrade),比如通过关闭资源密集型的特性,如推荐引擎。另外,当发布出了问题时,它们也可以让你马上关闭存在问题的特性,相当于做了一次回滚操作。

  Conclusions

  一种常见的软件项目失败模式是Don Reinertsen在他的书《The Principles of Product Development Flow: Second Generation Lean Product Development (Celeritas, 2009)》所说的“large batch death-spiral”,而product owners为了试图确保产品的成功,在项目进行中,增加越来越多的范围,从而导致成本显著增加,工期明显拖长。

  持续交付让团队大幅度减少发布高质量软件的transaction成本,所以你可以更频繁地发布,产品团队从而能够从用户那里得到更加丰富和迅速的反馈。但是,反过来,对于在整个软件交付流程中如何管理工作流,你也需要改变一下思考方式。尤其强调的一点是,假如你正确地实施了持续交付,在用户那里验证新的主意时,技术人员就不再是一种约束了。使用传统的交付流程,则你不得不等上数个星期或都是数月,才能看到你的想法变成软件。通过增量式交付小的功能,并收集反馈,我们可以持续思考:“下一步我们应用做什么?”没有哪个团队达到这种转变后,还想再回到原有的工作方式上。

  使用传统的交付方法,我们必须细心地挑选我们想实现哪些想法,因为软件交付的过程成本太高了。当然,那种审查流程也并不是基于真实数据的。然而,通过持续交付,我们就有了我的同事Darius Kumana所说的一种 ”创新失败的安全气囊”。在系统 we can try crazily innovative ideas cheaply and safely at any stage in the evolution 演进的过程中,可以用廉价且安全的方式尝试那些异想天开的创新想法,通过仅将其开放给少量用户组,缓解可能失败的风险。持续交付通过大幅度减少软件发布的风险来解放我们,把分析师带回他们本来的位置——全力创新。

2
0
标签:持续交付

软件工程热门文章

    软件工程最新文章

      最新新闻

        热门新闻