敏捷的需求分析

交付用户想要的软件

让客户作决定

在设计方面,作决定的时候好必须有开发者参与。但是,在一个项目中,它们不该该作全部决定,特别是业务方面的决定。程序员

Decide what you shouldn’t decide.
开发者(及项目经理)能作的一个最重要的决定就是:判断哪些是本身决定不来的,应该让企业主作决定。你不须要本身给业务上的关键问题作决定。毕竟那不是你的事情。若是遇到了一个问题,会影响到系统的行为或者如何使用系统,把这个问题告诉业务负责人。若是项目领导或经理试图全权负责这些问题,要委婉地劝说他们,这些问题最好仍是和真正的业务负责人或客户商议。数据库

当你和客户讨论问题的时候,准备好几种可选择的方案。不是从技术的角度,而是从业务的角度,介绍每种方案的优缺点,以及潜在的成本和利益。和他们讨论每一个选择对时间和预算的影响,以及如何权衡。不管他们作出了什么决定,他们必须接受它,因此最好让他们了解一切以后再作这些决定。若是时候他们又想要其余的东西,能够公正地就成本和时间从新谈判。promise

毕竟,这是他们的决定。安全

具体技巧

  • 记录客户作出的决定,并注明缘由。好记性不如烂笔头,但你选择的记录方法不能太笨重或太繁琐。
  • 不要用过于具体和没有价值的问题打扰繁忙的业务人员。若是问题对他们的业务没有影响,就应该是没有价值的。
  • 不要随意假设具体的问题不会影响他们的业务。若是能影响他们的业务,就是有价值的问题。
  • 若是业务负责任回答“我不知道”,这也是一个趁心如意的答案。也许是他们尚未想到那么远,也许是他们只有看到运行的实物才能评估出结果。尽你所能为他们提供建议,实现代码的时候也要考虑可能出现的变化。

让设计指导而不是操纵开发

“设计”是软件开发过程不可缺乏的步骤。它帮助你理解系统的细节,理解不见和子系统之间的关系,而且指导你的实现。服务器

一些成熟的方法论很强调设计,他们但愿在开始编码以前,先有完整的设计和文档。另外一方面,敏捷方法建议你早在开发初期就开始编码。是否那就意味着没有设计呢?不,绝对不是,好的设计仍然十分重要。画关键工做图是必不可少的,由于要使用类及其交互关系来描述系统是如何组织的。在作设计的时候,你须要画时间去思考各类不一样选择的缺陷和益处,以及如何作权衡。架构

而后,下一步才考虑是否须要开始编码。若是你在前期没有考虑清楚这些问题,就草草地开始编码,极可能会被不少意料以外的问题搞晕。可是,即便以前已经提交了设计文档,也还会有一些意料以外的状况出现,时刻谨记,此阶段提出的设计知识基于你目前对需求的理解而已。一旦开始了编码,一切都会改变。设计及其代码实现会不停地发展和变化。框架

Design should be only as detailed as needed to implement.
严格的需求-设计-代码-测试开发流程源于理想化的瀑布式开发方法,它致使在前面进行了过分的设计。这样在项目的生命周期中,更新和维护这些详细的设计文档变成了主要工做,须要时间和资源方面的巨大投资,却只有不多的回报。ide

若是你本身都不清楚所谈论的东西,就根本不可能精确地描述它。
设计能够分红两层:战略和战术。前期的设计属于战略,一般只有在没有深刻理解需求的时候须要这样的设计。更确切地说,它应该只描述整体战略,不该深刻到程序方法、参数、字段和对象交互精确顺序的具体细节。那应该留到战术设计阶段,它应该在项目开发的时候再具体展开。这时更适合讨论如何设计类的职责。由于这仍然是一个高层次、面向目标的设计。事实上,CRC(类-职责-协做)卡片的设计方法就是用来作这个事情的。工具

如何知道一个设计上好的设计,或者正合适?代码很天然地为设计的好坏提供了最好的反馈。若是需求有了小的变化,它仍然容易去实现,那么它就是好的设计。而若是小的需求变化就带来了一大批基础代码的破坏,那么设计就须要改进。单元测试

具体技巧

  • “不要再前期作大量的设计”并非说不要设计,只是说在没有通过真正的代码验证以前,不要陷入太多的设计任务。当对设计一无所知的时候,投入编码也是一件危险的事。若是深刻编码只是为了学习或创造原型,只要你随后能把这些代码扔掉,那也是一个不错的办法。
  • 即便初始的设计到后面再也不管用,你仍需设计:设计行为说无价的。“计划说没有价值的,但计划的过程说必不可少的。”在设计过程当中学习说有价值的,但设计自己也许没有太大的用处。
  • 白板、草图、便利贴都是很是好的设计工具。复杂的建模工具只会让你分散精力,而不是启发你的工做。

