特性注入是一种业务分析过程的框架,它让团队在频繁迭代交付的项目中(比如实施敏捷或精益过程的项目)充分利用传统业务分析方法的价值。它专注于使用测试驱动开发和行为驱动开发来交付商业价值,并确保团队只去构建能交付价值的特性和项目,避免需求蔓延(scope creep)和以防万一的代码(just-in-case code)产生浪费。
本文将对特性注入以及相关方法做一个扫盲性的介绍。我们会解释这个框架的关键要素,并附上实例来证实它们。为了让文章保持相对较短,我们不会深入到某个工具或方法中,而是会给出一些参考资料,以便大家做进一步的研究。
为什么我们要关心特性注入?
想象一下你在为一家在线商店的 IT 部门工作,该商店销售图书和消费电子产品,市场部门的副总裁发起了一个新的项目,想要整合第三方的销售分析解决方案。第三方的供应商使她确信,这样的整合是非常有益的,但需求是模糊不清的,她经常会说“把我们所有的数据都发送给他们”之类的话语。经过初步的分析,你的团队身陷于一些艰难的决定中,比如数据结构、导出文件的管理以及为了保护隐私和遵守数据保护法律所需的数据伪装。你很清楚不能把信用卡数据发送出去,但没有人真正知道客户的家庭地址和出生日期是否可以不经伪装就发送出去。市场部门的人员不顾架构团队的抱怨(会影响日常交易的运作),坚持要把数据及时地发送出去。有一名架构师与销售部门的资深总监是高中时代的朋友,他们在一起喝啤酒时,架构师表达了自己的担忧,然后整个项目就被搁置起来,正式等待进一步分析。这是不是耳熟能详?请接着往下读,你会了解如何避免这种情况。
如果你在为一家大型组织的 IT 部门工作,你的团队很可能必须要平衡和安排来自多方利益相关者的需求和要求,而且由于知识没有集中化,在软件开发的准备阶段,你必须让多名利益相关者甚至多个团队参与进来。你很可能会感觉到,你只要交付某个特性,马上就有人会提交变更请求,似乎商业用户没有对所需的方案进行过从头到尾的深思熟虑,导致许多需求蔓延和无谓的返工。如果你在这样的组织中扮演着商业利益相关者的角色,你很可能会觉得只用即时范围(比如用户故事)驱动的增量式或演进式开发方法无法交付商业价值。这两个问题都是由组织的大型业务和大型系统的复杂性导致的,它有两个相关的症状:对项目的商业价值从何而来,与交付团队沟通的商业用户经常没有定义清晰和沟通良好的想法;交付团队过分关注低层次的功能细节,忽视大局。
特性注入是防止此类问题的有效途径,同时它可以避免一些在更为传统的阶段式的开发过程中时常遭遇的陷阱,比如分析瘫痪、长分析阶段,以及对那些在实现前会改变的需求进行无用的分析。特性注入的目标是要把业务分析师社区同敏捷开发社区联系起来。从某个角度来看,特性注入让传统的业务分析师使用 UML/Use Case 或者 SSADM,有效地参与到敏捷或精益项目中,只是重点略有变化,不会产生学习新技术的陡峭曲线。从另一个角度来看,它帮助敏捷或精益软件开发团队从刚刚够用和及时的分析方法中受益,防止在复杂的企业项目中产生需求蔓延或无法交付商业价值的情况。
特性注入的三部曲
特性注入并没有设计成一个过程,它是在实践中产生的。最初的想法是由 Chris Matts 想到的,那时他正在 dot com era 与 Rohit Darji 做结对分析,由于空间的限制,他们两个共享一个桌子。2003 年的时候,Andy Pols 和 Matts 想寻找一种让传统业务分析师参与到敏捷项目中的方法,于是他们进一步演进了那个想法。2004 年的时候,当 Matts 与 Sanela Hodzic 一起工作时,Matts 对那个想法进行了扩展,使用实例去验证或推翻模型。最后,Matts 和 David Anderson 在 2007 年敏捷大会上的一次交谈,让这块思想拼图完整起来,他们把 IT 项目看作是信息到达的过程。
提取其核心的想法,Kent McDonald 把特性注入定义成一个三步走的过程框架(他在 2009 年敏捷大会上作了题为《特性注入:简介》的演讲):
- 寻找价值
- 注入特性
- 发现实例
这个框架的适用性很强——可用于小型项目,也适用于大型项目;团队也可以使用不同的方法来实现所需的效果;根据团队的特定约束,他们还可以侧重于过程的不同方面。
寻找价值
很多项目都是由功能请求开始的,然后团队去追寻那个未知的商业价值。例如,有一个请求想要构建更友好的用户界面,它可能来自于提高雇员满意度的需要,而其本身可能来自于减少员工流失率的需要,以便降低运营风险。当这样的信息在组织的不同层级和参与软件交付的不同角色之间传递时,时常会发生丢失。当项目的真实意图没有说明清楚、经过良好地沟通时,交付团队能实际交付它们的成功率会非常低。同时他们也没办法确定其它可能更容易、更廉价或者更快的实现方法来交付所需的商业价值。
为了确保软件可以交付预期的商业价值,我们首先必须对它进行明确的定义,并进行良好的沟通。有几种现成的过程框架试图处理这个问题,它们取得了不同程度的成功。用户故事要求对商业价值进行显示的声明,但许多团队都做得不对,导致故事卡片泛滥成灾。尤其是复杂的企业系统,价值对于开发团队来说并不总是显而易见的,他们需要上级的澄清和分析。Mark Denne 和 Jane Cleland-Huang 在《 Software by Numbers 》(译者注:该书中文版本已由清华大学出版社于 2005 年出版,名为《价值驱动的软件开发》)一书中描述了一种方法,它基于财务模型来驱动软件交付,但这对于团队来说是个难题,因为商业价值很难用数字描述,而且估算这样的数字不比估算某样东西需要多久才能交付来得简单。对预期商业价值分配的数字往往会成为项目构建的“基石”,很少会受检查或质疑。这会导致项目毫无进展或成为僵尸项目。
在特性注入中,团队首先会通过建立商业价值交付的模型来“寻找价值”,而不是使用简单的数字来进行描述。
例如,整合销售分析功能的价值模型可能会类似于:通过增加对现有客户的重复销售,我们会赚取到利润,我们期望利用销售分析功能,对大家可能想要购买的东西,主动提供一些建议,而不是变成一个被动的购物系统。通过使用这个方法,我们期望在第一个月增加 10% 的销售,6 个月内增长 200%。
模型要比简单的数字来的有用,因为它对潜在的价值做出了明确的假设。这样的模型可以用来评估系统是不是要包含由不同利益相关者建议的业务特性,并可以有效防止项目范围的膨胀,防止提供只看不用的特性。例如,根据与客户定期联系的模型,实时分析显然是没有必要的。
商业价值模型让我们可以创建一种策略,一种表示“这些是我们现在以及将来要做的事情”的方法,而且更重要的是,它是一种表达“这些是我们现在或者将来不会去做的事情”的方法。关键在于,商业价值模型可以用来让项目交付团队和商业投资者或赞助者保持一致。
明确的价值模型支持并鼓励团队在有新的信息到来时,频繁地对项目交付的价值进行重新评估。例如,在首次交付这个特性的一周后,我们可以衡量客户是否真的会购买系统推荐的商品,并判定这样的分析是否能提供预期的价值。我们可以利用这种信息来决定是否修改用于提供建议的分析方法,或者把重点放到运行良好的特定类型的建议上,或者在调查可以取消的特性之前监视客户的满意度。
让假设变得明确还可以帮助我们建立起价值从何而来的共识,让团队发现新的机会或者防止他们走进死胡同。例如,架构团队可能会建议使用一些现成的统计数据,比方说每周销售最火的 10 件商品,来检验客户是否会对主动销售做出积极回应。不整合第三方供应商,也可以做到这一点,或许还能提供一些快速的投资回报。
这儿是一些工具,你可以用来寻找价值并发展出模型:
- 对 why 堆栈 /5 个 why(why stack / five whys)进行出栈操作。我们从特性请求着手,不停地对 why 堆栈进行出栈操作,直到我们获取到最终的输出和价值。
- 询问“为什么那会有所帮助?”
- 目的对齐模型(purpose alignment model)
- 波士顿咨询集团的市场成熟度模型
- 检查模板。这对非功能性需求特别有用(对实际的需求“不进行设计”,请参考《Competitive Engineering》)
Chris 曾经参与过一个项目,那个项目用来计算一家石油公司的信贷风险。他加入那个项目时,他们刚刚选定解决方案不久。那个解决方案涉及到一个通宵批处理进程,用于计算公司交易对手的风险。
由于过去几年遭受的损失,该项目已经启动了。那个项目旨在防止公司再次遭受类似的损失。公司想要防止交易员与那种迟早会越过信用限额的交易对手发生业务往来。从某种程度上来讲,该项目的价值是可以被理解的。
其中有一个故事是说一家公司知道自己快要破产了。在它宣布破产并卖出期权的前几天,它就已经进入了市场。在明知自己永远不会兑现那些期权的情况下,他们还要吸纳期权费。(这类似于保险公司,在明知自己要破产,无力支付已经签订的保险单时,还在接受保险费)。那家公司已经超过了自己的限额,获取到了超过其自身价值的期权费。石油公司蒙受了更大的损失。
对付这种情况的唯一途径,是构建一个实时(或接近实时)系统,在交易完成的几分钟内就可以更新风险数据。通宵批处理系统不能产生这样的价值。
该系统可以让公司预测未来的风险,让他们可以找出未来何时他们的交易对手可能会不履行自己的限额。
注入特性
一旦定义好模型,我们要做的不止是评估是否接受或拒绝某个建议的特性。我们可以主动创建一个特性列表,基于我们的模型朝着交付商业价值的目标前进。这是特性注入的核心。
做任何分析最错误的地方都是从输入着手,然而这恰恰是许多团队在迭代交付时会犯的错误,因为从技术上来说,在使用某个功能之前,必须有东西输入到系统。在本文开篇的故事里,那个团队正是因为这个原因,在数据保护需求和运营顾虑上毫无进展。从系统的输入着手,会导致无休止的“我们需要什么”的问题,并且需要耗费大量的时间去分析大家建议的每一个特性,以便判定是否真的需要那个特性。这是一种分析瘫痪的常见原因。除了把输入当作创建输出的依赖,将输入送进计算机系统本身是没有什么价值的。
为了交付价值,特性注入帮助团队从输出开始工作。商业价值模型可以告诉我们我们追求的价值是什么。我们可以利用它来确定系统至少要有哪些输出才能交付那个价值。对于每个输出,我们可以使用传统的业务分析建模方法来记录产生那些输出所需的业务转换。同时那些业务转换也可以帮助我们确定所需的输入。
例如,为了使用之前描述的模型增加对现有客户的重复销售,最初我们可以侧重于主动提供通常大家一起购买的商品,或者提供拥有类似购买模式的人买过哪些商品的信息来增加销售。现在我们有两种商业价值增量(BVI,Business Value Increment)。
- 第一种,交付团队认为已经有现成的数据摆在那儿了,没有必要执行代价高昂的分析。他们建议创建一个夜间执行的作业(Job),执行简单的数据查询操作,并为库存中的产品一一记录下最佳建议,然后在结账过程中把它作为建议显示出来。
- 第二种,交付团队建议他们可以导出销售信息,包含产品和客户标识符,不包含任何敏感的个人数据,这些数据足以让分析程序提供建议。然后电子邮件作业会每周给客户发送由分析程序提供的建议。这两种情况的项目范围明显不同,价值模型还可以帮助我们对采取哪种方法进行评估。
在讨论这两个选项时,交付团队的一名分析师还提出了第三种完整的替代方案: - 通过重用已有的免费送货券系统,如果客户在一定的日期内再次进行购买,就向他们提供免费送货服务。实现这个方案所需的特性是在购买完成后自动发布一张新的免费送货券,并对发给客户的确认邮件稍作调整,使其包含送货券的信息即可。
通常业务人员会想出不成熟的解决方案,而不是他们想要的价值。他们购买了一个分析软件包,而且它在演示的时候效果非常好,但他们并没有对它进行彻头彻尾的考虑。现在我们了解到这项工作的价值在于带来新的销售,有许多方法可以达成这一目的,每一种都会成为一项单独的工作。使用商业价值模型,我们可以对建议的方案进行评估。关键在于,由于我们按照价值进行评估,所以我们可以开始切割价值。对于某个商业价值项,我们可以拥有多个交付物,而不是只有单个交付物。对于方案是否可行,我们可以开始快速地获取反馈。
从输出到输入进行工作可以防止每一步的分析瘫痪。我们会主动设计相关特性,并把输入送进系统以实现它们,而不是去评估某个特定的特性是否相关。商业价值可以确定输出的范围,而输出又可以确定过程和输入的范围。
注入特性可以使用的工具有:
- 传统的数据实体关系建模(ER)
- 对象建模(UML)
- 建立在电子表格内的模型(参考案例学习)
- 效果映射( Effect mapping )
Sanela Hodzic 和 Chris Matts 在一个用于计算油轮信贷风险的系统上,首次运用了这个方法。复杂的情况建模在了电子表格中。
输出很容易描述。你需要风险开始的日期、风险结束的日期以及风险金额。这些风险可以汇总起来,展示出交易对手的初步情况,如下所示。
从图中可以看到,系统显示在第四个月当 3 艘油轮都遭遇风险时,会有造成 2 百万的风险金额。信用部门想要在 4 月份阻止任何可能增加风险的业务。
现在我们了解了输出,就可以注入特性来计算价格了。我们从输出到输入倒着来工作。我们把油轮装载的油桶数乘以每桶的价格就可以获得金额。我们可以从“原油价格”系统中获取到原油的价格,因此我们可以就此打住。
原油的桶数更加有趣。在原始的合同中,桶数可以有 10% 的公差,因此,谨慎起见,我们把桶数设定成了合同数量的 110%。我们可以从“原油合同”系统中获取到这一信息。
当油轮确定后,我们可以获取到更加准确的原油桶数,偏差在 2% 左右。这一信息存储在调度系统中。但是,当有容量腾出可以进行更多交易时,这种额外的准确性却可以让交易员受益。加入这一信息是另外一个商业价值项。
当原油装上油轮后,准确的原油桶数就可以确定了。这一信息存储在运营系统中。再次,受益者是交易员。
起始日期和结束日期也在合同中指定了。它们也会有偏差。例如,一月份,或者第三季度,或者下半年。很明显,风险存在的时间越长,它的后果就越严重,因为它不能与其他交易发生重叠了。因此为了计算风险的起始日期,我们需要可以装载原油的最早日期。当交易对手付款后,风险就结束了。为了计算可能的最晚付款日期,我们需要了解交易对手最晚会在什么时候装载原油,这样最晚付款日期就是最晚装载原油的日期(合同系统)加上付款期限(计费系统)。当油轮调度好(调度系统)并装载完毕(运营系统)后,偏差会进一步减小。
现在我们知道系统需要哪些数据。我们还可以把交付物切割成几个价值交付物。一个是在原油价格系统、合同系统和计费系统中的数据,这些数据是计算最大风险所必须的。然后是其他交付物,加上调度系统和运营系统。
我们的第一个商业价值增量看起来像这个样子……
一旦我们确定好价格,我们就要从系统外部寻求信息来源,然后我们就可以停下来。特性注入有明确的结束点,因此不会遭受分析瘫痪。
发现实例
注入特性可以提供一组创建输出的“基本路径”,它们会交付商业价值。但是注入特性并不会提供所有会影响输出的输入变量,也不会提供成功交付需要考虑的所有情况。为了确定这些变量,我们必须扩大范围。特性注入以一种十分特别的方式来扩展已经注入的特性,只有在确保达成共识的情况下它才有效——通过使用实例。在日常交谈中,使用实例来沟通和澄清想法是一种非常自然的方法。我们使用实例时不会真正对它进行思考。比方说,在 Google 上搜索“for example”,会返回 3 亿多页结果。在需求中使用实例来验证和检查我们的假设,并从客户那里获取到他们真正的需求,也是一种非常有效的方法。
使用特性注入,团队可以扩展特性的范围,同时他们可以运用传统的业务分析方法和新兴的协作制定需求说明的方法,对特性使用的高层次的实例进行调查,以便提供具体细节。
现在扩展一下上面的案例研究,我们咨询了业务专家,想要了解我们构建的例子是否有什么不恰当的地方。业务人员不需要扩展这个模型,他们只需要为我们提供实例来检查这个模型。
起初的时候,我们只有简单的实例,比如说固定原油价格的合同。(我们需要获取合同价,同时还要有一种区分固定价格合同和市场价格合同的方法。)
然后他们开始分享在过去由不同类型的风险导致的问题。他们过去一直为一家破产的公司提供天然气。这些天然气供应给了一家发电站,为某个城市提供照明电力。当工程师关闭其他地方的天然气时,他们仍然会供应给那家发电站,警方通知他们如果他们将其关闭,他们就会违法联邦法律。结果,此类合同的风险在合同生效之日起就是全额的。(我们需要某种方法来辨别不能中断的合同——在合同系统中的一个新属性——以及合同的终止日期)。
业务人员能够理解这些实例,他们会提供更加隐蔽的例子。
在电子表格中建模的数据,是按照实体—关系(ER)的模型建模的。这帮助我们集中了问题,寻找出有趣的例子。比如,合同是否只覆盖到单次原油运输(油轮),还是它们能覆盖多次原油运输(驳船)。
例如,销售和市场团队在进行简单的讨论之后,认为对所有重复购买提供免费送货是不合情理的,但对于不是很重或体积较小的商品来说,是行得通的。举例来说,为一本图书提供免费送货是可以接受的,但从商业上来讲为一台冰箱提供免费送货就是不合理的。这激发了一场讨论,在哪里划定这条界线,如果客户同时购买了一本图书和一台冰箱系统应该怎么做。关于拆分购物车、管理多个购物车的建议开始涌现,然后架构团队再次利用商业价值模型建议试试简单的方案:只向订购书籍的客户提供免费送货。这很快就可以实现,而且团队在调查如何管理混合商品的购物车前,他们就可以衡量可能的影响。测试人员还举出了其他例子,另一个洲的客户购买一本图书时,他们担心国际快递的费用会超过其销售利润。这让最初的范围进一步缩减到境内客户。他们记录下这些担忧,并安排业务分析师与数据库管理员一起工作,为将来发展电子商品和国际订单的送货服务树立起良好的起点。同时,此时交付团队已经获得足够具体的信息,为了交付最初商定的特性集,他们可以开始深入细节了。在首次交付后,团队与利益相关者就可以根据该项目的价值模型对结果进行评估,并以此决定是否值得进一步完善免费送货的功能,还是去尝试其他方法来增加重复销售。
高层次的实例可以提供足够深的背景知识,让类似测试驱动开发(TDD)和行为驱动开发(BDD)之类的开发过程有的放矢。它们可以被分割成更小、粒度更细的例子,这些例子描述系统需要多少不同的功能,才能支持那个高层次的实例。如果这些例子足够详细,那么它们还能在开发过程中对系统进行自动化验证,这实际上就提供了一种衡量进度的客观标准,同时这也是活文档系统的基础。
用来发现实例的工具:
- 传统的实体关系建模(ER 建模)
- 对象建模(UML)
- 表单中的实例(详见案例学习)
- 提炼带实例的需求说明
- 领域驱动设计
关于作者
Gojko Adzic是战略软件交付顾问,他与多个具有上进心的团队合作,帮助他们改进软件产品和过程的质量。他专注于实施敏捷和精益的质量提高,尤其擅长敏捷测试、实例化需求和行为驱动开发。Gojko 经常在重要的软件开发和测试会议上发言,并运营着英国的敏捷测试用户小组。最近这11 年来,他一直在财务和能源交易平台、移动定位、电子商务、在线游戏和复杂配置管理系统等行业项目中,从事程序员、架构师、技术指导和顾问等工作。
他是如下书籍的作者:《Specification by Example》,《Bridging the Communication Gap》,《Test Driven.Net Development with FitNesse》和《The Secret Ninja Cucumber Scrolls》。
Chris Matts是一名业务分析师和项目经理,他为投资银行开发贸易和风险管理系统。他的 IT 风险管理方法源自他从投资银行那里学到的风险管理。Chris 的 Twitter 帐号是 @papachrismatts。他的博客在这里和这里。
感谢侯伯薇对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。
评论