Per Kroll
Director,Rational Unified Process IBM
2004年4月
本文来自 Rational Edge :RUP 的专家解释了被软件开发项目成员需要的职责和观点上的改变,并且介绍了成功的从传统的瀑布型方法向迭代方法转变的客户案例。
成功的采用迭代开发方法的实践不仅仅需要部署一系列的新技术,也需要改变团队协作的方式和团队成员的职责。在本文中,我们将会了解到被软件开发项目成员需要的职责和观点上的改变,并且介绍了成功的从传统的瀑布型方法向迭代方法转变的客户案例。
广泛的引用这些变化作为一种“新的思想”,我们将关注软件开发项目中的不同个体角色:
分析人员 主要负责与客户交互和需求。
开发人员 主要负责设计、实现和单元测试。
测试人员主要负责功能、性能和系统测试。
项目经理 主要负责持续的项目团队的跟踪并关注关键的交付产物。
质量保证和方法专家 负责质量标准和最佳实践。
客户 负责澄清他们的业务需求关心什么样的能力。
分析人员的新思想
在传统的瀑布型的方法中,分析人员与用户和项目团队之外的涉众打交道。目标是理解并开发一个代表了一系列需求的方案,文档化这些需求然后将这些需求文档交给开发团队。一些开发组织用一种“未来”状态的长列表来详细说明需求;另一些组织在高层次上表达需求,为解释需求保留了很大的空间。在这两种情况下,必须有这样的假设,分析人员既要了解业务又要了解用户,并且这个分析人员应该是指定系统应该具有什么功能的人。
一旦分析人员文档化了需求,他或者她就会要求用户来检查这些需求文档(甚至如果他们不能完全理解用来表达需求的技术语言,并且/或者他们不能通过可视化的方法来表示当系统被实现时许多需求是如何满足用户的需要的)。然后,实现需求规格说明就是开发人员的工作了。典型的,不论是开发人员还是测试人员都没有参与到阐述需求的工作中。并且一旦需求被规格化,很少会有在分析人员与设计人员之间的积极的交互。分析人员只是简单的阐明需求说明书中包含的内容。
这种传统的模型在某些方面的缺陷将在下面被解释。
分析人员的新思想
建立与最终客户的持续的交互以确保开发人员可以创建正确的系统。
鼓励尽早的开发和实现系统的关键能力部分,以加深你对什么需求将满足业务需要的理解。
从一开始就与开发人员和测试人员一起优化序需求。
为需求选择适当的详细程度,可以根据你的项目和当前的生命周期阶段而定。
分析人员不应该孤立的指定需求
首先, 瀑布型的方法失败的认识到客户、开发人员和测试人员参与需求说明工作的价值。没有对业务和技术拥有优秀的理解将不可能创建出能够改进你的业务的软件系统。不幸的是,很少有人同时在业务和技术领域具有深厚的知识背景。这就意味着,分析人员、开发人员、测试人员和客户应该一起工作提供需要的所有的信息以确保开发人员可以创建“正确的”软件系统 — 也就是说,一个充分满足客户业务需要并且提供从根本上有效的改进客户业务的能力的软件。
让我们来看一个简单的例子以说明这样的团队协作的好处。
例子:基于 Web 的航班预约系统
我们假设一个分析人员负责对这个基于 Web 的自助服务的航班预约系统的需求工作。这个分析人员指定用户将提供一个航班的代码并指明行程的开始地和目的地。如果用户不知道航班代码,他们可以通过提供城市名字进行查询。然后,这个分析人员指定,在用户预定了一个指定的航班后,他们将会得到关于如何联系不同的代理以预约到达目的地时的地面交通工具。
当设计人员检查系统需求时,他回想起曾经看到过一个能够提供部分功能的并且经过证明的Web 服务的方案。这个低成本的服务允许用户导航机场的地图显示并快速的找到符合他们需要的机场,甚至假如用户不熟悉他们的目的地城市或者不熟悉目的地的地区的机场。
在与客户验证了策略后,分析人员和设计人员对需求作了改动以包含这个 Web 服务的实现。然后,在几天的开发工作后,设计人员发现了这个服务的另一特性:当用户选择了一个机场时,他们会自动的收到一个机场信息的列表,信息中包括可得到的地面交通工具的模式和对每种模式预定的容量。设计人员和分析人员与客户和项目经理讨论了这个发现,大家都同意合并这个额外的 Web 服务的特性到他们的新系统中,代替他们原来指定的创建一个地面交通引用的特性。
就像你从这个简单的例子中所看到的那样,在项目的早期阶段就让设计人员/开发人员参与到需求中能够带来巨大的好处。他们中的每一个人都可以建议分析人员或者最终用户考虑不到的能力和方案。当然,衡量预期的项目范围变化的价值仍然是项目经理和客户的责任,分析人员仍然必须理解业务需要并驱使系统应该在何处结束。但是他或她可以通过与设计人员/开发人员协作找到更好的方案。
分析人员和最终用户的交流应该贯穿于整个项目的生命周期中
传统开发模式的另外一个缺陷是缺乏在分析人员与最终用户之间的交流。 最终用户被期望预先的指出需求并且对需求进行检查,但是他们有限的参与了方案的开发。在许多情况下,和约的商定是以预先被描述的需求为基础的,并且后来的变更需要有一个和约上的协商。
在整个开发的生命周期中维护在用户与分析人员之间的交流是尤其有效的。双方都应该理解他们拥有相同的目标:建立满足质量要求的可以解决问题的方案,同时成本是可接受的。如果他们的关系是围绕着争论关于什么是以前达成的一致和谁应该为此付钱,而不是建立一个正确的方案的话,那么项目就陷入了麻烦之中。这并不意味着分析人员应该接受所有的需求或者最终用户不应该作出变更的请求。相反,这意味着所有的项目相关的人员应该在提出需求和最终进入到订单中的需求进行一个平衡以形成更好方案的开发。他们需要认可当他们过分的严格时,应该通过一些讨论以达到一个折中的方案,并且要作积极的改变以保持项目按照计划进行。当然,这一点做起来要比说的有难度。但是朝着有效的团队协作的第一步是在分析人员与最终用户之间建立起有建设性的对话。
过度的指出预想的需求是不明智的
传统的开发方法提倡详细的预先需求,并且在过去的多年里很多人觉得项目失败是因为他们的需求对启动项目是不够详细的。但是增加需求说明的详细程度将会减少的回报。在一些情况下,项目团队需要不断的构建方案,并假设需求在整个项目周期不断的改进。记住:软件项目的主要目标是在尽可能低成本的条件下生成可执行的能够解决手工形式的业务问题的代码。一旦你的需求到达了一定的细化程度,将他们定案的最廉价的方法是对系统进行部分的实现以可以向最终用户进行演示。同时你可以一起确定你还需要提供什么样的其他能力。定案需求通常要经过几次的迭代,在迭代期间你可以调整需求、设计和代码,然后对测试进行引导。
在项目周期的后期你可以不必正式的文档化很多的详细的需求;代码本身可以提供足够的文档,并且很少在团队中误解什么是需要实现方面存在风险。这依赖于正被开发的系统自然的改变了参与的人数、系统期望的生命跨度、和约的义务和附加的质量标准的需求。最后,也许是最重要的,你应该象驱赶技术风险一样在项目中尽早驱赶商业上的风险。在细化预想的需求上花费过多的时间会使你的注意偏离出降低关键的风险。
开发人员的新思想
扩大了的职责包括详细设计、实现和单元测试。
成为需求工作中的一部分:帮助阐明需求然后创建符合需求的方案。
成为了测试工作的一部分:按照测试先行的设计原则开发代码。
尽可能的重用已存在的方案而不是重新构建方案。
开发人员的新思想
迭代开发,对开发人员来说使用与迭代开发相关联的最佳实践和现代的工具技术,同样需要在思想上的转变。首先,就像我们在上一部分讨论的,开发人员需要在指定需求中扮演更多积极的角色。
过去,开发人员以对辣手的问题提出聪明的解决方法为荣。他们创造唯一的方案以使系统性能最大化、内存使用最小化或者提供良好的图形用户界面。当然,开发人员仍然需要提出聪明的方法,但是他们的精力需要从构建方法转向到发现聪明的方法以尽量的将可重用的资产、开发源码的软件、通用的商业现货 (COTS) 组件和 Web 服务集成成为一个可使用的方案。为了成为优秀的开发人员,你需要知道如何最好的利用交互式的开发环境(IDE)和建模环境。“这里没有发明”的态度是达不到预期的目标的;作为一个开发人员,你的精力应该放在通过利用各种可重用的资产来产生可使用的方案上。今天快速并廉价的生产出高质量的产品才是应该受到褒奖的。
质量是测试团队的职责。在传统的开发中,在项目的最后几周,整个系统才交付到可怜数量的测试人员手中,他们被要求尽可能多的找出软件系统的缺陷。他们负责质量,开发人员负责修改他们发现的缺陷。迭代开发正好与之相反,迭代开发认为质量是项目中每一个人的职责。现在我们拥有支持这种共有职责概念的工具和过程,允许我们交付高质量的代码。新的工具技术允许我们同步代码和设计。他们也使我们可以在系统被完成前测试代码产生的内存泄漏问题和性能问题,这是在过去无法达到的。现代的配置管理和变更管理环境支持了每日构建,不仅允许我们测试我们分离的代码,还允许我们测试我们的代码如何与系统的其他部分代码的集成。
现代的最佳实践包括测试先行的设计:首先你要指出你应该进行什么测试,然后再构建能够通过这些测试的软件。这样创建高质量的代码是我们重点要考虑的事情。现代的工具技术也支持设计的质量问题,1 它使质量成为了设计过程中的主要部分。它允许你在设计过程的早期就进行质量的测量并且可以自动的从设计模型中产生测试。通过保证设计的质量增强了整个系统的质量并保证了测试代码的完成。
总而言之,使用迭代式的开发方法,开发人员角色需要进行扩展;除了简单的实现需求规格说明,开发人员必须在决定什么对整个系统是必要的方面承担更多的任务。这包括帮助确保需求是正确的和在可接受的成本下创建出高质量的系统。为了作出最好的决定,开发人员需要更好的理解项目的远景和驱动项目的业务问题。这样开发人员才有可能创建一个满足需求和能够解决业务问题的方案。
测试人员的新思想
成为团队中在质量问题上的指导者。
与分析人员和开发人员一起工作以确保需求和设计是可测试的。
在项目的早期就应引入测试。
稳定能力的持续的自动化测试。
测试人员的新思想
过去,我们注意到按照传统的方法,当项目快要结束时,开发出来的软件才被交给测试人员,让测试人员通过找到软件的缺陷来为软件“注入质量”。每一个测试人员都可能会退缩,因为通过经验他们知道这种方法是多么没有效率和令人失望的。
使用迭代的开发方法,测试人员仍然要负责确定系统的质量是否足以发布,但是他们确保完成高质量系统的方法却从根本上发生了变化。首先,测试人员在项目非常早的时候就参与其中,因为每一个迭代(可能除了第一个迭代)都会产生可以被立即测试的可执行的结果。在项目早期,测试更关注找到“影响大的”问题,而不是验证代码是不是已经可以交付了。这就意味着你不能简单的将代码交给测试人员;相反,测试人员需要与分析人员和开发人员密切的合作以便他们能够理解在每个迭代中什么是需要被测试的。
此外,测试人员必须向团队的其他能够适当的改经需求、设计、代码和其他支持性的产物的成员提供测试的反馈。测试人员可以通过这些任务来帮助其他项目成员的工作:通常他们可以帮助产生更好的需求,因为他们在计划方法来测量一个需求是否被满足的方面是经过训练的。同时,现代的集成测试和开发环境允许他们通过使用基线的代码配置进行连续的测试工作。
就像分析人员和开发人员承担了更多的任务一样,测试人员也承担起了更多的任务。在项目周期的后期,测试人员作为质量专家,对整个开发团队提供专家意见。例如,除了执行大量了集成和验收测试之外,他们可以在质量的相关决定上对项目经理进行指导。
因为贯穿整个项目中需求是被迭代的识别、细化、开发和测试的,因此项目团队并不应该过早的生成所有被执行的测试的详细说明。相反,早期的焦点应该是理解对于一定的阶段或者迭代的测试的目标 — 他们应该完成什么。这将焦点移到了识别每个迭代的潜在的问题领域上,并且开发测试以暴露那些问题领域。
迭代开发意味着在项目的早期你就要开发测试系统的关键能力。同时也意味着你需要在后续的迭代中测试和重新测试这些能力以确保你认为应该被解决的问题不会再一次出现。不通过有效的自动化测试进行完全的回归测试是不切合实际的 — 而且通常是不可能的,因此你必须要在整个项目中不断的开发出可自动化的测试。有效的实现这一点的诀窍是理解在迭代不断持续时什么元素是可以保持稳定的;通过这种方法,你可以避免为每一个迭代重写自动化测试。这就要求你对系统的体系架构有一定的了解;在比较靠后的迭代中,测试应该更注重系统详细的功能性。
项目经理的新思想
公开项目面临的风险,持续的重新评估风险,并且使用风险来为项目工作进行优先级的划分。
通过衡量可演示的结果而不是一系列被完成的活动来评估项目状态。
在项目的早期,对整个项目开发高层次的计划,但仅仅对当前的和下一个迭代生成详细计划。
根据你如何有效的处理风险的经验,在任何给定的时间上评估你在需求、架构、设计、实现和测试上的投入。
信任你的团队。给他们足够的知识和职责让他们全全负责产品的质量。帮助他们团结在一起工作。
项目经理的新思想
迭代开发方法的一个最重要的区别是他被设计成为在项目的早期将主要的风险去除掉。利用这个差别需要对项目所面临的风险公开而且诚实。同时你逃避风险的自然倾向会使人们推迟处理这些风险,风险不知何故的被忽略 — 就像他们从未发生过。风险就像是传染病:你忽略它越久,它的危害就越大。风险必须在整个项目中被持续的识别并划分优先级;每一个迭代都必须被降低风险的原则性的目标所驱动。
使用这种方法会需要一些文化上的变化。典型的管理形式规定你应该对广大听众避免承认风险,因为人们可能会断定你们在运作一个有问题的项目。这是一个危险的方法:假装风险不存在不会使风险离去。
传统的情况下,项目经理通过询问团队成员什么活动已经被完成来确定项目的状态。他们假设但所有活动都被完成时,项目也就被完成了。但是这种方法经常会导致项目的失败。检查被完成的活动是不好的测量项目进度的方法,因为它并没有对活动的结果的质量进行量化。如果项目经理能够精确的计划项目团队需要做的每一项工作,并且没有会背离项目计划的事情发生,这种方法可能会满足项目的需要。然而,就像很多项目经理知道的那样,事情很少是按照计划进行的。甚至是如果你创建了更为详细的计划,结果也是令人惊讶的。无论我们如何努力的预期未来,我们也不能预期每一件事情。
基于结果的管理
因为我们不能预测未来,软件项目的经理需要对他们的一些关键的策略进行风险的管理。这需要改变你的测量方法:代替基于完成活动的测量方法,你应该使用基于可演示的结果的方法进行测量。这是基于结果管理的基础。应用基于结果的管理策略意味着将重点放在风险上并正面的处理它。通过特意的结构化项目的活动以处理风险,你可以揭示隐藏的问题,解决问题并稳定的减少项目进程中的不确定因素。
此外,因为一个软件开发项目的主要结果是软件本身,所以你所交付的产物应该是成功的主要量度。你可以使用象一系列被通过的软件测试、代码中的缺陷的数量和他们的精确度等等的矩阵来评估你的软件。换句话说,移到迭代开发就意味着要通过根据指定目标和需求产生的的测量可演示的结果,而不是通过计算有多少活动、产物或者工作产品被完成来评估项目的状态。为了评估项目的稳定性(有效管理的另一个量度),你也应该跟踪需求、设计和代码中的冗余。
更少的也许是更多的
早期,我们注意到添加详细的信息到需求也许不总是对项目有益的。对其他类型的文档也是同样的。你的质量保证计划、软件开发计划或者需求管理计划都不是项目健康的良好量度。太详细不总是更好的:你应该调整你特定项目需要的文档详细级别。决定合适详细级别的方法是关注风险和结果:如果你添加详细信息到某一产物可以减少风险或者改进特定结果的质量,那么这个投入是值得的;否则,在更有生产力的活动上花费时间是更好的。
使用瀑布型的方法项目经理需要付出很多的注意以详细的计划和指定需求。而使用迭代开发的方法项目经理可以根据工作中的风险来权衡的将时间花费在细化需求、架构、设计和实现上。他们会问:“什么样类型的活动可以最有效的立即降低风险呢?” 也许原型化一个方案可以处理与项目客户买进相关的风险,或者也许他们需要实际的设计、实现和测试架构以完全的处理架构方面的风险。
使项目中的每一个成员都参与到质量保证中
对于项目经理来说移到迭代开发方法需要的其他思想的改变是开始将质量保证作为一个集体的职责考虑。我通常会惊讶的听到项目经理说“我需要测试小组对我的开发人员保持忠诚,”或者“如果分析人员没有写下单个的需求,他们将不会被实现。” 当然,你的确需要测试小组来建立高质量的应用,并且失败的文档化和跟踪需求将导致问题的出现。但是如果开发人员不把质量当作自己的责任,你也就会陷入到质量问题中。为了实现这一点,你需要从通过信任你的团队和清晰的交流你们的预期开始。假如你不能信任这些人,那么也许这些人不应该属于你的团队。
理想的情况下,项目经理应该能够宣称“我的开发人员负责交付高质量的代码;为了帮助开发人员,我们有一个测试团队,测试团队有专业的能力并可以验证被交付的代码是否是高质量的,”并且“我们的开发人员负责实现满足最终用户需要的应用。为了帮助开发人员,我们有一个分析的团队在适当的详细级别上文档化需求,并且分析人员是开发人员和最终客户之间的桥梁。” 创建交能够协同工作的团队 — 也就是说使团队中的分析人员、开发人员和测试人员能够一起工作来实现高质量的结果 — 是成功的迭代开发的关键之一。
质量保证和方法专家的新思想
为项目选择适当的形式级别(更多的不总是更好的)。
关注在整个项目周期中维护质量,但是可以是灵活的。最好的到达高质量的做法不是仅仅通过疯狂的关注检查和测试实现的,而是通过在给定时间上对需求、架构、设计、实现、检查和测试的良好平衡实现的。
采用风险驱动的过程方法。你的过程应该允许项目经理对项目当前的风险情况采用战术性的活动。
质量保证和方法专家的新思想
许多组织都有质量专家 — 负责达到一定的标准的人,比如 SEI CMM / CMMI 中的标准,或者是组织内部的质量标准。许多组织也有方法专家,他们或者来自软件工程过程组(SEPG),或者是独立的负责软件开发中的方法。
通常,这些质量和方法专家在采用迭代的开发思想时存在最大的问题。他们中的许多人花费了他们职业生涯的大部分时间来驱使组织按照“文档越多越好”、“越多检查越好”、“对于过程工作,需要被彻底的文档化”,和“过程应该提供一个基于时间的你所需要执行的项目中的特定任务的描述”这样的传统的至理名言来指定过程。他们相信通过跟随这些提供了高度形式化的原则,就可以避免项目的失败。
然而,当这样做的太过火时,将产生相反的效果,因为高度的形式化将增加迭代的成本,并鼓励使用瀑布型的周期。相反,你需要通过风险驱动,对每个迭代产生可演示的结果的迭代方法彻底的平衡文档的最佳实践。这种方法允许项目团队增强产品的质量,同时也可以降低形式化的程度和整个的成本。我们应该注意,使用迭代的方法并不排斥使用高度形式化的方法,高度形式化的方法可能对安全第一的应用或者其他严格要求质量的应用是有用的。2
灵活性是关键的
一个关键的变化是软件过程和质量方法应该提供给项目经理调节项目风险的足够的灵活性;项目经理应该不断的监视项目的活动和状态,并且调整过程的执行以降低关键的风险。一个过程可以指明如何应对各种风险和产生被需要的结果,但是风险典型的是预先未知的,因此你不可能在早期就指明什么任务应该被执行来应对风险。你也不知道哪一个需求应该被指定什么时候用什么组件来设计和实现他们。这就意味着你所用的过程需要提供关于里程碑代表什么、如何实现它和如何降低风险的清晰的管理指南 — 通过注意项目执行的细节来保留过程的灵活性。
你不能通过在项目过程中简单使用具体的指导来创建一个一个有效的项目计划。项目计划本身需要是一个迭代的过程,包括对当前风险、进度、测试结果等等进行评估以为下一阶段的迭代的详细计划收集输入。
这也意味着项目的检查或者审计不应该主要的关注验证是否项目团队已经制造了一系列的产物或者执行了一系列的活动。相反,审计应该瞄准在识别和验证风险和确认适当的产物和活动被完成以降低风险上。审计也应该检查以前的问题以识别出公共的失败模式,并且建议过程的修改以保护将来的最小失败的可能性。
客户的新思想
积极的参与描述需求并成为软件开发团队中不可缺少的部分。
对已经被开发的软件的能力不断的提供反馈,比如工作原型和用户界面设计。
利用一种使用迭代方法的进步的获得模式;这种模式保证买家和卖家的双方利益。
客户的新思想
使用传统的软件开发方法的客户期望在开发工作中有最小的投资。他们想预先指出所有的需求,确定一个固定的价格,然后等待最终系统的交付。经常的,会产生在期望值和实际交付系统之间的非常大的差距 — 解决方案并没有满足客户真实的业务需要。
通过转向迭代开发,改变客户和开发团队之间的交互模式,客户和开发团队都可以避免大量的痛苦。在一个迭代开发的项目中,客户应该是构建应用团队中的不可缺少的一部分。客户与开发团队的其他成员协同工作以确保最终交付的应用系统满足被需要的业务价值。客户的组织应该尽可能的保持与开发团队之间交互的兴趣,以确保开发团队可以理解他们应该构建什么和项目中具有什么样的风险和问题。如果客户没有帮助指导开发的工作,开发团队可能会开发出错误的应用 — 每个人都会蒙受损失。
在迭代开发的模式中,客户不能仅仅指出他们所预期的然后就等待系统交付。不论他们怎么清晰的定义,所有的需求都从属于众多的说明和可能的实现。对开发团队来说,与其生成更加详细的需求,还不如投入时间更加频繁和有效的与项目的关键投资人(包括客户)进行沟通。那么,当客户查看演进的应用时,他们将获得应用应该做什么的更好的理解,并可以提供有建设性的建议以改进系统。同时,如果在项目中业务要求发生快速的变化,需求也需要随之发生改变。
客户也可以从公开协商迭代式的和约中受益,一个叫作累进的获取得方法。使用这个方法,首先双方可以为整个项目协商一个大致的协议作为描述双方管理商业关系的合法的指导。然后项目被划分为两个或者更多的子和约。早期的和约基于时间和所需的资源指明了款额,因为任何一方都不能足以知道整个方案和可能的开发成本以作出合理的预先承诺。后来的和约式固定的价格,它最小化了双方对应该的交付产物的不一致。3
结论
我们已经讨论了对软件开发采用迭代的方法不仅仅简单的需要遵循一系列的指南。迭代开发和支持迭代开发的现代技术改变了软件开发游戏中的规则,并使许多在过去战统治地位的公理失去了效力。成功的从瀑布型的方法向迭代的方法转变要求软件开发团队在个人的责任和如何与团队其他成员交互上发生了变化。换句话说,它要求在多中角色团队成员的行为和价值上作出明显的和持久改变。
只有每一个团队成员都能够理解迭代开发需要做的必要的改变的基本原理,组织才能够实现这些变化。在每一个项目的开始,对于项目团队来说,公开的讨论我们在本文中的迭代开发训练部分已经讨论的必要的行为和有感知的变化是有益处的。本文可以作为这些讨论的出发点:项目团队应该赞同这些思想上的改变和上面针对他们特定项目讨论的实践。
基本上,本文是关于如何通过使用迭代开发的方法和通过确保整个团队共享项目的远景建立“正确的”软件的,并讲述了你应该如何与团队紧密的合作来实现这个远景。项目经理能够在工作过程中鼓励这种变化,但是它最终建立在团队成员接受和有效的实施是些变化之上。
鸣谢
我非常的感谢 Kurt Bittner 、Anthony Kesterton 和 Glen Tattersall ,他们对本文进行有价值的校对,同时也感谢 Marlene Ellin 出色的编辑工作。
其他读物