敏捷软件开发(珍藏版)
上QQ阅读APP看书,第一时间看更新

前言

1999年,UML WORLD的克劳迪亚(Claudia Frers)调侃说:“老兄,你说过去年写完这本书的。”

敏捷开发是一种面对迅速变化的需求,快速开发软件的能力。为了获得这种敏捷性,我们需要使用一些可以提供必要纪律和反馈的实践。我们需要使用一些可以保持我们的软件灵活且可维护的设计原则,并且我们需要知道一些已经被证明针对特定的问题可以平衡这些原则的设计模式。本书试图把所有这三个概念编织在一起,使其成为一个有机的整体。

本书首先描述了这些原则、模式以及实践,然后通过学习一些案例来演示它们的具体应用。更重要的是,案例介绍的并不是最终完成的结果,而是我们的设计过程。你会看到设计者犯的错误;你会看到他们如何识别并最终改正错误;你会看到他们如何对难题进行苦思冥想以及如何进行权衡,如何苦恼于含糊不清的问题;你会看到设计的艺术。

细节之美

本书包含许多的Java和C++代码。我希望你仔细学习这些代码,因为在很大程度上,代码才是本书的要旨。代码是本书主题的具体实现。

本书采用一种重复的讲解方式。它由一系列不同规模的案例组成。有一些非常小,有一些却需要用好几章的篇幅来描述。每个案例之前都有一些有针对性的预备内容。例如,在薪水支付案例之前,就有一些章节在描述该案例中用到的面向对象设计原则和模式。

本书首先对开发实践和过程进行讨论,穿插了许多小的案例研究以及示例。然后话锋一转,谈论敏捷设计和设计原则,接着介绍一些设计模式、更多包管理的设计原则以及模式。所有这些主题都附有案例。

因此,请准备好阅读一些代码并钻研一些UML图。这本书技术性很强,要讲的知识点都隐藏在细节中,细节是魔鬼。

本书前传

大约在6年前,我写过一本书,书名为《C++面向对象程序设计:Booch方法》。这是我的一部重要作品,影响力和销量都让我感到非常满意。

本书原本是它的第2版。但事与愿违,能够保留下来的内容非常少。本书只保留了其中三章内容,而且还有大幅度的修改。但两本书的意图、精神主旨和许多知识是相通的。但在《C++面向对象程序设计》出版后的6年,我在软件设计方面又学到了非常多的知识,这些都体现在这本书中。

再说,《C++面向对象程序设计》出版于互联网爆炸式流行的前夕。此后,软件行业的新名词在数量上已经翻了一倍,设计模式、Java、EJB、RMI、J2EE、XML、XSLT、HTML、ASP、JSP、Servlets、Application Servers、ZOPE、SOAP、C#和.NET等,多得让人眼花缭乱。把这些最近进展更新到那本书里是很困难的。

与Booch合作

1997年,Booch找到我,他写过一本非常成功的书,书名为《面向对象程序分析与设计》,邀请我和他一起写第3版。我之前和他有过一些合作,也是他很多作品(包括UML)的热心读者和参与者。于是,我愉快地答应了。我还邀请我的好友Jim Newkirk一起参与完成这项工作。

在接下来的两年,我们俩写了好几章的内容。当然,这些成果意味着我不可能在把自己的精力全部放在这本书上,但我觉得他的书值得我这样做。另外,当时我的计划也是写自己那本《C++面向对象程序设计》的第2版,所以也不怎么上心。如果我要阐明一些东西的话,当然是想说一些新颖的。

糟糕的是,Booch的第3版并没有写成。正常时间本来就很难抽出时间来写书。更何况在浮躁的互联网泡沫时代。Booch自己也忙于Rational和Capapulse等新的风投事务。就这样,写书的事情就停下来了。最后,我问Booch和出版社是否可以把我们写好的几章加入自己的书中。他们很有风度地同意了。我们这本书里面的一些案例和UML的章节就是这样来的。

极限编程的影响

