敏捷软件开发:原则、模式与实践(C#版·修订版)(txt+pdf+epub+mobi电子书下载)


发布时间:2020-06-22 13:29:52

点击下载

作者:[美]RobertC.MartinMicahMartin著

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

敏捷软件开发:原则、模式与实践(C#版·修订版)

敏捷软件开发:原则、模式与实践(C#版·修订版)试读:

前言

可是Bob,你说过去年就能写完这本书的。

——Claudia Frers,1999年UML World大会

Bob的引言

离Claudia说出这句合情合理的抱怨已经7年了,不过我觉得我已经做出了补偿。在这几年里,我出版了3本书,对于一个同时经营着一家咨询公司,并且还得进行大量的代码编写、培训、指导、演讲的工作,以及撰写文章、专栏和博客的人来讲,要每隔一年出一本书是一项很大的挑战,更不要说还得养活并陪伴一个大家庭了。但是,我喜欢这样。

敏捷开发(Agile Development)就是指能够在需求迅速变化的情况下快速开发软件。为了达到这种敏捷性,我们需要使用一些实践提供必要的准则和反馈,需要使用一些设计原则使我们的软件保持灵活且可维护,还需要理解一些已经被证明在特定问题中可以权衡这些原则的设计模式。本书试图将这3个概念融汇起来,使它们成为有机的整体。

本书首先描述了这些原则、模式以及实践,然后通过许多案例来演示如何应用它们。更重要的是,案例给出的并不是最终的结果,而是设计的过程。你会看到设计者犯错误;你会看到他们如何找到错误并最终改正;你会看到他们对问题苦思冥想,面对一些难以权衡的含糊问题的疑惑与探索。是的,你会看到设计的真正历程。

Micah的引言

2005年初,我参与到一个小的开发团队中,该团队正准备用C#开发一个.NET应用程序。使用敏捷开发实践是团队的强制性规定,这也是我参与其中的原因之一。虽然我以前曾经使用过C#,但是我的大部分编程经验都是基于Java和C++的。我认为.NET不会有什么不同,结果也表明确实如此。

项目开始两个月后,我们进行了第一次发布。这是一次部分发布,其中只包含了所有计划特性中的一部分,但却是完全可用的,并且也确实被投入使用。仅仅两个月公司就得到了我们开发的软件带来的好处。管理层非常兴奋,他们要求雇佣更多的人,这样就可以启动更多的项目。

我投身到敏捷社区已经有几年了,我认识很多可以帮助我们的敏捷开发者。我通知了他们每一个人,请求他们加入到我们中来。结果,没有一个敏捷朋友加入我们的团队。为什么?也许最主要的原因是我们是基于.NET进行开发的。

几乎所有敏捷开发者都具有Java、C++或者Smalltalk方面的背景。几乎从来没有听说过有敏捷.NET程序员。也许,当我说我们正在使用.NET进行敏捷软件开发时,我的那些朋友根本就没当回事,也许他们想避免和.NET有什么瓜葛。这是一个严重的问题。我已经不止一次看到这种情况了。

我讲过许多为期一周的关于各种软件主题的课程,有机会见到来自世界各地的具有广泛代表性的开发者。我曾经指导过的很多学生都是.NET程序员,也有很多是Java和C++程序员。恕我直言:在我的经历中,.NET程序员常常要比Java和C++程序员差一些。当然,也并非总是如此。但是,通过在课堂中的再三观察,我只能得出这样的结论:在敏捷软件实践、设计模式、设计原则等方面,.NET程序员往往要弱一些。在我的课堂上,.NET程序员常常从来没有听说过这些基本概念。必须改变这种情况。

本书的另一版本,由我父亲Robert C.Martin撰写的Agile Software Development:Principles,Patterns,and Practices在2002年末出版,并赢得了2003年的Jolt大奖。那是一本很好的书,得到了许多开发者的赞扬。遗憾的是,它对.NET社区几乎没有提供什么帮助。尽管书中的内容同样适用于.NET,但是几乎没有.NET程序员读过它。

我希望这本.NET版本能够充当.NET社区和其他开发者社区之间的桥梁。我希望程序员能够阅读它并看到更好的构建软件的方法。我希望他们开始使用更好的软件实践、创建更好的设计并提升.NET应用的质量标准。我希望.NET程序员可以和其他程序员一样好。我希望.NET程序员能够在软件社区中获得新的地位,这样Java程序员就会以加入.NET团队为荣。

在完成本书的整个过程中,对于是否把我的名字放在一本与.NET有关的图书的封面上,我有过多次思想斗争。我曾问自己是否要把名字和.NET联系在一起,并承担可能由此带来的所有负面后果,但现在我不再迟疑了。我是一名.NET程序员。不!是一名敏捷的.NET程序员。我以此为荣。

关于本书

本书简史

20世纪90年代初,我(Bob)写了一本名为Designing Object-Oriented C++ Application using the Booch Method的书。它曾是我的代表作,其效果和销量都让我非常高兴。

这本书最初想作为Designing一书的第2版,但是结果却并非如此。书中所保留的原书内容非常少,只有3章内容,即便这3章也进行了大量的修改,但书的意图、精神以及许多知识是相同的。自Desinging出版10年以来,在软件设计和开发方面我又学到了非常多的知识,这些将在本书中表现出来。

10年过去了!Designing刚好在因特网大发展之前出版。从那时起,我们使用的缩略词的数量已经翻了一倍,诸如EJB、RMI、J2EE、XML、XSLT、HTML、ASP、JSP、ZOPE、SOAP、C#、.NET以及设计模式、Java、Servelet和应用服务器。我要告诉你,要使这本书的内容跟得上最新技术潮流非常困难。

与Booch的关系

1997年,Booch与我联系,让我帮他撰写其非常成功的Object-Oriented Analysis and Design with Applications一书的第3版。以前,我和他在一些项目中有过合作,并且是他的许多作品(包括UML)的热心读者和参编者。因此,我高兴地接受了,并邀请我的好朋友Jim Newkirk来帮助完成这项工作。

在接下来的两年中,我和Jim为Booch的书撰写了许多章节。当然,这些工作意味着我不可能按照我本来想的那样投入大量精力写作本书,但是我觉得Booch的书值得我这样做。另外,当时这本书完全只是Designing的第2版,并且我的心思也不在其上。如果我要讲些东西的话,我想讲些新的并且是不同的东西。

遗憾的是,Booch著作的这个版本始终没有完成。在正常情况下已经很难抽出空来写书了,在浮躁的.com泡沫时期,就更加不可能了。Grady忙于Rational以及Catapulse等新公司的事务。因此这项工作就停止了。最后,我问Grady和Addison-Wesley公司是否可以把我和Jim撰写的那些章节包含在本书中,他们很慷慨地同意了。于是,一些案例研究和UML的章节就由此而来。

极限编程的影响

1998年后期,极限编程(XP)崭露头角,它有力地冲击了我们所信奉的关于软件开发的观念。我们是应该在编写任何代码前先画许多UML图呢?还是应该不使用任何UML图而仅仅编写大量代码?我们是应该撰写大量描述我们设计的叙述性文档?还是应该努力使代码具有自释义能力以及表达力,免除撰写辅助性文档的必要?我们应该结对编程吗?我们应该在编写产品代码前先编写测试吗?我们应该做什么呢?

这场变革来得正是时候。在20世纪90年代中后期,Object Mentor公司在面向对象设计以及项目管理问题上帮助了许多公司。我们帮助这些公司完成项目,在此过程中,我们慢慢地向这些公司灌输自己的一些观点和做法。遗憾的是,这些观点和做法没有被记录下来,它们只是我们对客户的口述。

到了1998年,我认识到需要把我们的过程和实践写下来,这样就可以更好地把它们传达给我们的客户。于是,我在C++ Report上撰写了许多关于过程的论文[1],但这些文章都没有达到目的。它们提供了丰富的信息并且在某些情况下也很引人入胜,但是它们没有系统地反映我们在项目中实际应用的实践和看法,而是对影响我数十年的价值观念的一种不经意的放弃。Kent Beck向我指出了这一点。

与Kent Beck的关系

1998年末,当我正为整理Object-Mentor过程烦恼时,我偶然看到了Kent在极限编程(XP)方面的一些文字。这些文字散布在Ward Cunningham的wiki[2]中,并且和其他一些人的文字混合在一起。尽管如此,通过努力我还是抓住了Kent 所谈论的要点。这激起了我极大的兴趣,但是仍有一些疑虑。XP中的某些东西和我的开发过程观念完全吻合,但是其他一些东西,比如缺乏明确的设计阶段,却令我迷惑不解。

我和Kent来自完全不同的软件环境。他是一个知名的Smalltalk顾问,而我却是一个知名的C++顾问。这两个领域之间很难相互交流。这之间几乎有一个库恩式的(Kuhnian)[3]范型隔阂。

如果不是看到他的观点,我绝无可能邀请Kent为C++Report撰写论文。但是我们关于过程认识上的一致填补了语言上的隔阂。1999年2月,我在慕尼黑的OOP会议上遇到了Kent。他在进行关于XP的讲演,而我在进行面向对象设计原则的讲演,我们的会场所正好面对面。由于无法听到他的讲演,我就在午餐时找到了Kent。我们谈论了XP,我邀请他为C++Report撰写了一篇论文。这是一篇很棒的论文,其中描述了Kent和一位同事在一小时左右的现场系统开发中所进行的彻底的设计改变。

在接下来的几个月中,我逐渐消除了自己对XP的担心。我最大的担心在于所采用的过程中没有一个明显的预先设计阶段,我对此有些犹豫。我不是一直在教导我的客户以及整个行业,设计非常重要,应该投入时间吗?

最后我认识到,实际上我自己也并不真正需要这样一个阶段。甚至在我撰写的所有关于设计、Booch图和UML图的论文以及图书中,总是把代码作为验证这些图是否有意义的一种方式。在我所有的客户咨询项目中,我会先花费1~2个小时帮助他们绘制一些图,然后会使用代码来指导他们考查这些图。我开始明白,虽然XP关于设计的措词有点陌生(在库恩式的意义上),但是这些措词背后的实践对我来说却很熟悉。

我关于XP的另一个担心相对比较容易解决。我私底下实际上一直是一个结对程序员。XP使我可以光明正大地和同伴沉醉于一起编程的快乐之中。重构、持续集成以及现场客户对我来说都非常熟悉。它们都非常接近于我先前对客户建议的工作方式。

有一个XP实践对我来说是新的发现。当你第一次听到测试驱动开发[4](TDD)时会觉得它似乎很平常。它只是要在编写任何产品代码前先编写测试用例。编写的所有产品代码都是为了让失败的测试用例通过。对于这种方式编写代码所带来的意义深远的结果,我始料未及。这个实践完全改变了我编写软件的方法,并把它变得更好了。

于是,到1999年秋天,我确信Object Mentor应该采用XP作为自己的过程,并且我应该放弃编写自己过程的愿望。Kent在表达XP的实践和过程方面已经做了一项卓越的工作,相比起来我自己那些不充分的尝试就显得苍白无力了。

.NET

在几个大公司之间一直在进行着一场战争。这些公司在为了赢得你的忠诚而战。这些公司相信,如果它们拥有了语言,那么它们将拥有程序员以及雇佣这些程序员的公司。

首先打响这场战争的是Java。Java是第一个由大公司创造的用来赢得程序员的编程语言。结果取得了极大的成功。Java确实深深地扎根于软件开发社团中,并成为现代多层IT应用开发的事实标准。

对此的还击之一来自IBM。IBM通过Eclipse开发环境占领了大部分的Java市场。另外一个对此的重大阻击来自微软的一些追求完美的设计者,他们给我们提供了通用的.NET平台和特定的C#语言。

令人惊异的是,很难对Java和C#做出区分。这两种语言在语义上是等同的,并且语法也非常相似,以至于许多代码片段都可以写得很相似。所有在技术创新上的不足,微软都通过其在能力上的卓越表现进行了超额的补偿,并赶超上来,赢得胜利。

本书的第一版是使用Java和C++作为编程语言编写的。本书使用了C#和.NET平台。不要把这看作是对某一方的支持。我们不会在这场战争中拥护某一方。事实上,我认为当几年后一种更好的语言出现并占领了参与交战的公司花费巨大代价赢得的程序员意向份额时,这场战争就会自行结束。

本书的.NET版本只是为了能够影响到.NET程序员。虽然本书中的原则、模式和实践与语言无关,但是案例研究却与语言相关。正如.NET程序员更加乐于阅读.NET案例研究一样,Java程序员则更加乐于阅读Java示例。

尽在细节中

本书包含了许多.NET代码。希望你能够仔细阅读它们,因为在很大程度上,代码正是本书的精髓。代码是本书所讲内容的实际体现。

本书采用重复讲解的方式,由一系列不同规模的案例研究组成。有些案例非常小,有些案例则需要用几章来描述。每个案例研究之前都有一些预备材料,其中讲述了在该案例研究中将用到的面向对象设计原则和模式。

本书首先讨论了开发实践和过程,其中穿插了许多小的案例研究以及示例。然后,我们转移到设计和设计原则的主题上,接着是一些设计模式、更多管理包的设计原则以及更多的模式。所有这些主题都附有案例研究。

因此,请准备好学习一些代码和UML(统一建模语言)图。你将要学习的图书技术性非常强,其中要教授的知识就像恶魔一样,尽在细节中[5]。

本书的内容结构

本书由四个部分和两个附录组成。

第一部分:敏捷开发。本部分描述了敏捷开发的概念。首先介绍了敏捷联盟宣言,然后提供了对极限编程(XP)的概述,接着讨论了许多阐明个别极限编程实践的小案例,特别是那些影响设计和编写代码方式的实践。

第二部分:敏捷设计。本部分中的各章谈论了面向对象软件设计:什么是面向对象软件设计,管理复杂性的问题以及技术,面向对象类设计的一些原则。本部分最后几章讲述UML实用子集。

第三部分:薪水支付案例研究。它描述了一个简单的批量处理薪水支付系统的面向对象设计和C#实现。本部分的前几章描述了该案例研究会用到的一些设计模式。最后一章包含了完整的案例研究,这也是本书中最大和最完整的一个案例。

第四部分:打包薪水支付系统。本部分开始描述面向对象包设计的一些原则。接着,通过增量地打包上一部分中的类来继续阐明这些原则。本部分最后讲述薪水支付应用的数据库和UI设计。

接下来是两个附录:附录A,“双公司记”;附录B,Jack Reeves的文章“什么是软件”。

如何使用本书

如果你是一名开发人员,请从头至尾阅读本书。本书主要是写给开发人员的,它包含以敏捷方式开发软件所需要的信息。从头至尾阅读可以首先学习实践,接着是原则,然后是模式,最后是把它们全部联系起来的案例研究。把所有这些知识整合起来会帮助你完成项目。

如果你是一名管理人员或者业务分析师,请阅读第一部分“敏捷开发”。第1章~第6章提供了对敏捷原则和实践的深入讨论。内容涉及需求、计划、测试、重构以及编程。它会给你一些有关如何构建团队以及管理项目的指导,帮助你完成项目。

如果你想学习UML,请首先阅读第13章~第19章。然后,阅读第三部分“薪水支付案例研究”的所有章节。这种阅读方法在UML语法和使用方面会给你提供一个好的基础,同时也会帮助你在UML和C#语言之间进行转换。

如果你想学习设计模式,请先阅读第二部分“敏捷设计”学习设计原则,然后阅读第三部分“薪水支付案例研究”、第四部分“打包薪水支付系统”。这几部分定义了所有的模式,并且展示了如何在典型的情形中使用它们。

如果你想学习面向对象设计原则,请阅读第二部分“敏捷设计”、第三部分“薪水支付案例研究”以及第四部分“打包薪水支付系统”。这些章节将会描述面向对象设计的原则,并且向你展示如何使用这些原则。

如果你想学习敏捷开发方法,请阅读第一部分“敏捷开发”。这部分描述了敏捷开发,内容涉及需求、计划、测试、重构以及编程。

如果你只想笑一笑,请阅读附录A“双公司记”。

致谢

衷心感谢以下人士:Lowell Lindstrom、Brian Button、Erik Meade、Mike Hill、Michael Feathers、Jim Newkirk、Micah Martin、Angelique Martin、Susan Rosso、Talisha Jefferson、Ron Jeffries、Kent Beck、Jeff Langr、David Farber、Bob Koss、James Grenning、Lance Welter、Pascal Roy、Martin Fowler、John Goodsen、Alan Apt、Paul Hodgetts、Phil Markgraf、Pete McBreen、H.S.Lahman、Dave Harris、James Kanze、Mark Webster、Chris Biegay、Alan Francis、Jessica D’Amico、Chris Guzikowski、Paul Petralia、Michelle Housley、David Chelimsky、Paul Pagel、Tim Ottinger、Christoffer Hedgate以及Neil Roodyn。

非常感谢Grady Booch和Paul Becker允许我在本书中使用原本用于Grady的Object-Oriented Analysis and Design with Applications第3版中的章节。特别感谢Jack Reeves,他慷慨地允许我全文引用他的论文“什么是软件设计”(What Is Software Design?)。

每章开头处美妙的、偶尔还有些炫目的插图是Jennifer Kohnke和我的女儿Angela Brooks绘制的。[1].这些论文可以在http://www.object.mentor.com的publications部分找到,共有4篇。前3篇名为:Iterative and Incremental Development(I,II,III)。最后一篇名为:C.O.D.E Culled Object Development Process。[2].http://c2.com/cgi/wiki。这个网站中包含有数量众多的涉及各种各样主题的论文,论文作者成百上千。人们都说,只有Ward Cunningham才能使用几行Perl煽动一场社会革命。[3].写于1995~2001年的任何可信的学术作品中肯定使用了术语Kuhnian。它指的是The Structure of Scientific Revolutions一书,作者为Thomas S.Kuhn,由芝加哥大学出版社出版于1962年。[库恩是美国著名科学史家和哲学家,在其代表作《科学革命的结构》一书中提出了“范型转换”(paradigm shift)理论。——编者注][4].Kent Beck,Test-Driven Development by Example,Addison-Wesley,2003。[5].原文为The devils are in the details,谚语,相当于韩非子所说的“千里之堤,溃于蚁穴”,比喻细节之重要。——编者注第一部分敏捷开发

人与人之间的交互是复杂的,并且其效果从来都难以预期,但是它们却是工作中最为重要的方面。

——Tom DeMarco和Timothy Lister,《人件》

原则(principle)、模式(pattern)和实践(practice)都是重要的,但是使它们发挥作用的是人。正如Alistair Cockburn所说的:“过程和技术对于项目的结果只有次要的影响。首要的影响是人。”[1]

如果把程序员团队看作是由过程驱动的组件(component)所组成的系统,那么就无法对他们进行管理。用Alistair Cockburn的话来说,人不是“插入即兼容的编程装置。”如果想要项目取得成功,我们就必须构建起具有合作精神的、自组织(self-organizing)的团队。

鼓励构建这种团队的公司比认为软件开发组织不过是由无关紧要的、雷同的一群人堆砌起来的公司更具竞争优势。凝聚在一起的软件团队是最强大的软件开发力量。第1章敏捷实践

教堂尖顶上的风标,即使由钢铁制成,如果不懂得顺应风势的艺术,一样会很快被暴风所摧毁。

——海因里希·海涅,德国诗人

许多人都经历过由于没有实践的指导而导致的项目噩梦。缺乏有效的实践会导致不可预测性、重复的错误以及努力白白浪费。延期的进度、增长的预算和低劣的质量致使客户对我们丧失信心。更长时间的工作却生产出更加低劣的软件产品,也使得开发人员感到沮丧。

一旦经历了这样的惨败,就会害怕重蹈覆辙。这种恐惧激发我们创建一个过程来约束我们的活动,并要求某些输出和制品(artifact)。我们根据过去的经验来规定这些约束和输出,挑选那些在以前的项目中看起来好像工作得不错的方法。我们希望这些方法这次还会有效,从而消除我们的恐惧。

然而,项目并没有简单到使用一些约束和制品就能够可靠地防止错误的地步。当连续地犯错误时,我们会对错误进行诊断,并在过程中增加更多的约束和制品来防止以后重犯这样的错误。经过多个项目以后,我们就会不堪巨大、笨重的过程的重负,极大地削弱我们完成项目的能力。

一个大而笨重的过程会产生它本来企图去避免的问题。它降低了团队的开发效率,使得进度延期,预算超支。它降低了团队的响应能力,使得团队经常创建错误的产品。遗憾的是,这导致许多团队认为,这种结果是因为他们没有采用足够多的过程方法引起的。因此,在这种失控的过程膨胀中,过程会变得越来越庞大。

用失控的过程膨胀来描述公元2000年前后许多软件公司中的情形是很合适的。虽然有很多团队在工作中并没有使用过程方法,但是采用庞大、重型的过程方法的趋势却在迅速增长,在大公司中尤其如此。1.1 敏捷联盟

2001年初,由于看到许多公司的软件团队陷入了不断增长的过程的泥潭,一批业界专家聚集在一起概括出了一些可以让软件开发团队具有快速工作和响应变化能力的价值观和原则。他们称自己为敏捷联盟。在随后的几个月中,他们创建出了一份价值观声明,也就是敏捷联盟宣言(The Manifesto of the Agile Alliance)。

敏捷软件开发宣言

我们正在通过亲身实践以及帮助他人实践,揭示更好的软件开发方法。

通过这项工作,我们认为:

人和交互  重于  过程和工具

可以工作的软件  重于  面面俱到的文档

客户合作  重于  合同谈判

随时应对变化  重于  遵循计划

虽然右项也有其价值,但我们认为左项更加重要。

Kent Beck     Mike Beedle   Arie van Bennekum  Alistair Cockburn

Ward Cunningham  Martin Fowler  James Grenning   Jim Highsmith

Andrew Hunt   Ron Jeffries   Jon Kern      Brian Marick

Robert C.Martin  Steve Mellor   Ken Schwaber    Jeff Sutherland

Dave Thomas1.1.1 人和交互重于过程和工具

人是获得成功的最为重要的因素。如果团队中没有优秀的成员,那么就算是使用好的过程也不能从失败中挽救项目。但是,不好的过程却可以使最优秀的团队成员失去效用。如果不能作为一个团队进行工作,那么即使拥有一批优秀的成员也一样会惨败。

一个优秀的团队成员未必就是一个一流的程序员。一个优秀的团队成员可能是一个具有一般水平的程序员,但是却能够很好地与他人合作。好的合作(沟通以及交互)能力要比单纯的编程能力更为重要。一个由一般水平的、具有良好沟通能力的程序员组成的团队,比那些拥有一批高水平的程序员,但是成员之间却不能进行交流的团队更有可能获得成功。

合适的工具对于成功来说非常重要。像编译器、IDE和源代码控制系统等,对于团队的开发者正确地完成他们的工作至关重要。然而,工具的作用可能会被过分地夸大。使用过多庞大、笨重的工具就像缺少工具一样,都是不好的。

我的建议是从使用小工具开始。尝试一个工具,直到发现它无法适用时才去更换它。不要急着去购买那些先进的、价格昂贵的源代码控制系统,相反应该先使用一个免费的系统,直到能够证明该系统已经不再适用。在决定为团队购买最好的CASE工具许可证前,先使用白板和方格纸,直到明确地知道需要更多的功能。在决定使用庞大的、高性能的数据库系统前,先使用平面文件(flat file)。不要认为更大的、更好的工具可以自动地帮你做得更好。通常,它们造成的障碍要大于带来的帮助。

记住,团队的构建要比环境的构建重要得多。许多团队和管理者就犯了先构建环境,然后期望团队自动凝聚在一起的错误。相反,应该首先致力于构建团队,然后再让团队基于需要来配置环境。1.1.2 可以工作的软件重于面面俱到的文档

没有文档的软件是一种灾难。代码不是交流系统原理和结构的理想媒介。团队更需要编制容易看懂的文档,来对系统及其设计决策的依据进行描述。

然而,过多的文档比过少的文档更糟。编制众多的文档需要花费大量的时间,并且使这些文档和代码保持同步,要花费更多的时间。如果文档和代码之间失去同步,那么文档就会变成庞大的、复杂的谎言,会造成重大的误导。

对于团队来说,编写并维护一份系统原理和结构方面的文档总是一个好主意,但是那份文档应该短小并且主题突出。短小的意思是说,最多有一二十页。主题突出的意思是说,应该仅论述系统的最高层结构和概括的设计原理。

如果我们拥有的仅仅是一份简短的系统原理和结构方面的文档,那么如何来培训新的团队成员,使他们能够从事系统相关的工作呢?我们会非常密切地和他们一起工作。我们紧挨着他们坐下来帮助他们,把我们的知识传授给他们。我们通过频繁的培训和交互使他们成为团队的一部分。

在向新的团队成员传授知识方面,最好的两份文档是代码和团队。代码真实地表达了它所做的事情。虽然从代码中提取系统的原理和结构信息可能是困难的,但是代码是唯一没有二义性的信息源。在团队成员的头脑中,保存着时常变化的系统的脉络图。人和人之间的交互是比把这份脉络图记在纸上并传授给他人更快、更有效的方式。

许多团队因为注重文档而非软件,从而导致进度拖延。这常常是一个致命的缺陷。有一个简单规则可以预防该缺陷的发生。

Martin文档第一定律(Martin’s First Law of Documentation)

直到迫切需要并且意义重大时,才编制文档。1.1.3 客户合作重于合同谈判

不能像订购日用品一样来订购软件。你不能够仅仅写下一份关于你想要的软件的描述,然后就让人在固定的时间内以固定的价格去开发它。所有用这种方式来对待软件项目的尝试都将以失败而告终。有时,失败是惨重的。

告诉开发团队想要的东西,然后期望开发团队消失一段时间回来后就能够交付一个满足需要的系统,这对于公司的管理者来说是具有诱惑力的。然而,这种操作模式将导致低劣的质量和失败。

成功的项目需要定期且频繁的客户反馈。不是依赖于合同或者关于工作的陈述,而是让软件的客户和开发团队密切地工作在一起,并尽量经常地提供反馈。

一个指明了需求、进度以及项目成本的合同存在根本的缺陷。在大多数情况下,合同中规定的条款远在项目完成之前(有时甚至是远在合同签署之前)就变得没有意义。那些为开发团队和客户的协同工作方式提供指导的合同才是最好的合同。

我在1994年为一个大型、需要多年才能完成并有50万行代码的项目达成的合同,可以作为一个成功合同的样例。作为开发团队的我们,每个月的报酬相对是比较低的。大部分的报酬要在我们交付了某些大的功能块后才支付。那些功能块没有在合同中详细地指明。合同中仅仅规定在一个功能块通过了客户的验收测试时才支付该功能块的报酬。那些验收测试的细节并没有在合同中指明。

在这个项目开发期间,我们和客户紧密地工作在一起。几乎每个周五,我们都会把软件提交给客户。到下一周的周一或者周二,客户会给我们一份关于软件的变更列表。我们会把这些变更放在一起排定优先级,然后把它们安排在随后几周的工作中。客户和我们如此紧密地工作在一起,以至于验收测试根本就不是问题。因为他们周复一周地观察着每个功能块的演进,所以他们知道何时这个功能块能够满足他们的需要。

这个项目的需求基本处于一个持续变化的状态。大的变更是很平常的。在这期间,也会出现整个功能块被去掉,而另外的功能块被加进来的情况。然而,合同和项目都经受住了这些变更,并获得成功。成功的关键在于与客户的紧密协作,并且合同指导了这种协作,而不是试图去规定项目范围的细节和固定成本下的进度。1.1.4 随时应对变化重于遵循计划

随时应对变化的能力常常决定着一个软件项目的成败。当我们构建计划时,应该确保计划是灵活的,并且易于适应商务和技术方面的变化。

计划不能考虑得过远。首先,商务环境很可能会变化,这会引起需求的变动。其次,一旦客户看到系统开始运作,他们很可能会改变需求。最后,即使我们知道需求是什么,并且确信它们不会改变,我们仍然不能很好地估算出开发它们需要的时间。

对于一个缺乏经验的管理者来说,创建一张优美的、关于整个项目的PERT或者甘特图,并把它贴到墙上是很有诱惑力的。他们也许觉得这张图赋予了他们对项目的控制权。他们能够跟踪单个人的任务,并在任务完成时将任务从图上去除。他们可以将实际完成的日期和计划完成的日期进行比较,并对出现的任何偏差做出反应。

然而,实际会发生的是:这张图的组织结构不再适用。当团队对于系统有了新认识,当客户对于需求有了新认识,图中的某些任务会变得没有必要。另外一些任务会被发现并增加到图中。简而言之,计划图的形状(shape)将会改变,而不仅仅是日期上的改变。

较好的做计划的策略是:为下一周做详细的计划,为下3个月做粗略的计划,再以后就做极为简略的计划。我们应该清楚地知道下周要完成的任务,粗略地了解一下以后3个月要实现的需求。至于系统一年后将要做什么,有一个模糊的想法就行了。

计划中这种逐渐降低的细致度,意味着我们仅仅对于迫切的任务才花费时间进行详细的计划。一旦制定了这个详细的计划,就很难进行改变,因为团队会根据这个计划启动工作并有相应的投入。然而,由于该计划仅仅支配了一周的时间,计划的其余部分仍然保持着灵活性。1.2 原则

从上述的价值观中引出了下面的12条原则,它们是敏捷实践区别于重型过程的特征所在。

(1) 我们最优先要做的是通过尽早地、持续地交付有价值的软件来使客户满意。《MIT Sloan管理评论》杂志刊登过一篇论文,分析了对于公司构建高质量产品方面有帮助的软件开发实践[2]。该论文总结了很多对于最终系统质量有重要影响的实践。其中一个实践表明,尽早交付具有部分功能的系统和系统质量之间具有很强的相关性。该论文指出,初期交付的系统中所包含的功能越少,最终交付的系统的质量就越高。该论文的另一项发现是,以逐渐增加功能的方式经常性地交付系统和最终质量之间有非常强的相关性。交付得越频繁,最终产品的质量就越高。

敏捷实践会尽早地、经常地进行交付。我们努力在项目刚开始的几周内就交付一个具有基本功能的系统。然后,我们努力坚持每几周就交付一个功能渐增的系统。如果客户认为目前的功能已经足够了,客户可以选择把这些系统加入到产品中。或者,他们可以只是选择再检查一遍已有的功能,并指出他们想要做的改变。

(2) 我们欢迎需求的变化,即使到了开发后期。敏捷过程能够驾驭变化,为客户创造竞争优势。这是一个关于态度的声明。敏捷过程的参与者不惧怕变化。他们认为改变需求是好事情,因为那些改变意味着团队已经学到了更多如何满足客户需要的知识。

敏捷团队会非常努力地保持软件结构的灵活性,这样当需求变化时,对于系统造成的影响是最小的。在本书的后面部分,我们会学习一些面向对象设计的原则、模式和实践,这些内容会帮助我们维持这种灵活性。

(3) 经常交付可以工作的软件,从几个星期到几个月,时间间隔越短越好。我们交付可以工作的软件,并且尽早地、经常性地交付它。我们不赞成交付大量的文档或者计划。我们认为那些不是真正要交付的东西。我们关注的目标是交付满足客户需要的软件。

(4) 在整个项目开发期间,业务人员和开发人员必须朝夕工作在一起。为了能够以敏捷的方式进行项目的开发,客户、开发人员以及利益相关者之间就必须要进行有意义的、频繁的交互。软件项目不像发射出去就能够自动导航的武器,必须要对软件项目持续不断地进行引导。

(5) 依靠斗志高昂的人构建项目。给他们提供所需的环境和支持,并且信任他们能够完成工作。人是项目取得成功的最重要的因素。所有其他的因素(过程、环境、管理等)都被认为是次要的,当它们对人有负面的影响时,就要对它们进行改变。

(6) 在团队内部,最有效率也最有效果的信息传达方式,就是面对面的交谈。在敏捷项目中,人们之间相互交谈。首要的沟通方式就是人与人之间的交互。书面文档会按照和软件一样的时间安排进行编写和更新,但是仅在需要时才这样做。

(7) 可以工作的软件是进度主要的度量标准。敏捷项目通过度量当前满足客户需求的软件量来度量开发进度。他们不是根据所处的开发阶段、已经编写的文档总量或者已经创建的基础设施代码的数量来度量开发进度。仅当30%的必需功能可以工作时,才可以确定进度完成了30%。

(8) 敏捷过程提倡可持续开发。出资人、开发者和用户应该总是保持稳定的开发速度。敏捷项目不是 米短跑;而是马拉松长跑。团队不是以全速启动并试图在项目开发期间维持那个速度;相反,他们以快速但是可持续的速度行进。

跑得过快会导致团队精力耗尽、抄捷径以致崩溃。敏捷团队会测量他们自己的速度。他们不允许自己过于疲惫。他们不会借用明天的精力来在今天多完成一点工作。他们工作在一个可以保证在整个项目开发期间保持最高质量标准的速度上。

(9) 对卓越技术和良好设计的不断追求有助于提高敏捷性。高的产品质量是获取高的开发速度的关键。保持软件尽可能干净、健壮是快速开发软件的途径。因而,所有的敏捷团队成员都致力于只编写他们能够编写的最高质量的代码。他们不会制造混乱然后告诉自己等有更多的时间时再来清理它们。如果他们在今天制造了混乱,就会在今天把混乱清理干净。

(10) 简单——尽量减少工作量的艺术是至关重要的。敏捷团队不会试图去构建那些华而不实的系统,他们总是更愿意采用和目标一致的最简单的方法。他们并不看重对于明天会出现的问题的预测,也不会在今天就对那些问题进行防卫。相反,他们在今天以最高的质量完成最简单的工作,并深信如果在明天发生了问题,也会很容易进行处理。

(11) 最好的构架、需求和设计都源自自我组织的团队。敏捷团队是自我组织的团队。责任不是从外部分配给单个团队成员,而是分配给整个团队,然后再由团队来确定履行职责的最好方法。

敏捷团队的成员共同来解决项目中所有方面的问题。每一个成员都具有项目中所有方面的参与权力。不存在某个团队成员仅对系统构架、需求或者测试负责的情况。整个团队共同承担那些职责,每一个团队成员都能够影响它们。

(12) 每隔一定时间,团队都要总结如何更有效率,然后相应地调整自己的行为。敏捷团队会不断地对团队的组织方式、规则、约定和关系等进行调整。敏捷团队知道团队所处的环境在不断地变化,并且知道为了保持团队的敏捷性,就必须要随环境一起变化。1.3 结论

每一个软件开发人员、每一个开发团队的职业目标,都是给他们的雇主和客户交付最大可能的价值。可是,我们的项目令人沮丧地失败了,或者未能交付任何价值。虽然在项目中采用过程方法是出于好意,但是膨胀的过程方法对于我们的失败至少是应该负一些责任的。敏捷软件开发的原则和价值观构成了一个可以帮助团队打破过程膨胀循环的方法,这个方法关注的是可以达到团队目标的一些简单的技术。

在撰写本书的时候,已经有许多的敏捷过程可供选择,包括SCRUM[3]、Crystal[4]、特征驱动软件开发[5](Feature-Driven Development,FDD)、自适应软件开发[6](Adaptive Software Development, ADP)以及极限编程[7](Extreme Programming,XP)。不过,绝大多数成功的敏捷团队都是从所有这些过程方法中汲取知识并调和成最适合自己的方法。常见的做法是把SCRUM和XP结合起来,其中使用SCRUM实践来管理多个使用XP实践的团队。1.4 参考文献

[Beck99]Kent Beck,Extreme Programming Explained:Embrace Change,Addison-Wesley,1999.

[Highsmith2000]James A.Highsmith,Adaptive Software Development:A Collaborative Approach to Managing Complex Systems,Dorset House,2000.

[Newkirk2001] James Newkirk and Robert C.Martin,Extreme Programming in Practice,Addison-Wesley,2001.第2章极限编程概述

作为开发人员,我们应该记住,XP并非唯一选择。

——Pete McBreen,软件技术专家

在第1章中,我们概述了有关敏捷软件开发方法方面的内容,但它没有确切地告诉我们去做些什么;其中给出了一些泛泛的陈述和目标,却没有给出实际的指导方法。本章要改变这种状况。2.1 极限编程实践2.1.1 完整团队

我们希望客户、管理者和开发人员紧密地工作在一起,以便于彼此知晓对方所面临的问题,并共同去解决这些问题。谁是客户?XP团队中的客户是指定义产品的特性并排列这些特性优先级的人或者团体。有时,客户是和开发人员同属一家公司的一组业务分析师、质量保证专家和/或者市场专家。有时,客户是用户团体委派的用户代表。有时,客户是真正支付开发费用的人。但是在XP项目中,无论谁是客户,他们都是能够和团队一起工作的团队成员。

最好的情况是客户和开发人员在同一个房间中工作,次一点的情况是客户和开发人员之间的工作距离在100m以内。距离越大,客户就越难成为真正的团队成员。如果客户工作在另外一幢建筑或另外一个城市,那么他将会很难融合到团队中来。

如果确实无法和客户工作在一起,该怎么办呢?我的建议是去寻找能够在一起工作、愿意并能够代替真正客户的人。2.1.2 用户故事

为了进行项目计划,必须要了解需求,但是却无需了解得太多。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载