本文来自 Rational Edge :一个理想的迭代开发方法模型在很多方面与理想的瀑布开发模型有着根本上的不同。但是,从实际来说,没有一个团队严格的应用了每一种开发方法模型。本文解释了为什么开发团队决定逐步的从类似瀑布型的开发方法转变成更加类似迭代开发的方法,同时也概述了能够帮助这种转变的步骤。
实际上,多数的开发团队使用了改进了的 瀑布型开发方法,他们将项目分解成为两个或者更多的部分,有时这些部分被称为阶段或者是时期。这种改良可以帮助简化集成、使测试人员更早的进行测试工作和提供更早的项目状态的观测。这种方法也将代码分解成了易于管理的片断并最小化了以存根和驱动程序形式的、被测试需要的代码集成。此外这种方法允许你原型化你认为有风险的或者有难度的部分,并且使用来自每一个阶段的反馈修改你的设计。然而,使用瀑布型开发方法的执行与想象是相反的:很多设计团队把在阶段 1 之后的修改设计视为他们的最初设计或者需求过程的失败。虽然一个改进了的瀑布型开发方法并不排除反馈的使用,但是它并没有促进、支持和鼓励反馈的使用。最后,想要最小化风险就不要典型的驱动一个瀑布型的开发项目。对于软件开发过程来说,本文探索了”迭代“开发方法超越传统的瀑布型开发方法的进步。 相比较而言,迭代开发方法 以 IBM 的 Rational 统一过程 ®,或者 RUP ®为例 包括了一系列的增量的步骤或者迭代。每一个迭代都包括一些或者很多的开发活动(需求、分析、设计、实现等等),就像你在图 1 中看到的那样。每一个迭代也有一系列良好定义的目标并生成最终系统的部分工作实现。每个后续的迭代都建立在前一个迭代的基础上以使系统得到发展和细化,直到最终产品被完成。 早期的迭代着重于需求、分析和设计;后期的迭代着重于实现和测试。
图 1: RUP 的迭代开发。每一个迭代都包括需求、分析、设计、实现和测试活动。同时,每个迭代都建立在前一个迭代工作的基础上,每一次迭代都会生成更加接近最终产品的可执行版本。 迭代开发方法已经证明了自己优于瀑布型的开发方法,理由如下:
一些项目经理反抗采用迭代的开发方法,将迭代开发视为一种没有尽头的、不可控的形式。然而,在 RUP 中,这个项目是能够被很好的控制的。迭代的次数、周期和目标被仔细的计划;并且项目参与者的任务和角色被良好的定义。此外,进展的客观量度应该能够被获取。虽然团队要从一个迭代到下一个迭代中重做一些事情,但是这个工作也是可以被仔细的控制的。
多数的瀑布型的项目将开发工作划分为阶段或者时期;我们也可以将这个划分视为向迭代方法转换的第一步。但是为了实现向迭代开发方法的过渡,我们要使用下面四个步骤来应用不同的过程原则:
让我们来更进一步的解释每一个步骤。 作为向迭代开发转换的第一步,在需求和设计阶段考虑一个或者更多的功能原型。这些原型的目标是减少主要的技术风险和澄清项目涉众对系统应该做什么的理解。 通过识别最重要的三个技术风险和最重要的三个有必要澄清的功能部分开始。技术风险也许与新技术、对整个方案影响很多的未决定的技术选择或者你知道的很难满足的技术需求有关。功能上的风险也许与项目涉众为关键的功能性提供了模糊的需求或者几个需求对项目系统都是核心的有关。 对于每一个重要的技术风险,拟订你要原型化什么以减少风险。考虑一下下面的例子: 技术风险: 项目需要将一个已存在的应用移植到 IBM WebSphere Application Server 上运行。用户已经开始抱怨应用的性能,并且你所担心的是移植后也许性能会更加的慢。 原型: 构建一个架构的原型来找出移植你的应用的不同方法。要求一个专家级的 WebSphere 架构师来帮助你。评价结果并编写架构的和设计的指导方针为开发团队提供什么 应该做和什么 不应该做。这将增加你移植的应用的性能是足够好的以避免在项目后期返工的可能性。 技术风险: 你正在为安排和估计软件项目构建一个新的应用。你知道对于这个应用和购买的软件的关键区分将是如何能够很好的支持迭代计划。然而,这也是在你的需求说明中最模糊的部分之一。 原型: 基于你关于如何支持迭代项目计划的设想构建一个功能原型。通过向不同的项目涉中演示原型,你将可以鼓励他们更加注意项目的计划,并且他们能够告诉你他们对你的哪些设想是赞同的、哪些是不赞同的。原型将帮助你澄清计划的需求,也能够为你提供关于用户体验和对于你的应用的外表和感觉的有用的信息。这个原型甚至能够产生一些可重用的代码。
很多项目团队发现在他们知道项目是真正关于什么的之前划分一个项目成为有意义的迭代是困难的。但是,当你已经进入了详细设计阶段时,你通常对需求是什么和系统的架构看起来象什么样子有了很好的理解。这是我们试验迭代开发的时候了! 你能够使用两个主要的方法来确定你应该在什么样的迭代中作些什么事情。让我们从正反两方面讨论一下每一个方法。 方法 1 :同时开发一个或者多个子系统。让我们假设你有九个子系统,每一个都有数量日益增加的组件。你可以划分详细设计、实现和测试阶段到三个迭代中,每个迭代瞄准实现九个子系统中的三个。如果在不同的子系统之间存在有限的依赖这将工作的相当的好。例如,如果你的九个子系统的每一个都为用户提供良好定义的一系列能力,你可以在第一个迭代中开发优先级最高的子系统,其次重要的子系统在第二个迭代中实现,以此类推。这种方法有很大的优点:如果你的进度落后了时间计划,你仍然可以交付可运行的具有最重要能力的部分系统。 然而,如果你有一个分层的体系架构,在上层的子系统依赖于底层子系统的能力,这种方法将不能够很好的工作。如果你必须要在一个时间内构建一个子系统,这样的体系架构将迫使你首先构建底层的子系统,然后构建越来越上层的子系统。但是为了构建在底层子系统的正确的能力,你通常需要在上层的子系统上进行大量的详细设计和实现的工作,因为他们决定了什么是你在底层子系统中需要的。这产生了 “catch-22”的现象;第二个方法解释了如何解决这个问题。 方法 2 :首先开发最重要的场景。如果你使用方法 1 ,你一次只能开发一个子系统。使用方法 2 ,你将重点放在了重要的场景上,或者使用系统的关键方法上,然后再添加更多的不是那么重要的场景。这与方法 1 有什么不同呢?让我们来看一个例子。 假设你正在构建一个新的应用,这个应用将为用户提供管理缺陷的能力。这是一个分层的应用,被构建在 WebSphere Application Server 上,使用 DB2 作为底层的数据库。在首先的迭代中,你开发了一系列重要的场景,比如输入一个简单的缺陷。在第二次迭代中,你为这些场景添加了复杂性 例如,你也许使缺陷能够被一个工作流来处理。在第三次迭代中,你通过为非典型的用户提供完整的支持,比如保存部分的缺陷条目然后返回到这个条目中的能力等等。 使用这种方法,你在 所有的迭代中完成 所有的子系统的工作,但是在第一个迭代中你仍然关注最重要的场景,而将不是非常重要的或者最小难度的场景留到最后的迭代中实现。 如果你正工作在一个良好定义的体系架构的系统中时,方法 1 是更加适合的 比如,一个已存在系统的增进或者开发使用简单体系架构的新应用。多数构建复杂应用的项目应该使用方法 2 ,但是他们应该以这样的方式来计划迭代,这种方法能够削减后来迭代的范围以弥补可能的时间推延。
你可以将这个步骤看作是更加正式和有组织的完成步骤 1 ( 尽早的构建功能原型)的方法。但是什么是“可执行的架构”呢? 可执行的架构是系统的部分的实现,它被构建以演示架构的设计所支持的关键的功能。更重要的是,它能够证明设计能够满足对于性能、生产能力、容量可靠性、可测量性和其他方面的需求。构建一个可执行的架构允许你在稍后的阶段中在一个坚实的基础上构建所有的系统功能性的能力。这个可执行的架构是一个 进化的原型,它的目的是当系统的架构成熟时,保持已经被证明的特性并保证他们最大可能的满足系统的需求。换句话说,这些特性将是交付系统的一部分。与你在步骤 1中构建的 功能原型相比,这个进化的原型覆盖了架构问题的所有方面。 生成一个进化的原型意味着你要设计、实现和测试一系统的个框架结构或者架构。在应用的角度上,系统的功能还没有被完成,但是大多数的构建模块之间的接口已经被实现了,你能够(并应该)在某种程度上编译并测试架构。指导初始的负载和性能测试。这个原型也会反映你的关键设计的决定,包括技术、主要组件和他们之间接口的选择。 但是你将如何为这个进化的原型提出系统的架构呢?关键是将重点放在最重要的百分之二十到三十的用例上(系统为用户提供的完全的服务)。这里是一些决定什么用例是最重要的方法。
上面所列出的第一个和最后一个标准是架构师最关心的;项目经理主要关注于前两个。 对于每一个关键的用例,识别最重要的场景并用他们创建可执行的系统架构。换句话说就是设计、实现和 测试这些场景。
如果你将要遵循上面所描述的步骤 2 和步骤 3 ,那么你将会非常的接近“理想”迭代开发的模型。那么,你接下来的步骤应该是融合步骤 2 和步骤 3 ,并添加支持风险驱动和迭代开发的管理生命周期。这就是在 RUP 中被描述的迭代开式的生命周期。 RUP 对迭代开发提供了一个结构化的方法,它将一个项目划分成为四个阶段:初始阶段、细化阶段、构建阶段和转换阶段。每一个阶段包含了一个或者更多的迭代,每个迭代都关注于产生必要的技术上的可交付物以实现阶段的业务目标。团队经历的迭代次数与需要实现阶段的目标的数量是一样的,而不是更多。如果在团队计划的迭代次数内他们没有成功的实现这些目标,他们必须为那个阶段添加额外的迭代 并且推迟项目。为了避免这种事情发生,你一定要严格的将你的精力集中在每个阶段你需要实现的业务目标上。例如,在初始阶段将精力过于集中在需求上将会成生相反的效果。下面是典型的阶段目标的简要描述。
在本文中,我们已经描述了你如何能够使用四个步骤逐步的从瀑布型的开发方法转换到增量的迭代开发方法。每一个步骤都以最小的中断为你的开发工作添加了切实的价值。一些团队每次不止使用一个步骤;其他的团队可能在一个步骤上运作了几个项目,然后才执行下一个步骤。然而,你应该选择使用这种明智的实施方法,因为它能够帮助你在开发组织中减少由于过程变化所带来的风险。
1 对于实践中 RUP 软件开发周期的详细描述,参见 The Rational Unified Process Made Easy的第 5-8 章,Per Kroll 和 Philippe Kruchten 著(Addison-Wesley, 2003)。 |
|