合理地使用技术

Blindly picking a framework is the having kids to save taxes.
在考虑引入新技术或框架以前,先要把你须要解决的问题找出来。你的表述方式不一样,会让结果有很大差别。找到了须要解决的问题,接下来就要考虑:

  • 这个技术框架真能解决这个问题吗?要确保它能解决你的问题,并无任何的毒反作用。若是须要,先作一个小的原型。
  • 你将会被它拴住吗?有些技术缺少可取消性,当条件能发生变化时,这可能对项目有致命打击。咱们要考虑它时开放技术仍是专利技术,若是是开发的技术,那又开放到什么程度?
  • 维护成本是多少?会不会随着时间的推移,它的维护成本会很是昂贵?毕竟,方案的花费不该该高于要解决的问题,不然就是一次失败的投资。

具体技巧

  • 也许在项目中真正评估技术方案还为时太早。那就好。若是你在作系统原型并要演示给客户看,也许一个简单的散列表就能够代替数据库了。若是你尚未足够的经验,不要急于决定用什么技术。
  • 每一门技术都会有优势和缺点,不管它是开源的仍是商业产品、框架、工具或者语言,必定要清楚它的利弊。
  • 不要开发那些你容易下载到的东西。虽然有时须要从最基础开发全部你须要的东西,但那时至关危险和昂贵的。

提前集成,频繁集成

在产品的开发过程当中,集成是一个主要的风险区域。让你的子系统不停地增加,不去作系统集成,就等于一步一步把本身置于愈来愈大的风险中,潜在的分歧会继续增长。相反,尽量早地集成也更容易发现风险,这样风险及相关的代价就会至关低。而等的时间越长,你也就会越痛苦。

你能集成而且独立
集成和独立不是相互矛盾的,你能够一边进行集成,一边进行独立开发。
使用mock对象来隔离对象之间的依赖关系,这样在集成以前就能够先作测试。用一个mock对象模拟真实的对象(或者子系统)。mock对象就是真实对象的替身,它并不提供真实对象的功能,可是它更容易控制,可以模仿须要的行为,使测试更加简单。
你可使用mock对象,编写独立的单元测试,而不须要马上就集成和测试其余系统,只有当你自信它能工做的时候,才开始集成。

当早期就进行集成的时候,你会看到子系统之间的交互和影响,你就能够估算它们之间通讯和共享的信息数据。相反,若是你推迟集成的时间,解决这些问题就会变得很难,须要大量和大范围地修改代码,会形成项目延期和一片混乱。

具体技巧

  • 成功的集成就意味着全部的单元测试不停地经过。
  • 一般天天要和团队成员一块儿集成代码好几回,好比平均天天5~10次,甚至更多。但不要过于频繁了。
  • 若是你集成的问题很大,那必定是集成得不够频繁。
  • 对那些原型和实验代码,也许你想要独立开发,而不要想在集成上浪费时间。可是不能独立开发太长时间。一旦你有了经验,就要快速地开始集成。

保持能够发布

Checked-in code is always ready for action.
在团队里工做,修改一些东西的时候必须很谨慎。你要时刻经济,没错改动都会影响系统的状态和整个团队的工做效率。下面是一个简单的工做流程,能够防止你提交破坏系统的代码:

  • 在本地运行测试。先保证你完成的代码能够编译,而且能经过全部的单元测试。接着确保系统中的其余测试均可以经过。
  • 检出最新的代码。从版本控制系统中更新代码到最新的版本,再变异和运行测试。这样每每会发现让你吃惊的事情:其余人提交的代码和你的代码发生了冲突。
  • 提交代码。

最好的办法是你有一个持续集成系统,能够自动集成并报告集成结果。持续集成系统就是在后台不停地检出、构建和测试代码的应用。你能够本身使用脚本快速实现这样的方式,但若是你选择已有的免费、开源的解决方案,它们会提供更多的功能且更加稳定。

具体技巧

  • 有时候,作一些大的改动后,你没法花费太多的时间和精力去保证系统一直能够发布。若是总共须要一个月的时间才能保证它一周以内能够发布,那就算了。但这只应该是例外,不能养成习惯。
  • 若是你不得不让系统常去不能够发布,那就作一个(代码和架构的)分支版本,你能够继续进行本身的实验,若是不行,还能够撤销,从头再来。千万不能让系统既不能够发布又不能够撤销。

提前实现自动化部署

系统能在你的机器上运行,或者能在开发者和测试人员对机器上运行,固然很好。可是它同时也须要可以部署在用户的机器上,若是系统能运行在开发服务器上,那很好,可是它同时也要运行在生产环境中。

QA should test deployment.
这就意味着,你要能用一种可重复和可靠的方式,在目标机器上部署你的应用。若是如今你仍是手工帮助质量保证人员安装应用,花一些时间,考虑如何将安装过程自动化。这样只要用户须要,你就能够随时为它们安装系统。要提前实现它,这样让质量保证团队既能够测试应用,又能够测试安装过程。

