2.3 开发方法
讨论了高质量软件开发的原则和许多有助于达到这些原则的习惯后,我们将学习在Java开发工作中使用的实用方法。
有这样一个笑话,“开发方法和恐怖分子之间有什么不同?区别是您可以同恐怖分子谈判!”这个笑话讽刺了一个非常现实的问题。我们总是认为开发方法必须考虑到开发生命周期中可能出现的所有情况,并且必须一直坚持——否则它就不会生效。当然,所有的开发方法都应该根据具体的开发场景进行调整,但是在调整一个开发方法前您必须要了解这个方法的细节。
对于开发方法的完整探讨和比较超出了本书的范围,下面只简单介绍一些当今常用的方法。
2.3.1 瀑布方法
所有软件开发方法都源自瀑布方法(waterfall methodology)。它之所以被称为瀑布方法是因为开发模块相互之间是依次流动的,如图2-2所示。
瀑布方法由以控制闸门分隔的一系列活动组成。这些控制闸门决定着一个给定的活动是否已经完成并可以进入下一个活动。需求阶段处理所有软件需求的有关问题。设计阶段,顾名思义,决定整个系统的设计。然后在代码阶段编写代码。之后测试代码。最后,发布产品。
对瀑布模型最主要的批评是它获得反馈所需的时间太长。正如上文所说,软件的某些部分很容易理解,而另一些则相反。因此,当用户对于手边出现的问题没有很好地理解的时候,试图先完成所有的需求分析(也就是说,将需求量化到实际的规格说明中)是非常困难的。进一步说,如果在需求分析中出现一个错误,它就会传播到设计阶段、代码等。同时,流程中一般没有办法返回到上一个阶段。因此,如果到了测试阶段发现设计的一部分无法工作,那么在完成时,您进行修改以修复该问题,而这会失去设计活动的所有上下文环境。

图2-2
认识到这个问题后,瀑布方法被修改为其他几种形式,例如螺旋式方法(spiral methodology),它只不过是使用了多个瀑布模型。这种方法缩短了生命周期的时间;也就是说,为解决问题提供了迭代的解决方案。
最终,您无法脱离瀑布方法,因为它确实是最常规的方法。首先,您要决定将要构建的内容,然后决定将要如何构建这些内容,接下来实际构建这些内容,最后您要确保自己确实构建了所需的东西(并且可以成功运行)。下面介绍的两个方法之间主要的不同在于每次构建时需要付出的代价。
2.3.2 统一流程
统一流程(Unified Process,UP)由几个面向对象的开发方法合并而来。统一流程要求基于系统最重要的方面实施短期迭代开发,如图2-3所示。[LARMAN]

图2-3
进行用例(use case)调查(即对用户与系统交互的简短描述),开始排除那些可能影响整个系统成功的用例。只要合适,就可以在整个开发过程中从调查中添加或删除用例。图2-3所显示的几个阶段定义和度量了系统的相对成熟度。
统一流程4个阶段的定义如下:
● 起始(Inception):系统仍然处于决定系统范围的阶段——系统要执行哪些操作、系统的边界是什么。如果系统能够很好地被理解,那么这个阶段将非常短。
● 细化(Elaboration):减少系统的结构性风险。可以用一句话来表示该阶段:“您解决了所有难题了吗?”或者“您知道如何完成您想完成的事情吗?”
● 构造(Construction):完成所有相关的用例,准备好系统的Beta版本。
● 移交(Transition):使系统通过最后的发布阶段和Beta版本。它包括软件操作和维护。
这是一个关注于维护要素的敏捷流程,但是仍然采用了大量用例开发、建模等方面的传统实践。下一个方法学也是一个敏捷流程,但在如何实现上具有不同的关注点。
2.3.3 极限编程
Kent Beck在《eXtreme Programming eXplained》一书中向软件开发社区介绍了一个激进的新方法。基于他在克莱斯勒汽车公司所实施的项目开发的经验,他提出了开发过程中以代码为中心的方法。
让用户描述系统应该如何工作,并基于相对重要性对这些描述进行排序。这样便为团队提供了一个描述集合,可以在一个给定的迭代中(大约两周时间——每周工作40个小时)完成它们。为每个描述分配一个两人的工作小组,在代码被编写时提供确定数量的内置对等评审。您和您的同伴在编写源代码的同时编写单元测试。在完成自己负责的那段代码后,将其拿到集成的机器上,放入代码基线,运行从所有人的代码中收集来的单元测试。每次迭代后,您应该提供一个运行系统,使用户可以评审以确保您的工作满足他们的需求。整个过程如图2-4所示。
注意,极限编程并没有将软件的设计作为重点。相反,它认为那些前期的设计对于整个系统开发不是很有帮助,它们随着实际开发的进行总是会被修改。
极限编程对于需要持续提供运行系统的软件开发来说非常适合,但在缺少用户介入或者项目规模很大(有50位或更多的开发人员)时不太好用,此时协调和设计活动更加有用。
极限编程灵活迅速,合理地考虑了开发团队的能力,从而使您能够有效地制定计划,避免了工程师的超负荷工作,避免了客户的不满。
2.3.4 关于方法的评价
回顾一下上面三种不同的方法,可以得出以下几点结论:
● 本质上,每种方法都能完成任务,应根据您在每个开发活动中定位的开发范围采用不同的方法。
● 敏捷的方法(比如统一流程和极限编程)关注积极响应而不是放任自流。也就是说,它们试图评估成功并不断调整努力的方向,而不依赖于瀑布控制闸门的通过和失败状态。
● 各种方法在对设计阶段的重要性和需要的配备(例如UML建模工具等)方面各不相同。瀑布流程认为设计阶段非常重要,而统一流程根据在迭代中对系统设计的定位来认识其重要性。极限编程认为编码就是设计,所有额外的工作都是围绕假定的场景构建的,而假定的场景实际上并不存在于系统功能性中。毕竟,您是在编码实现实际的用户描述。
● 所有这些方法都认识到用例的重要性,但是它们从不同的方面来定位用例。瀑布方法将用例看成是生成显式系统需求的工具,提供背景信息。统一流程将用例作为重要的清单。调查报告包含了对每个用例的简单解释,并且依赖它们在每次迭代中构建其设计模型。极限编程则是直接基于开发来满足所谓的用户描述,它们在形式上有了更多的内容,实际上同调查报告没有本质区别。

图2-4
没有包治百病的方法。正如同2.2节中提到的,确定您和您的团队的流程,从而实现软件构建所定位的需求是非常重要的。本节主要向您提供当今软件开发中一些常见方法的背景知识,下一节将讨论在实际开发场景上下文环境中软件开发的一些常用工具。
posted on
浙公网安备 33010602011771号