1998年末,XP崭露头角并向我们所珍爱的对软件开发的信仰发起挑战。应该在写代码前创建大量UML图,还是应该避开任何种类的UML图直接写大量的代码?应该写大量的叙述性文档去描述设计,还是应该努力让代码本身就有解释能力和表现力,不需要借助于文档?该不该结对编程?要不要在写产品代码前写测试?我们应该怎么做?

说实话,我是凑巧接触到这次革命的。20世纪90年代中后期,Object Mentor公司帮助许多公司解决了面向对象(OO)设计和项目管理问题。我们帮助他们完成了很多项目。在合作过程中,我们慢慢向团队灌输我们自己的一些看法和实践。糟糕的是,这些看法和实践没有被记录下来,只是从我们这一侧口头传给另一侧的客户。

到了1998年,我意识到我们需要把我们的过程和实践写下来,以便更好地传达给客户。于是,我在C++ Report1写了许多关于过程的文章。这些文章信息丰富,并且在某些情况下也很引人入胜,这些内容并不是对项目实际应用和看法的整理,而是在不经意间偏离了影响过我几十年的价值观。这是旁观者Kent Beck看出来的。

与Kent合作

1998年末,当时我正为整理Object-Mentor的过程而烦恼时,偶然接触到Kent在极限编程(eXtreme Programming, XP)方面的一些著述。这些内容散布在维基(1)并与其他一些人的文字混在一起。尽管如此,通过一些努力,我还是抓住了他想要表达的重点。这激起了我相当大的兴趣,但仍然有一些困惑。XP中的某些东西和我的开发过程观念完全吻合,但其他一些东西,比如缺乏明确的设计阶段,让我感到困惑不解。

我和Kent来自完全不同的软件环境。他是公认的Smalltalk顾问,我却是大家公认的C++顾问。这两个领域很难交流,貌似存在着库恩(2)思维范式的隔阂。

在其他情况下,我绝对不会邀请他为C++ Report写文章。但我们对过程的共识填补了编程语言上的隔阂。1999年2月,我在慕尼黑的OOP会议上遇到他。他演讲的主题是XP,我的演讲主题是面向对象设计原则,我们俩的会场正好面对面。由于没法听他的演讲,所以我就在午餐时找到他。我们谈了XP,然后我邀请他为C++ Report写篇文章。他写的这篇文章很棒,描述了他和一位同事如何在1小时左右的时间里对一个真实的系统进行彻底的设计改变。

在接下来的几个月,我按顺序整理并按顺序整理了一下我对XP的顾虑。我最大的顾虑是XP软件过程中没有显式的预先设计阶段。对此,我有些犹豫。难道我没有义务让我的客户乃至整个行业明白设计是值得花时间的吗?

最后,我认识到我自己其实也没有设计这个阶段。甚至在我写的所有关于设计、Booch图和UML图的文章和书籍中,也总是把代码作为验证这些图是否有意义的一种方式。在我所有的咨询项目中,我会先花一两个小时帮他们绘一些图,然后用代码来指导他们查验这些图。我开始明白了,虽然XP对设计的措辞有些陌生(在库恩式的意义上(3)),但具体实践却是我很熟悉的。

我对XP的另一个担心倒非常容易消除。实际上,我本人一直是结对编程的拥趸和实践者。XP使我可以光明正大地和同伴一起沉浸于编程的乐趣中。重构、持续集成以及在客户现场工作,都让我非常容易“入戏”,它们都非常接近于我先前建议客户采用的工作方式。

有一个XP实践对我来说是个新发现。当你第一次听到测试优先的软件设计时,会觉得它似乎很平常。它指出,在写任何产品代码之前,要先写测试用例。写的所有产品代码都是为了让失败的测试用例能够得以通过。我最开始并没有预料到这种编码方式所带来的深远意义。测试先行,这个实践完全改变了我写软件的方式,让我变得更好。在本书中,你可以看出这个变化。书中有些代码写于1999年以前。这些代码都是没有测试用例的。但是,所有写于1999年之后的代码都带有测试用例,并且测试用例一般都是先出现的。我相信你会注意到这些不同。