有了自动化部署系统后,在项目开发的整个过程当中,会更容易适应互相依赖的变化。极可能你在安装系统的时候,会忘记添加须要的库或组建——在任意一台机器上运行自动化安装程序,你很快就会知道什么丢失了。

从第一天起就开始交付
一开始就进行全面部署,而不是等到项目的后期,这会有不少好处。事实上,有些项目在正式开发以前,就设置好了全部的安装环境。
在咱们公司,要求你们为预期客户实现一个简单的功能演示——验证一个概念的可行性。即便项目尚未正式开始,咱们就有了单元测试、持续集成和基于窗口的安装程序。这样,咱们就能够更容易更简单地给用户交互这个演示系统。
在签约以前,就能提供出如此强大的演示,这无疑证实了咱们很是专业,具备强大的开发能力。

具体技巧

  • 通常产品在安装的时候,都须要有相应的软硬件环境。这些环境的不一样极可能致使不少技术支持的电话。因此检查这些依赖关系,也是安装过程的一部分。
  • 在没有询问并征得用户的赞成以前,安装程序绝对不能删除用户的数据
  • 部署一个紧急修复的Bug应该很简单,特别是在生产服务器的环境中。你不想在压力之下,凌晨三点半还在手工部署系统。
  • 用户应该能够安全而且完整地卸载安装程序,特别是在质量保证人员的机器环境中。
  • 若是维护安装脚本变得很困难,那极可能是一个早起警告,预示着很高的维护成本。
  • 若是你打算把持续部署系统和产品CD或者DVD刻录机链接到一块儿,你就能够自动地为每一个构建制做出一个完整且有标签的光盘。任何人想要最新的构建,只要从架子上拿最上面的一张光盘安装便可。

使用演示得到频繁反馈

Requirements are as fluid as ink.
没有人的思想和观点能够及时冻结,特别是项目的客户。就算算他们已经告诉你想要的东西了,他们的指望和想法仍是在不停地进化——特别是当他们在使用新系统的部分功能时,他们才开始意识到它的影响和可能发生的问题。这就是人的本性。

此处省略了数值分析中偏微分方程的例子……

应该按期地,每隔一段时间,例如一个迭代,就与客户会晤,而且演示已经完成的功能特性。若是你能与客户频繁协商,根据他们的反馈开发,每一个人均可以从中受益。客户会清楚你的工做进度。反过来,他们也会提炼需求,而后趁热反馈到你的团队中。这样,他们就会基于本身进化到指望和理解为你导航,你编写的程序也就愈来愈接近他们的真实需求。客户也会基于可用的预算和时间,根据大家真实的工做进度,排列任务的优先级。

维护项目术语表(Wiki规格)
不一致的术语是致使需求误解的一个主要缘由。企业喜欢用看似普通浅显的词语来表达很是具体、深入的意义。
团队中的程序员们使用了和用户或者业务人员不一样的术语,最后由于“阻抗失调”致使Bug和设计错误。这样的事情常常发生。
为了不这类问题,需维护一份项目术语表。人们应该能够公开访问它,通常是在企业内部网或者Wiki上。
在项目开发过程当中,从术语表中为程序结构——类、方法、模型、变量等选择合适的名字,而且要检查和确保这些定义一直符合用户的指望。

跟踪问题(工做项)
随着项目的进展,你会获得不少反馈——修正、建议、变动要求、功能加强、Bug修复等。要注意的信息不少,随机的邮件和潦草的告示帖上没法应付的。因此,要有一个跟踪系统记录全部这些日志。

具体技巧

  • 当你第一次试图用这种方法和客户一块儿工做的时候,也许他们被这么多的发布吓到了。因此,要让他们知道,这些都是内部的发布(演示),时为了他们本身的利益,不须要发布给全面的最终用户。
  • 一些客户,也许会以为没有时间应付天天、每周甚至时每两周的回忆。毕竟,他们还有本身的全职工做。因此要尊重客户的时间。若是客户只能够接受一个月一次会议,那么就定一个月。
  • 一些客户的联络人的全职工做就是参加演示会议。他们恨不得每隔一小时就有一次演示和反馈。你会发现这么频繁的回忆很难应付,并且还要开发代码让他们看。缩减次数,只有在你作完一些东西能够给他们演示的时候,你们才碰面。
  • 演示时用来让客户反馈的,有助于驾驭项目的方向。若是缺乏功能或者稳定性的时候,不该该拿来演示,那只能让人生气。能够及早说明指望的功能:让客户知道,他们看到的是一个正在开发中的应用,而不是一个最终已经完成的产品。

使用短迭代,增量发布

