第3章:学无止境
许多新技术都基于现有的技术和思想。它们会加入一些新的东西,这些新东西是逐步加入的量。需要了解一些跟踪变化的方法
给自己投资,让自己与时俱进,当然再好不过,但是也要努力对团队投资。
学习新的技术和新的开发方法很重要,同时你也要能摒弃陈旧和过时的开发方法。换句话说,你需要懂得丢弃。
你要对没有完全理解的某些疑问不懈地深入追踪下去,要打破砂锅问到底,以及有效地提问。
一个活力十足的敏捷开发团队需要有规律反复地做很多事情,一旦项目开始运作,你就要把握开发节奏。
跟踪变化
如何才能跟上技术变化的步伐呢?
迭代和增量式的学习。每天计划用一段时间来学习新技术,它不需要很长时间,但需要经常进行。记下那些你想学习的东西——当你听到一些不熟悉的术语或者短语时,简要地把它记录下来。然后在计划的时间中深入研究它。
了解最新行情。互联网上有大量关于学习新技术的资源。阅读社区讨论和邮件列表,可以了解其他人遇到的问题,以及他们发现的很酷的解决方案。选择一些公认的优秀技术博客,经常去读一读,以了解那些顶尖的博客作者们正在关注什么(最新的博客列表请参考pragrog.com)。
参加本地的用户组活动。Java、Ruby、Delphi、.NET、过程改进、面向对象设计、Linux.Mac,以及其他的各种技术在很多地区都会有用户组。听讲座,然后积极加入到问答环节中。
参加研讨会议。计算机大会在世界各地举行,许多知名的顾问或作者主持研讨会或者课程。这些聚会是向专家学习的最直接的好机会。
如饥似渴地阅读。找一些关于软件开发和非技术主题的好书(我们很乐意为你推荐),也可以是一些专业的期刊和商业杂志,甚至是一些大众媒体新闻(有趣的是在那里常常能看到老技术被吹捧为最新潮流)。
跟踪技术变化。你不需要精通所有技术,但需要清楚知道行业的动向从而规划你的项目和职业生涯。
平衡的艺术
- 许多新想法从未变得羽翼丰满,成为有用的技术即使是大型、热门和资金充裕的项目也会有同样的下场。你要正确把握自己投入的精力。
- 你不可能精通每一项技术,没有必要去做这样的尝试。只要你在某些方面成为专家,就能使用同样的方法,很容易地成为新领域的专家。
- 你要明白为什么需要这项新技术—它试图解决什么样的问题?它可以被用在什么地方?
- 避免在一时冲动的情况下,只是因为想学习而将应用切换到新的技术、框架或开发语言。在做决策之前,你必须评估新技术的优势。开发一个小的原型系统,是对付技术狂热者的一剂良药。
对团队投资
平衡的艺术
- 读书小组逐章一起阅读一本书,会非常有用,但是要选好书。《7天用设计模式和UML精通……》也许不会是一本好书。
- 不是所有的讲座都能引人入胜,有些甚至显得不合时宜。个管怎么样,都要未雨绸缪;诺亚在建造方舟的时候,可并没有开始下雨,谁能料到后来洪水泛滥呢?
- 尽量让讲座走入团队中。如果午餐会议在礼堂中进行,有餐饮公司供饭,还要使用幻灯片,那么就会减少大家接触和讨论的机会。
- 坚持有计划有规律地举行讲座。持续、小步前进才是敏捷。稀少、间隔时间长的马拉松式会议非敏捷也。
- 如果一些团队成员因为吃午饭而缺席,用美食引诱他们。
- 不要局限于纯技术的图书和主题相关的非技术主题(项目估算、沟通技巧等)也会对团队有帮助。
- 午餐会议不是设计会议。总之,你应专注讨论那些与应用相关的一般主题。具体的设计问题,最好是留到设计会议中去解决。
懂得丢弃
在学习一门新技术的时候,多问问自己,是否把太多旧的态度和方法用在了新技术上。学习面向对象编程和学习面向过程编程是截然不同的。
学习新的东西,丢弃旧的东西。在学习一门新技术的时候,要丢弃会阻止你前进的旧习惯。毕竟,汽车要比马车车厢强得多。
平衡的艺术
- 沉舟侧畔千帆过,病树前头万木春。要果断丢弃旧习惯,一味遵循过时的旧习惯会危害你的职业生涯。
- 不是完全忘记旧的习惯,而是只在使用适当的技术时才使用它。
- 对于所使用的语言,要总结熟悉的语言特性,并且比较这些特性在新语言或新版本中有什么不同。
打破砂锅问到底
不停地问为什么。不能只满足于别人告诉你的表面现象。要不停地提问直到你明白问题的根源。
切身感受
你要能感觉到真正地理解了问题,而不是只知道表面的症状。
平衡的艺术
- 你可能会跑题,问了一些与主题无关的问题。就好比是,如果汽车启动不了,你问是不是轮胎出了问题,这是没有任何帮助的。问“为什么”,但是要问到点子上。
- 当你问“为什么”的时候,也许你会被反问:“为什么你问这个问题?”在提问之前,想好你提问的理由,这会有助于你问出恰当的问题。
- “这个,我不知道”是一个好的起点,应该由此进行更进一步的调查,而不应在此戛然结束。
把握开发节奏
时间盒
敏捷开发者可以从多方面得到反馈:用户、团队成员和测试代码。这些反馈会帮助你驾驭项目。但是时间本身就是一个非常重要的反馈。
许多的敏捷技巧来源于时间盒—设定一个短时的期限,为任务设定不能延长但是最终期限是不变的。你可的最终期限。
当你遇到艰难抉择的时候,固定的时间期限会促使你做决定。你不能在讨论或功能上浪费很多时间,这些时间可以用于具体的工作。时间盒会帮助你一直前进。
站立会议最好每天在固定的时间和地点举行。要养成这样的习惯,在那时就准备好一切参加站立会议。
最大的节拍就是迭代时间,一般是1~4周的时间。不管你的一个迭代是多长,都应该坚持—―确保每个迭代周期的时间相同很重要。运用有规律的开发节奏,会更容易达到目标,并确保项目不停地前进。
解决任务,在事情变得一团糟之前。保持事件之间稳定重复的间隔,更容易解决常见的重复任务。
切身感受
项目开发需要有一致和稳定的节奏编辑,运行测试,代码复审,一致的迭代,然后发布。
平衡的艺术
- 在每天结束的时候,测试代码,提交代码,没有残留的代码。
- 不要搞得经常加班。
- 以固定、有规律的长度运行迭代。也许刚开始你要调整迭代的长度,找到团队最舒服可行的时间值,但之后就必须要坚持。
- 如果开发节奏过于密集,你会精疲力竭的。一般来说,当与其他团队(或组织)合作时,你需要减慢开发节奏。因此人们常说,互联网时代发展太快,有害健康。
- 有规律的开发节奏会暴露很多问题,让你有更多鼓起勇气的借口。
- 就像是减肥一样,一点点的成功也是一个很大的激励。小而可达到的目标会让每个人全速前进。庆祝每一次难忘的成功:共享美食和啤酒或者团队聚餐。
第4章:交付用户想要的软件
你不可能“战胜”变化——无论它是设计、架构还是你对需求的理解。敏捷一一成功的软件开发方法一一取决于你识别和适应变化的能力。只有这样才有可能在预算之内及时完成开发,创建真正符合用户需求的系统。
在本章中,我们会介绍如何达到敏捷的目标。
首先,要介绍为什么用户和客户参与开发如此重要,以及为什么让客户做决定。
设计是软件开发的基础,没有它很难做好开发,但你也不能被它牵制。将介绍如何让设计指导而不是操纵开发。
说到牵制,你应确保在项目中引入合适的技术。你需要合理地使用技术。
不能一次又一次为用户演示新功能,而浪费宝贵的开发时间,因此你需要提早实现自动化部署。只要代码一直可用,并且易于向用户部署,就能使用演示获得频繁反馈。这样你就能经常向全世界发布新版本。你想通过使用短迭代,增量发布来帮助经常发布新功能,与用户的需求变化联系更紧密。
事实上是固定的价格就意味着背叛承诺。
让客户做决定
开发者(及项目经理)能做的一个最重要的决定就是:判断哪些是自己决定不了的,应该让企业主做决定。你不需要自己给业务上的关键问题做决定。毕竟,那不是你的事情。如果遇到了一个问题,会影响到系统的行为或者如何使用系统,把这个问题告诉业务负责人。如果项目领导或经理试图全权负责这些问题,要委婉地劝说他们,这些问题最好还是和真正的业务负责人或者客户商议。
当你和客户讨论问题的时候,准备好几种可选择的方案。不是从技术的角度,而是从业务的角度,介绍每种方案的优缺点,以及潜在的成本和利益。和他们讨论每个选择对时间和预算的影响,以及如何权衡。无论他们做出了什么决定,他们必须接受它,所以最好让他们了解一切之后再做这些决定。如果事后他们又想要其他的东西,可以公正地就成本和时间重新谈判。
让你的客户做决定。开发者、经理或者业务分析师不应该做业务方面的决定。用业务负责人能够理解的语言,向他们详细解释遇到的问题,并让他们做决定.
切身感受
业务应用需要开发者和业务负责人互相配合来开发。这种配合的感觉就应该像-一种良好的、诚实的工作关系。
平衡的艺术
- 记录客户做出的决定,并注明原因。好记性不如烂笔头。可以使用工程师的工作日记或日志、Wiki、邮件记录或者问题跟踪数据库。但是也要注意,你选择的记录方法不能太笨重或者太繁琐。
- 不要用低级别和没有价值的问题打扰繁忙的业务人员。如果问题对他们的业务没有影响,就应该是没有价值的。
- 不要随意假设低级别的问题不会影响他们的业务。如果能影响他们的业务,就是有价值的问题。
- 如果业务负责人回答“我不知道",这也是一个称心如意的答案。也许是他们还没有想到那么远,也许是他们只有看到运行的实物才能评估出结果。尽你所能为他们提供建议,实现代码的时候也要考虑可能出现的变化。
让设计指导而不是操纵开发
“设计”是软件开发过程不可缺少的步骤。它帮助你理解系统的细节,理解部件和子系统之间的关系,并且指导你的实现。一些成熟的方法论很强调设计,例如,统一过程(Unified Process, UP)十分重视和产品相关的文档。项目管理者和企业主常常为开发细节困扰,他们希望在开始编码之前,先有完整的设计和文档。毕竟,那也是你如何管理桥梁或建筑项目的,难道不是吗?
另一方面,敏捷方法建议你早在开发初期就开始编码。好的设计依然很重要,画关键工作图(例如,用UML)是必不可少的,因为要使用类及其交互关系来描绘系统是如何组织的。在做设计的时候,你需要花时间去思考(讨论)各种不同选择的缺陷和益处,以及如何做权衡。
然后,下一步才考虑是否需要开始编码。
但是,即使之前已经提交了设计文档,也还会有一些意料之外的情况出现。时刻谨记,此阶段提出的设计只是基于你目前对需求的理解而已。一旦开始了编码,一切都会改变。设计及其代码实现会不停地发展和变化。
设计满足实现即可,不必过于详细。
严格的 需求-设计-代码-测试 开发流程源于理想化的瀑布式开发方法,它导致在前面进行了过度的设计。这样在项目的生命周期中,更新和维护这些详细的设计文档变成了主要工作,需要时间和资源方面的巨大投资,却只有很少的回报。
设计可以分为两层:战略和战术。前期的设计属于战略,通常只有在没有深入理解需求的时候需要这样的设计。更确切地说,它应该只描述总体战略,不应深入到具体的细节。
前面刚说过,战略级别的设计不应该具体说明程序方法、参数、字段和对象交互精确顺序的细节。那应该留到战术设计阶段,它应该在项目开发的时候再具体展开。
良好的战略设计应该扮演地图的角色,指引你向正确的方向前进。任何设计仅是一个起跑点:它就像你的代码一样,在项目的生命周期中,会不停地进一步发展和提炼。
不要一开始就进行战术设计,它的重点是集中在单个的方法或数据类型上。这时,更适合讨论如何设计类的职责。因为这仍然是一个高层次、面向目标的设计。事实上,CRC(类-职责-协作)卡片的设计方法就是用来做这个事情的。每个类按照下面的术语描述。
如果需求有了小的变化,它仍然容易去实现,那么它就是好的设计。而如果小的需求变化就带来一大批基础代码的破坏,那么设计就需要改进。
好设计是一张地图,它也会进化。设计指引你向正确的方向前进,它不是殖民地,它不应该标识具体的路线。你不要被设计(或者设计师)操纵。
切身感受
好的设计应该是正确的,而不是精确的。也就是说,它描述的一切必须是正确的,不应该涉及不确定或者可能会发生变化的细节。它是目标,不是具体的处方。
平衡的艺术
- “不要在前期做大量的设计”并不是说不要设计。只是说在没有经过真正的代码验证之前,不要陷入太多的设计任务。当对设计一无所知的时候,投入编码也是一件危险的事。如果深入编码只是为了学习或创造原型,只要你随后能把这些代码扔掉,那也是一个不错的办法。
- 即使初始的设计到后面不再管用,你仍需设计:设计行为是无价的。正如美国总统艾森豪威尔所说:“计划是没有价值的,但计划的过程是必不可少的”。在设计过程中学习是有价值的,但设计本身也许没有太大的用处。
- 白板、草图、便利贴都是非常好的设计工具。复杂的建模工具只会让你分散精力,而不是启发你的工作。
合理地使用技术
盲目地为项目选择技术框架,就好比是为了少交税而生孩子。
- 这个技术框架真能解决这个问题吗?是的,也许这是显而易见的。但是,这个技术真能解决你面临的那个问题吗?或者,更尖锐一点说,你是如何评估这个技术的?是通过市场宣传还是道听途说?要确保它能解决你的问题,并没有任何的毒副作用。如果需要,先做一个小的原型。
- 你将会被它拴住吗?一些技术是贼船,一旦你使用了它,就会被它套牢,再也不可能回头了。它缺乏可取消性(查阅[HT00]),当条件发生变化时,这可能对项目有致命打击。我们要考虑它是开放技术还是专利技术,如果是开放的技术,那又开放到什么程度?
- 维护成本是多少?会不会随着时间的推移,它的维护成本会非常昂贵?
当你在考察一个框架(或者任何技术)的时候, 也许会被它提供的各种功能吸引。接着,在验证是否使用这个框架的时候,你可能只会考虑已经发现的另外一些功能。但是,你真的需要这些功能吗?也许为了迎合你发现的功能,你正在为它们找问题。这很像站在结账处一时冲动而买些无用的小零碎。
不要开发你能下载到的东西
如果你发现自己在做一些花哨的东西(比如从头创建自己的框架),那就醒醒吧,闻闻烟味有多大,马上该起火了。你的代码写得越少,需要维护的东西就越少。
你可以把更多的时间和精力投入到应用的开发 - 领域或具体应用中。
根据需要选择技术。首先决定什么是你需要的,接着为这些具体的问题评估使用技术。对任何要使用的技术,多问一些挑剔的问题,并真实地作出回答。
切身感受
新技术就应该像是新的工具,可以帮助你更好地工作,它自己不应该成为你的工作。
平衡的艺术
- 也许在项目中真正评估技术方案还为时太早。那就好。如果你在做系统原型并要演示给客户看,也许一个简单的散列表就可以代替数据库了。如果你还没有足够的经验,不要急于决定用什么技术。
- 每一门技术都会有优点和缺点,无论它是开源的还是商业产品、框架、工具或者语言,一定要清楚它的利弊。
- 不要开发那些你容易下载到的东西。虽然有时需要从最基础开发所有你需要的东西,但那是相当危险和昂贵的。
保持可以发布
已提交的代码应该随时可以行动。
可以防止你提交破坏系统的代码。
- 在本地运行测试。先保证你完成的代码可以编译,并且能通过所有的单元测试。接着确保系统中的其他测试都可以通过。
- 检出最新的代码。从版本控制系统中更新代码到最新的版本,再编译和运行测试。这样往往会发现让你吃惊的事情:其他人提交的新代码和你的代码发生了冲突。
- 提交代码。现在是最新的代码了,并且通过了编译和测试,你可以提交它们了。
一个持续集成系统,可以自动集成并报告集成结果。
持续集成系统就是在后台不停地检出、构建和测试代码的应用。你可以自己使用脚本快速实现这样的方式,但如果你选择已有的免费、开源的解决方案,它们会提供更多的功能且更加稳定。有兴趣的话,可以看一看Martin Fowler的文章,或者是Mike Clark编著的图书《项目自动化之道》[Cla04]
保持你的项目时刻可以发布。保证你的系统随时可以编译、运行、测试并立即部署。
切身感受
偶尔来公司参观项目的时候,你都能很自信并毫不犹豫地给他们演示最新构建的软件。你的项目一直处于可以运行的稳定状态。
平衡的艺术
如果你不得不让系统长期不可以发布,那就做一个(代码和架构的)分支版本,你可以继续进行自己的实验,如果不行,还可以撤销,从头再来。千万不能让系统既不可以发布,又不可以撤销。
提早集成,频繁集成
在产品的开发过程中,集成是一个主要的风险区域。
尽可能早地集成也更容易发现风险,这样风险及相关的代价就会相当低。而等的时间越长,你也就会越痛苦。
绝不要做大爆炸式的集成。
当早期就进行集成的时候,你会看到子系统之间的交互和影响,你就可以估算它们之间通信和共享的信息数据。
提早集成,频繁集成。代码集成是主要的风险来源。要想规避这个风险,只有提早集成,持续而有规律地进行集成。
平衡的艺术
- 成功的集成就意味着所有的单元测试不停地通过。
- 通常,每天要和团队其他的成员一起集成代码好几次,比如平均每天5~10次,甚至更多。但如果你每次修改一行代码就集成一次,那效用肯定会缩水。如果你发现自己的大部分时间都在集成,而不是写代码,那你一定是集成得过于频繁了。
- 如果你集成得不够频繁(比如,你一天集成次,一周一次,甚至更糟),也许就会发现整天在解决代码集成带来的问题,而不是在专心写代码。如果你集成的问题很大,那一定是做得不够颊繁。
- 对那些原型和实验代码,也许你想要独立开发,而不要想在集成上浪费时间。但是不能独立开发太长的时间。一旦你有了经验,就要快速地开始集成。
提早实现自动化部署
- 用一种可重复和可靠的方式,在目标机器上部署你的应用。
- 让质量保证团队既可以测试应用,又可以测试安装过程。
- 有了自动化部署系统后,在项目开发的整个过程中,会更容易适应互相依赖的变化。
- 开始就进行全面部署,而不是等到项目的后期。
一开始就实现自动化部署应用。使用部署系统安装你的应用,在不同的机器上用不同的配置文件测试依赖的问题。质量保证人员要像测试应用一样测试部署。
切身感受
这些工作都应该是无形的。系统的安装或者部署应该简单、可靠及可重复。一切都很自然。
平衡的艺术
- 一般产品在安装的时候,都需要有相应的软、硬件环境。比如,Java或Ruby的某个版本、外部数据库或者操作系统。这些环境的不同很可能会导致很多技术支持的电话。所以检查这些依赖关系,也是安装过程的一部分。
- 在没有询问并征得用户的同意之前,安装程序绝对不能删除用户的数据。
- 部署一个紧急修复的bug应该很简单,特别是在生产服务器的环境中。你知道这会发生,而且你不想在压力之下,在凌晨3点半,你还在手工部署系统。
- 用户应该可以安全并且完整地卸载安装程序,特别是在质量保证人员的机器环境中。
- 如果维护安装脚本变得很困难,那很可能是一个早期警告,预示着——很高的维护成本(或者不好的设计决策)。
- 如果你打算把持续部署系统和产品CD或者DVD刻录机连接到一起,你就可以自动地为每个构建制作出一个完整且有标签的光盘。任何人想要最新的构建,只要从架子上拿最上面的一张光盘安装即可。
使用演示获得频繁反馈
需求就像是流动的油墨。
你的客户的期望就像宇宙飞船的实际位置。软件开发的成功就在于最后你离客户的期望有多近。你计算的每个精确位置,就是一个给客户演示目前已经完成功能的机会,也正是得到用户反馈的时候。在你动身进入下一段旅程的时候,这些反馈可以用来纠正你的方向
如果你能与客户频繁协商,根据他们的反馈开发,每个人都可以从中受益。客户会清楚你的工作进度。反过来,他们也会提炼需求,然后趁热反馈到你的团队中。这样,他们就会基于自己进化的期望和理解为你导航,你编写的程序也就越来越接近他们的真实需求。客户也会基于可用的预算和时间,根据你们真实的工作进度,排列任务的优先级。
清晰可见的开发。在开发的时候,要保持应用可见(而且客户心中也要了解)。每隔一周或者两周,邀请所有的客户,给他们演示最新完成的功能,积极获得他们的反馈。
切身感受
《软件项目成功之道》
平衡的艺术
- 当你第一次试图用这种方法和客户一起工作的时候,也许他们被这么多的发布吓到了。所以,要让他们知道,这些都是内部的发布(演示),是为了他们自己的利益,不需要发布给全部的最终用户。
- 一些客户,也许会觉得没有时间应付每天、每周甚至是每两周的会议。毕竟,他们还有自己的全职工作。
所以要尊重客户的时间。如果客户只可以接受一个月一次会议,那么就定一个月。
- 一些客户的联络人的全职工作就是参加演示会议。他们巴不得每隔1小时就有一次演示和反馈。你会发现这么频繁的会议很难应付,而且还要开发代码让他们看。缩减次数,只有在你做完一些东西可以给他们演示的时候,大家才碰面。
- 演示是用来让客户提出反馈的,有助于驾驭项目的方向。如果缺少功能或者稳定性的时候,不应该拿来演示,那只能让人生气可以及早说明期望的功能:让客户知道,他们看到的是一个正在开发中的应已经完成的产品。
使用短迭代,增量发布
统一过程和敏捷方法都使用迭代和增量开发,使用增量开发,可一次开发应用功能的几个小组。每一轮的开发都是基于前一次的功能,增加为产品增值的新功能。这时,你就可以发布或者演示产品。
迭代开发是,在小且重复的周期里,你完成各种开发任务:分析、设计、实现、测试和获得反馈,所以叫作迭代。
给我一份详细的后期计划,我就会给你一个注定完蛋的项目。
大型系统更容易失败。它们通常不遵守迭代和增量开发的计划,或者迭代时间太长。
对付大项目,最理想的办法就是小步前进,这也是敏捷方法的核心。
大部分用户都是希望现在就有一个够用的软件,而不是在一年之后得到一个超级好的软件(可以参见《程序员修炼之道——从小工到专家》。
使用短迭代和增量开发,可以让开发者更加专注于自己的工作。
描述了敏捷项目主要的周期关系。根据项目的大小,理想的发布周期是几周到几个月。在每个增量开发周期里,应该使用短的迭代(不应该超过两周)。每个迭代都要有演示,选择可能提供反馈的用户,给他们每人一份最新的产品副本。
增量开发。发布带有最小却可用功能块的产品,每个增量开发中,使用1~4周左右迭代周期。
切身感受
短迭代让人感觉非常专注且具效率。你能看到一个实际并且确切的目标。
平衡的艺术
- 关于迭代时间长短一直是一个有争议的问题。Andy曾经遇到这样一位客户:他们坚持认为迭代就是4周的时间,因为这是他们学到的。但他们的团队却因为这样的步伐而垂死挣扎,因为他们无法在开发新的代码的同时又要维护很多已经完成了的代码。解决方案是,在每4周的迭代中间安排一周的维护任务。没有规定说迭代必须要紧挨着下一个迭代。
- 如果每个迭代的时间都不够用,要么是任务太大,要么是迭代的时间太短(这是平均数据,不要因为一次迭代的古怪情况而去调整迭代时间)。把握好自己的节奏。
- 如果发布的功能背离了用户的需要,那么多半是因为迭代的周期太长了。用户的需要、技术和我们对需求的理解,都会随着时间的推移而变化,在项目发布的时候,需要清楚地反映出这些变化。如果你发现自己工作时还带有过时的观点和陈腐的想法,那么很可能你等待太长时间做调整了。
- 增量的发布必须是可用的,并且能为用户提供价值。你怎么知道用户会觉得有价值呢?这当然要去问用户。
固定的价格就意味着背叛承诺
固定的价格就是保证要背叛承诺。软件项目天生就是变化无常的,不可重复。
如果你的客户一定要你预先确定项目的报价(比如政府合约),那么可能你需要研究些重型的评估技术,比如COCOMO模型或者功能点分析法(Function Point analysis)。
大部分项目都是业务应用,一个用户和另一个用户都有着巨大的差别。项目的发据和创造需要很多配合工作。或许你可以提供稍有不同的安排,试试下面的办法。
(1) 主动提议先构建系统最初的、小的和有用的部分(用建筑来打个比方,就是先做一个车库)。挑选一系列小的功能,这样完成第一次交付应该不多于6~8周。向客户解释,这时候还不是要完成所有的功能,而是要足够一次交付,并能让用户真正使用。
(2) 第一个迭代结束时客户有两个选择:可以选择一系列新的功能,继续进入下一个迭代或者可以取消合同,仅需支付第一个迭代的几周费用,他们要么把现在的成果扔掉,要么找其他的团队来完成它。
(3) 如果他们选择继续前进。那么这时候,应该就能很好地预测下一个迭代工作。在下一个迭代结束的时候,用户仍然有同样的选择机会:要么现在停止,要么继续下一个迭代。
对客户来说,这种方式的好处是项目不可能会死亡。他们可以很早地看到工作的进度(或者不足之处)。他们总是可以控制项目,可以随时停止项目,不需要缴纳任何的违约金。他们可以控制先完成哪些功能,并能精确地知道需要花费多少资金。总而言之,客户会承担更低的风险。
而你所做的就是在进行迭代和增量开发。
基于真实工作的评估。让团队和客户一起,真正地在当前项目中工作,做具体实际的评估。由客户控制他们要的功能和预算。
平衡的艺术
- 如果你对答案不满意,那么看看你是否可以改变问题。
- 如果你是在一个基于计划的非敏捷环境中工作,那么要么考虑一个基于计划且非敏捷的开发方法,要么换一个不同的环境。
- 如果你在完成第一个迭代开发之前,拒绝做任何评估,也许你会失去这个合同,让位于那些提供了评估的人,无论他们做了多么不切实际的承诺。
- 敏捷不是意味着“开始编码,我们最终会知道何时可以完成”。你仍然需要根据当前的知识和猜想,做一个大致的评估,解释如何才能到达这个目标,并给出误差范围。
- 如果你现在别无选择,你不得不提供一个固定的价格,那么你需要学到真正好的评估技巧。
- 也许你会考虑在合同中确定每个迭代的固定价格,但迭代的数量是可以商量的,它可以根据当前的工作状况进行调整。