就这样,到1999年秋天,我确信Object Mentor应该选用XP,并且,我要放弃自己写软件过程的想法。在表述XP实践和过程方面,Kent已经做了相当出色卓越的工作,相比之下,我自己原来那些不充分的尝试显得有些苍白无力。

本书的组织结构

● 第Ⅰ部分“敏捷开发”描述敏捷开发的概念。介绍敏捷宣言之后后,对极限编程进行概述,接着讨论很多关于个体极限编程实践的小案例——特别是那些影响我们设计和编码方式的实践。

● 第Ⅱ部分“敏捷设计”谈论面向对象软件设计。首先提出问题,阐述了什么是设计。接下来讨论管理复杂性的问题和技术。最后,阐述面向对象类设计的一些原则。

● 第Ⅲ部分“薪水支付系统”是本书最大并且也最完整的案例。它描述一个简单的批处理薪水支付系统的面向对象设计和C++的实现。前几章描述该案例使用的一些设计模式。最后两章包含完整的案例学习。

● 第Ⅳ部分“打包薪水支付系统”首先描述面向对象包设计的一些原则,接着把前面一部分中提到的类进行打包,借此来阐明这些原则。

● 第Ⅴ部分“气象站案例”包含一个原本打算放入Booch那本书第3版的案例。气象站案例描述的是一个公司做出了一项重要的业务决策,阐明Java开发团队对此所做出的反应。还描述了要用到的一些设计模式以及设计和实现。

● 第VI部分“ETS案例”描述作者亲自参与的一个真实项目。该项目在1999年就已经产品化,是一个自动考试系统,美国注册建筑师委员会的注册考试的答题和评分系统。

● 附录 前两个附录包含用来描述UML表示法的几个案例。另外还有几个附录。

如何使用本书

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

● 如果你是一名管理人员或者业务分析师……请阅读第Ⅰ部分。这部分对敏捷原则和实践进行深入的讨论。内容涉及需求、计划、测试、重构以及编程。它会指导你构建团队和管理项目,指导最后完成项目。

● 如果你想学习UML……请首先阅读附录A,接着阅读附录B,然后阅读第Ⅲ部分。这种阅读方式可以帮助你掌握UML语法和用法。还可以帮助你自如地在UML和Java或C++等编程语言之间进行转换。

● 如果你想学习设计模式……要想找到一个特定的模式,可以使用“设计模式列表”找到自己感兴趣的模式。要想在总体上学习模式,请阅读第Ⅱ部分,学习设计原则,然后阅读第Ⅲ部分、第Ⅳ部分、第Ⅴ部分以及第VI部分。这些部分定义了所有模式及其典型的应用场景。

● 如果你想学习面向对象设计原则……请阅读第Ⅱ部分、第Ⅲ部分和及第Ⅳ部分。这几个部分描述了面向对象设计的原则及其用法。

● 如果你想学习敏捷开发方法……请阅读第Ⅰ部分。这部分描述的是敏捷开发,内容涉及需求、计划、测试、重构和编程。

● 如果你只是想笑一笑,看个热闹先……请阅读附录C,了解形成鲜明对比的两家公司。

资源

本书中的所有源代码可以从https://github.com/unclebob/PPP下载。


(1)http://c2.com/cgi/wiki,该网站中包含数量众多且涉及各种主题的论文。作者人数破千。据说,只有沃德·坎宁安(Ward Cunningham)才能使用几行Perl代码发起一场社会变革。坎宁安是计算机程序员,也是维基之父,设计模式和敏捷软件方法的先驱之一。他从普度大学获得交叉学科工学学士学位以及计算机科学的硕士学位。1995年,他在波特兰模式知识库创建了第一个维基站点,致力于“人、项目和模式”。

(2)写于1995至2001年之间的任何可信的学术作品中肯定使用过术语“Kuhnian”。它指的是《科学革命的结构》一书,作者是托马斯·库恩,芝加哥大学出版社1962年出版。

(3)如果你在一篇文章中提到过两次库恩,就会有更高的可信度。