统一过程和敏捷方法都使用迭代和增量开发。使用增量开发,可一次开发应用功能的几个小组。每一轮的开发都是基于前一次的功能,增长为产品增值的新功能。这时你就能够发布或者演示产品。

迭代开发式是,你在小且重复的周期里完成各类开发任务:分析、设计、实现、测试和得到反馈,因此叫作迭代。

Show me a detailed long-term plan and I will show you a project that’s doomed.
对付大项目最理想的办法就是小步前进,这也是敏捷方法的核心。大步跳跃大大的增长了风险,小步前进才能够帮助你很好地把握平衡。

大部分用户都但愿如今就有一个够用的软件,而不是在一年以后,获得一个超级的好软件,肯定使产品可用的核心功能,而后把它们放在生产环境中,越早找到用户的手里越好。

询问用户哪些是产品可用且必不可少的核心功能,不要为全部可能须要的华丽功能而分心,不要沉迷于你的想象而去作那些华而不实的用户界面。有一堆的理由,值得你尽快把软件交到用户手中:只要交到用户手里,你就有了收入,这样就有更好的理由,继续为产品投资了。从用户那里获得的反馈会让咱们进一步理解什么是用户真正想要的,以及下一步该实现哪些功能。也许你会发现一些过去认为重要的功能,如今已经再也不重要了。

使用短迭代和增量开发可让开发者更加专一于本身的工做,若是别人告诉你有一年的时间来完成系统,你会以为时间很长,若是目标很遥远,又很难让本身去专一于他。在这个快节奏的社会,咱们都但愿更快地获得结果,但愿更快的见到有形的东西。这不必定是坏事。相反,他会使一件好事,只要把它转换成生产率和正面的反馈。

具体技巧

  • 关于迭代时间长短一直是一个很是有争议的问题,没有规定说迭代必需要紧挨着下一个迭代。
  • 若是每一个迭代的时间都不够用,要么上任务太大,要么是迭代的时间过短,把握好本身的节奏。
  • 若是发布的功能背离了用户的须要,多半是由于迭代的周期太长了。用户的须要、技术和咱们对需求的理解都会随着时间的推移而变化,在项目发布的时候,须要清楚地反映出这些变化。若是你发现本身工做时还带有过期的观点和陈腐的想法,那么极可能你等待太长时间作调整了。
  • 增量的发布必须是可用的,而且能为用户提供价值,你怎么知道用户会以为有价值呢?这固然要去问用户。

固定的价格就意味着背叛承诺

A fixed price guarantees a broken promise.
固订价格的合同会是敏捷团队的一大难题,咱们一直在讨论如何用持续、迭代和增量的方式工做。可是如今却有些人跑过来,想提前知道他会花费多少时间及多少成本。软件项目,天生就是变化无常的,不可重复。若是要提早给出一个固定的价格,就几乎确定不能遵照开发上的承诺。

根据本身的处境,选择不一样的战略。

  1. 主动提议先构建系统最初的、小的和有用的部分,挑选一系列小的功能,这样完成第一次交付差很少六到八周。向客户解释,这时候还不是要完成全部的功能,而是要足够一次交付,并能让用户真正使用。
  2. 第一个迭代结束时,客户有两个选择:能够选择一系列新的功能,继续进入下一个迭代;或者能够取消合同,仅需支付第一个迭代的几周费用。他们要么把如今的成果扔掉要么找其余的团队来完成它。
  3. 若是他们选择继续前进,那么这时候,应该就能很好地预测下一个迭代工做。在下一次迭代结束的时候,用户仍然有一样的选择机会:要么如今中止,要么继续下一个迭代。

对客户来讲,这种方式的好处是项目不可能会死亡。他们能够很早的看到工做的进度或者不足之处。他们老是能够控制项目,能够随时中止项目,不须要缴纳任何违约金。他们能够控制先完成哪些功能,并能精确的知道须要花费多少资金。总而言之客户会承担更低的风险。

具体技巧

  • 若是你对答案不满意,那么看看你是否能够改变问题。
  • 若是你是在一个基于计划的非敏捷环境中中工做,那么要么考虑一个基于计划且非敏捷的开发方法,要么换一个不一样的环境。
  • 若是你在完成第一个迭代开发以前,拒绝作任何评估,也许你会失去这个合同,让位于那些提供了评估的人,不管他们作了多么不切实际的承诺。
  • 敏捷不是意味着开始编码,咱们最终会知道什么时候能够完成,你仍然须要根据当前的知识和猜测,作一个大体的评估,解释如何才能到达这个目标,并给出偏差范围。
  • 若是你如今别无选择,你不得不提供一个固定的价格,那么你须要学到真正好的评估技巧。
  • 也许你会考虑在合同中肯定每一个迭代的固订价格,但迭代的数量是能够商量的,它能够根据当前的工做情况进行调整。
相关文章
相关标签/搜索