第2章 软件过程

第2章 软件过程

软件工程过程是为了获得高质量软件所需要完成的一系列任务的框架,它规定了完成各项任务的工作步骤。

在完成开发任务时必须进行一些开发活动,并且使用适当的资源(人员、时间、计算机硬件、软件工具等),在过程结束时将输入(如软件需求)转化为输出(如软件产品),因此,ISO9000把过程定义为“把输入转化为输出的一组彼此相关的资源和活动”。过程定义了运用方法的顺序、应该交付的文档资料、为保证软件质量和协调变化所需要采取的管理措施,以及标志软件开发各个阶段任务完成的里程碑。为获得高质量的软件产品,软件工程过程必须科学、合理。

本章讲述在软件生命周期全过程中应该完成的基本任务,并介绍各种常用的过程模型。

2.1 软件生命周期的基本任务

概括地说,软件生命周期由软件定义、软件开发和运行维护3个时期组成,每个时期又可进一步划分成若干个阶段。

软件定义时期的任务是确定软件开发工程必须完成的总目标;确定工程的可行性;导出实现工程目标应该采用的策略及系统必须完成的功能;估计完成该项工程需要的资源和成本,并且制订工程进度表。这个时期的工作通常又称为系统分析,由系统分析员负责完成。软件定义时期通常进一步划分为3个阶段,即问题定义、可行性研究和需求分析。

软件开发时期具体设计和实现在前一个时期定义的软件,它通常由下述4个阶段组成:概要设计、详细设计、编码和单元测试、综合测试。其中前两个阶段又称为系统设计,后两个阶段又称为系统实现。

运行维护时期的主要任务是使软件持久地满足用户的需要。具体地说,当软件在使用过程中发现错误时应该加以改正;当环境改变时应该修改软件以适应新的环境;当用户有新要求时应该及时改进软件以满足用户的新需要。通常对维护时期不再进一步划分阶段,但是每一次维护活动本质上都是一次压缩和简化了的定义和开发过程。

下面简要介绍上述各个阶段应该完成的基本任务。

1.问题定义

问题定义阶段必须回答的关键问题是:“要解决的问题是什么”。如果不知道问题是什么就试图解决这个问题,显然是盲目的,只会白白浪费时间和金钱,最终得出的结果很可能是毫无意义的。尽管确切地定义问题的必要性是十分明显的,但是在实践中它却可能是最容易被忽视的一个步骤。

通过调研,系统分析员应该提出关于问题性质、工程目标和工程规模的书面报告,并且需要得到客户对这份报告的确认。

2.可行性研究

这个阶段要回答的关键问题是:“上一个阶段所确定的问题是否有行得通的解决办法”。并非所有问题都有切实可行的解决办法,事实上,许多问题不可能在预定的系统规模或时间期限之内解决。如果问题没有可行的解,那么花费在这项工程上的任何时间、资源和经费都是无谓的浪费。

可行性研究的目的就是用最小的代价在尽可能短的时间内确定问题是否能够解决。必须记住,可行性研究的目的不是解决问题,而是确定问题是否值得去解。要达到这个目的,不能靠主观猜想而只能靠客观分析。系统分析员必须进一步概括地了解用户的需求,并在此基础上提出若干种可能的系统实现方案,对每种方案都从技术、经济、社会因素(如法律)等方面分析可行性,从而最终确定这项工程的可行性。

3.需求分析

这个阶段的任务仍然不是具体地解决客户的问题,而是准确地回答“目标系统必须做什么”这个问题。

虽然在可行性研究阶段已经粗略了解了用户的需求,甚至还提出了一些可行的方案,但是,可行性研究的基本目的是用较小的成本在较短的时间内确定是否存在可行的解法,因此许多细节被忽略了。然而在最终的系统中却不能遗漏任何一个微小的细节,所以可行性研究并不能代替需求分析,它实际上并没有准确地回答“系统必须做什么”这个问题。

需求分析的任务还不是确定系统怎样完成它的工作,而仅仅是确定系统必须完成哪些工作,也就是对目标系统提出完整、准确、清晰和具体的要求。

用户了解他们所面对的问题,知道必须做什么,但是通常不能完整准确地表达出他们的要求,更不知道怎样利用计算机解决他们的问题;软件开发人员知道怎样用软件实现人们的要求,但是对特定用户的具体要求并不完全清楚。因此,系统分析员在需求分析阶段必须与用户密切配合,充分交流信息,以得出经过用户确认的系统需求。

这个阶段的另外一项重要任务,是用正式文档准确地记录对目标系统的需求,该文档通常称为规格说明(specification)。

4.概要设计

这个阶段的基本任务是:概括地回答“怎样实现目标系统?”概要设计又称为初步设计、逻辑设计、高层设计或总体设计。

首先,应该设计出实现目标系统的几种可能的方案。软件工程师应该用适当的表达工具描述每种可能的方案,分析每种方案的优缺点,并在充分权衡各种方案利弊的基础上,推荐一个最佳方案。此外,还应该制定出实现所推荐方案的详细计划。如果客户接受所推荐的系统方案,则应该进一步完成本阶段的另一项主要任务。

上述设计工作确定了解决问题的策略及目标系统中应包含的程序。但是,对于怎样设计这些程序,软件设计的一条基本原理指出,程序应该模块化,也就是说,一个程序应该由若干个规模适中的模块按合理的层次结构组织而成。因此,概要设计的另一项主要任务就是设计程序的体系结构,也就是确定程序由哪些模块组成以及模块间的关系。

5.详细设计

概要设计阶段以比较抽象概括的方式提出了解决问题的办法。详细设计阶段的任务就是把解法具体化,也就是回答“应该怎样具体地实现这个系统”这个关键问题。

这个阶段的任务还不是编写程序,而是设计出程序的详细规格说明。这种规格说明的作用很类似于其他工程领域中工程师经常使用的工程蓝图,它们应该包含必要的细节,程序员可以根据它们写出实际的程序代码。

详细设计也称为模块设计、物理设计或低层设计。在这个阶段将详细地设计每个模块,确定实现模块功能所需要的算法和数据结构。

6.编码和单元测试

这个阶段的关键任务是写出正确的,容易理解、容易维护的程序模块。

程序员应该根据目标系统的性质和实际环境,选取一种适当的高级程序设计语言(必要时用汇编语言),把详细设计的结果翻译成用选定的语言书写的程序,并且仔细测试编写出的每一个模块。

7.综合测试

这个阶段的关键任务是通过各种类型的测试(及相应的调试)使软件达到预定的要求。最基本的测试是集成测试和验收测试。所谓集成测试是根据设计的软件结构,把经过单元测试检验的模块按某种选定的策略装配起来,在装配过程中对程序进行必要的测试。所谓验收测试则是按照规格说明书的规定(通常在需求分析阶段确定),由用户(或在用户积极参加下)对目标系统进行验收。必要时还可以再通过现场测试或平行运行等方法对目标系统进一步测试检验。为了使用户能够积极参加验收测试,并且在系统投入生产性运行以后能够正确有效地使用这个系统,通常需要以正式的或非正式的方式对用户进行培训。通过对软件测试结果的分析可以预测软件的可靠性;反之,根据对软件可靠性的要求,也可以决定测试和调试过程什么时候可以结束。应该用正式的文档资料把测试计划、详细测试方案以及实际测试结果保存下来,作为软件配置的一个组成部分。

8.软件维护

维护阶段的关键任务是,通过各种必要的维护活动使系统持久地满足用户的需要。通常有4类维护活动:改正性维护,也就是诊断和改正在使用过程中发现的软件错误;适应性维护,即修改软件以适应环境的变化;完善性维护,即根据用户的要求改进或扩充软件使它更完善;预防性维护,即修改软件为将来的维护活动预先做准备。

虽然没有把维护阶段进一步划分成更小的阶段,但是实际上每一项维护活动都应该经过提出维护要求(或报告问题),分析维护要求,提出维护方案,审批维护方案,确定维护计划,修改软件设计,修改程序,测试程序,复查验收等一系列步骤,因此,实质上是经历了一次压缩和简化了的软件定义和开发的全过程。

每一项维护活动都应该准确地记录下来,作为正式的文档资料加以保存。我国国家标准《计算机软件开发规范》(GB8566—88)也把软件生命周期划分成8个阶段,这些阶段是:可行性研究与计划,需求分析,概要设计,详细设计,实现,组装测试,确认测试,使用和维护。其中,实现阶段即是编码与单元测试阶段,组装测试即是集成测试,确认测试即是验收测试。可见,国家标准中划分阶段的方法与前面介绍的阶段划分方法基本相同,差别仅仅是:因为问题定义的工作量很小而没有把它作为一个独立的阶段列出来;由于综合测试的工作量过大而把它分解成了两个阶段。

在实际从事软件开发工作时,软件规模、种类、开发环境及开发时使用的技术方法等因素,都影响阶段的划分。事实上,承担的软件项目不同,应该完成的任务也有差异,没有一个适用于所有软件项目的任务集合。适用于大型复杂项目的任务集合,对于小型且较简单的项目而言往往就过于复杂了。因此,一个科学、有效的软件工程过程应该定义一组适合于所承担的项目特点的任务集合。一个任务集合通常包括一组软件工程工作任务、里程碑和应该交付的产品(软件配置成分)。

生命周期模型规定了把生命周期划分成哪些阶段及各个阶段的执行顺序,因此,也称为过程模型。

实际从事软件开发工作时应该根据所承担的项目的特点来划分阶段,但是,下面讲述软件过程模型时并不是针对某个特定项目讲的,因此,只能使用“通用的”阶段划分方法。由于瀑布模型与快速原型模型的主要区别是获取用户需求的方法不同,因此,下面在介绍生命周期模型时把“规格说明”作为一个阶段独立出来。此外,问题定义和可行性研究的主要任务是概括地了解用户的需求,为了简洁地描述软件过程,把它们都归并到需求分析中去了。同样,为了简单起见,把概要设计和详细设计合并在一起称为“设计”。

2.2 瀑布模型

在20世纪80年代之前,瀑布模型(waterfall model)一直是唯一被广泛采用的生命周期模型,现在它仍然是软件工程中应用最广泛的过程模型。图2.1所示为传统的瀑布模型。

图像说明文字

图2.1 传统的瀑布模型

按照传统的瀑布模型来开发软件,有如下几个特点。

(1)阶段间具有顺序性和依赖性

这个特点有两重含义:①必须等前一阶段的工作完成之后,才能开始后一阶段的工作;②前一阶段的输出文档就是后一阶段的输入文档。因此,只有前一阶段的输出文档正确,后一阶段的工作才能获得正确的结果。但是,万一在生命周期某一阶段发现了问题,很可能需要追溯到在它之前的一些阶段,必要时还要修改前面已经完成的文档。然而,在生命周期后期改正早期阶段造成的问题,需要付出很高的代价。这就好像水已经从瀑布顶部流泻到底部,再想使它返回到高处需要付出很大能量一样。

(2)推迟实现的观点

缺乏软件工程实践经验的软件开发人员,接到软件开发任务以后常常急于求成,总想尽早开始编写程序。但实践表明,对于规模较大的软件项目来说,往往编码开始得越早最终完成开发工作所需要的时间反而越长。这是因为,前面阶段的工作没做或做得不扎实,过早地考虑进行程序实现,往往导致大量返工,有时甚至发生无法弥补的问题,带来灾难性后果。

瀑布模型在编码之前设置了系统分析与系统设计的各个阶段,分析与设计阶段的基本任务规定,在这两个阶段主要考虑目标系统的逻辑模型,不涉及软件的物理实现。

清楚地区分逻辑设计与物理设计,尽可能推迟程序的物理实现,是按照瀑布模型开发软件的一条重要的指导思想。

(3)质量保证的观点

软件工程的基本目标是优质、高产。为了保证所开发软件的质量,在瀑布模型的每个阶段都应坚持两个重要做法。

  • 每个阶段都必须完成规定的文档,没有交出合格的文档就是没有完成该阶段的任务。完整、准确的合格文档不仅是软件开发时期各类人员之间相互通信的媒介,也是运行时期对软件进行维护的重要依据。
  • 每个阶段结束前都要对所完成的文档进行评审,以便尽早发现问题,改正错误。事实上,越是早期阶段犯下的错误,暴露出来的时间就越晚,排除故障改正错误所需付出的代价也越高。因此,及时审查,是保证软件质量,降低软件成本的重要措施。

传统的瀑布模型过于理想化了。事实上,人在工作过程中不可能不犯错误。在设计阶段可能发现规格说明文档中的错误,而设计上的缺陷或错误可能在实现过程中显现出来,在综合测试阶段将发现需求分析、设计或编码阶段的许多错误。因此,实际的瀑布模型是带“反馈环”的,如图2.2所示(图中实线箭头表示开发过程,虚线箭头表示维护过程)。当在后面阶段发现前面阶段的错误时,需要沿图中左侧的反馈线返回前面的阶段,修正前面阶段的产品之后再回来继续完成后面阶段的任务。

0202

图2.2 加入迭代过程的瀑布模型

瀑布模型有许多优点:可强迫开发人员采用规范的方法(如结构化技术);严格地规定了每个阶段必须提交的文档;要求每个阶段交出的所有产品都必须经过质量保证小组的仔细验证。

各个阶段产生的文档是维护软件产品时必不可少的,没有文档的软件几乎是不可能维护的。遵守瀑布模型的文档约束,将使软件维护变得比较容易一些。由于绝大部分软件预算都花费在软件维护上,因此,使软件变得比较容易维护就能显著降低软件预算。可以说,瀑布模型的成功在很大程度上是由于它基本上是一种文档驱动的模型。

但是,“瀑布模型是由文档驱动的”这个事实也是它的一个主要缺点。在可运行的软件产品交付给用户之前,用户只能通过文档来了解产品是什么样的。但是,仅仅通过写在纸上的静态的规格说明,很难全面正确地认识动态的软件产品。而且事实证明,一旦一个用户开始使用一个软件,在他的头脑中关于该软件应该做什么的想法就会或多或少地发生变化,这就使得最初提出的需求变得不完全适用了。其实,要求用户不经过实践就提出完整准确的需求,在许多情况下都是不切实际的。总之,由于瀑布模型几乎完全依赖于书面的规格说明,很可能导致最终开发出的软件产品不能真正满足用户的需要。

下一节将介绍快速原型模型,它的优点是有助于保证用户的真实需要得到满足。

2.3 快速原型模型

快速原型(rapid prototype)是快速建立起来的可以在计算机上运行的程序,它所能完成的功能往往是最终产品能完成的功能的一个子集。如图2.3所示(图中实线箭头表示开发过程,虚线箭头表示维护过程),快速原型模型(rapid application development,RAD)的第一步是快速建立一个能反映用户主要需求的原型系统(prototype),让用户在计算机上试用它,通过实践来了解目标系统的概貌。通常,用户试用原型系统之后会提出许多修改意见,开发人员按照用户的意见快速地修改原型系统,然后再次请用户试用……一旦用户认为这个原型系统确实能做他们所需要的工作,开发人员便可据此书写规格说明文档,根据这份文档开发出的软件可以满足用户的真实需求。

0203

图2.3 快速原型模型

从图2.3可以看出,快速原型模型是不带反馈环的,这正是这种过程模型的主要优点:软件产品的开发基本上是按线性顺序进行的。能做到基本上按线性顺序开发的主要原因如下。

  • 原型系统已经通过与用户交互而得到验证,据此产生的规格说明文档正确地描述了用户需求,因此,在开发过程的后续阶段不会因为发现了规格说明文档的错误而进行较大的返工。
  • 开发人员通过建立原型系统已经学到了许多东西(至少知道了“系统不应该做什么,以及怎样不去做不该做的事情”),因此,在设计和编码阶段发生错误的可能性也比较小,这自然减少了在后续阶段需要改正前面阶段所犯错误的可能性。

软件产品一旦交付给用户使用之后,维护便开始了。根据用户使用过程中的反馈,可能需要返回到收集需求阶段,如图2.3中虚线箭头所示。

快速原型的本质是“快速”。开发人员应该尽可能快地建造出原型系统,以加速软件开发过程,节约软件开发成本。原型的用途是获知用户的真正需求,一旦需求确定了,原型将被抛弃。因此,原型系统的内部结构并不重要,重要的是,必须迅速地构建原型然后根据用户意见迅速地修改原型。UNIX Shell和超文本都是广泛使用的快速原型语言。快速原型模型是伴随着第四代语言(PowerBuilder,Informix-4GL等)和强有力的可视化编程工具(Visual Basic,Delphi等)的出现而成为一种流行的开发模式。

当快速原型的某个部分是利用软件工具由计算机自动生成的时候,可以把这部分用到最终的软件产品中。例如,用户界面通常是快速原型的一个关键部分,当使用屏幕生成程序和报表生成程序自动生成用户界面时,实际上可以把这样得到的用户界面用在最终的软件产品中。

2.4 增量模型

增量模型也称为渐增模型,如图2.4所示。使用增量模型开发软件时,把软件产品作为一系列的增量构件来设计、编码、集成和测试。每个构件由多个相互作用的模块构成,并且能够完成特定的功能。使用增量模型时,第1个增量构件往往实现软件的基本需求,提供最核心的功能,如使用增量模型开发字处理软件时,第1个增量构件可能提供基本的文件管理、编辑和文档生成功能;第2个增量构件提供更完善的编辑和文档生成功能;第3个增量构件实现拼写和语法检查功能;第4个增量构件完成高级的页面排版功能。把软件产品分解成增量构件时,应该使构件的规模适中,规模过大或过小都不好。最佳分解方法因软件产品特点和开发人员的习惯而异。分解时唯一必须遵守的约束条件是,当把新构件集成到现有软件中时,所形成的产品必须是可测试的。

图像说明文字

图2.4 增量模型

采用瀑布模型或快速原型模型开发软件时,目标都是一次就把一个满足所有需求的产品提交给用户。增量模型则与之相反,它分批地逐步向用户提交产品,每次提交一个满足用户需求子集的可运行的产品。整个软件产品被分解成许多个增量构件,开发人员一个构件接一个构件地向用户提交产品。每次用户都得到一个满足部分需求的可运行的产品,直到最后一次得到满足全部需求的完整产品。从第1个构件交付之日起,用户就能做一些有用的工作。显然,能在较短时间内向用户提交可完成一些有用的工作的产品,是增量模型的一个优点。增量模型的另一个优点是,逐步增加产品功能可以使用户有较充裕的时间学习和适应新产品,从而减少一个全新的软件可能给客户组织带来的冲击。

使用增量模型的困难是,在把每个新的增量构件集成到现有软件体系结构中时,必须不破坏原来已经开发出的产品。此外,必须把软件的体系结构设计得便于按这种方式进行扩充,向现有产品中加入新构件的过程必须简单、方便。也就是说,软件体系结构必须是开放的。从长远观点看,具有开放结构的软件拥有真正的优势,这种软件的可维护性明显好于封闭结构的软件。尽管采用增量模型比采用瀑布模型和快速原型模型需要更精心的设计,但在设计阶段多付出的劳动将在维护阶段获得回报。如果一个设计非常灵活而且足够开放,足以支持增量模型,那么,这样的设计将允许在不破坏产品的情况下进行维护。事实上,使用增量模型时开发软件和扩充软件功能(完善性维护)并没有本质区别,都是向现有产品中加入新构件的过程。

从某种意义上说,增量模型本身是自相矛盾的。它一方面要求开发人员把软件看做一个整体,另一方面又要求开发人员把软件看做构件序列,每个构件本质上都独立于另一个构件。除非开发人员有足够的技术能力协调好这一明显的矛盾,否则用增量模型开发出的产品可能并不令人满意。

2.5 螺旋模型

软件开发几乎总要冒一定风险,例如,产品交付给用户之后用户可能不满意,到了预定的交付日期软件可能还未开发出来,实际的开发成本可能超过预算,产品完成前一些关键的开发人员可能“跳槽”了,产品投入市场之前竞争对手发布了一个功能相近、价格更低的软件等。软件风险是任何软件开发项目中都普遍存在的实际问题,项目越大,软件越复杂,承担该项目所冒的风险也越大。软件风险可能在不同程度上损害软件开发过程和软件产品质量,因此,在软件开发过程中必须及时识别和分析风险,并且采取适当措施以消除或减少风险的危害。

构建原型是一种能使某些类型的风险降至最低的方法。正如2.3节所述,为了降低交付给用户的产品不能满足用户需要的风险,一种行之有效的方法是在需求分析阶段快速地构建一个原型。在后续的阶段中也可以通过构造适当的原型来降低某些技术风险。当然,原型并不能“包治百病”,对于某些类型的风险(例如,聘请不到需要的专业人员或关键的技术人员在项目完成前“跳槽”),原型方法是无能为力的。

螺旋模型的基本思想是,使用原型及其他方法来尽量降低风险。理解这种模型的一个简便方法,是把它看做在每个阶段之前都增加了风险分析过程的快速原型模型,如图2.5所示。图中带箭头的点画线的长度代表当前累计的开发费用,螺线旋过的角度值代表开发进度。螺旋线每个周期对应于一个开发阶段,每个阶段开始时(左上象限)的任务是:确定该阶段的目标、为完成这些目标选择方案及设定这些方案的约束条件。接下来的任务是:从风险角度分析上一步的工作结果,努力排除各种潜在的风险。通常用建造原型的方法来排除风险,如果风险不能排除,则停止开发工作或大幅度地削减项目规模;如果成功地排除了所有风险,则启动下一个开发步骤(见图2.5右下象限)。在这个步骤的工作过程相当于纯粹的瀑布模型。最后是评价该阶段的工作成果并计划下一个阶段的工作。

螺旋模型有许多优点:对可选方案和约束条件的强调有利于已有软件的重用,也有助于把软件质量作为软件开发的一个重要目标;减少了过多测试(浪费资金)或测试不足(产品故障多)所带来的风险;更重要的是,在螺旋模型中维护只是模型的另一个周期,在维护和开发之间并没有本质区别。

0205

图2.5 螺旋模型

螺旋模型主要适用于内部开发的大规模软件项目。如果进行风险分析的费用接近整个项目的经费预算,则风险分析是不可行的。事实上,项目越大,风险也越大,因此,进行风险分析的必要性也越大。此外,只有内部开发的项目,才能在风险过大时方便地终止。

螺旋模型的主要优势在于,它是风险驱动的;但是,这也可能是它的一个弱点。除非软件开发人员具有丰富的风险评估经验和这方面的专门知识,否则将出现真正的风险:当项目实际上正在走向灾难时,开发人员可能还认为一切正常。

2.6 喷泉模型

迭代是软件开发过程中普遍存在的一种内在属性。经验表明,软件过程各个阶段之间的迭代或一个阶段内各个工作步骤之间的迭代,在面向对象范型中比在结构化范型中更常见。

图2.6所示的喷泉模型是典型的面向对象生命周期模型。“喷泉”这个词体现了面向对象软件开发过程迭代和无缝的特性。图中代表不同阶段的圆圈相互重叠,这明确表示两个活动之间存在交迭;而面向对象方法在概念和表示方法上的一致性,保证了在各项开发活动之间的无缝过渡。事实上,用面向对象方法开发软件时,在分析、设计、编码等项开发活动之间并不存在明显的边界。图中在一个阶段内的向下箭头代表该阶段内的迭代(或求精)。图中较小的圆圈代表维护,圆圈较小象征着采用了面向对象范型之后维护时间缩短了。

0206

图2.6 喷泉模型

为避免使用喷泉模型开发软件时开发过程过分无序,应该把一个线性过程(例如,快速原型模型或螺旋模型中的中心垂线)作为总目标。但是,同时也应该记住,面向对象范型本身要求经常对开发活动进行迭代或求精。

2.7 Rational统一过程

Rational统一过程(rational unified process,RUP)是由Rational软件公司(已被IBM并购)推出的一个软件开发过程框架。所谓软件开发过程框架是指团队可以根据具体的项目组或软件开发企业的不同需求,能够定义、配置、定制和实施一致的软件开发过程。

通过总结经过多年实践和验证的各种软件开发最佳实践,RUP框架提出一组丰富的软件工程原则的指导信息。它既适用于不同规模和不同复杂度的项目,也适用于不同的开发环境和领域。

RUP包含以下3个核心元素。

  • 用于成功开发软件的一组基本观念和原则。这些观念和原则是开发 RUP 的基础,包含了后面要讲述的6条“最佳实践”和10个“流程要素”。
  • 一套关于可重用方法内容和过程构建的框架。可以在这个框架之下定义自己的开发方法和过程。
  • 基础的方法和过程定义语言。这就是统一方法架构元模型(unified method architecture,UMA)。该模型提供了用于描述方法内容及过程的语言。这种新语言统一了不同方法和过程工程语言。

2.7.1 最佳实践

软件开发是一项团队活动。理想情况下,此类活动包括在贯穿软件生命周期的各阶段中进行配合默契的团队工作。此类活动既不是科学研究也不是工程设计——至少从基于确凿事实的可量化原则的角度来说不是。软件开发工作假设开发人员可以计划和创建单独片段并稍后将它们集成起来(就如同在构建桥梁或宇航飞船),经常会在截止期限、预算和用户满意度的某一方面失败。

在缺少系统的理论指导时,那么就必须依靠称为“最佳实践”的软件开发技术,其价值已在不同的软件开发团队里的多年应用中已经过反复验证。RUP的“最佳实践”描述了一个指导开发团队达成目标的迭代和递增式的软件开发过程,而不是强制规定软件项目的“计划—构建—集成”这类活动顺序。以下分别讲述RUP的6条最佳实践。

(1)迭代式开发

采用传统的顺序开发方法(瀑布模型)是不可能完成客户需要的大型复杂软件系统的开发工作的。事实上,在整个软件开发过程中客户的需求会经常改变,因此,需要有一种能够通过一系列细化、若干个渐进的反复过程而得出有效解决方案的迭代式方法。迭代式开发如图2.7所示。

0207

图2.7 迭代式开发

迭代式开发允许在每次迭代过程中需求发生变化,这种开发方法通过一系列细化来加深对问题的理解,因此能更容易地容纳需求的变更。

也可以把软件开发过程看做是一个风险管理过程,迭代式开发通过采用可验证的方法来减少风险。采用迭代式开发方法,每个迭代过程以完成可执行版本结束,这可以让最终用户不断地介入和提出反馈意见。同时,开发团队根据产生的结果可以频繁地进行状态检查以确保项目能按时进行。迭代式方法同样使得需求、特色和日程上战略性的变化更为容易。

(2)管理需求

在开发软件的过程中,客户需求将不断地发生变化,因此,确定系统的需求是一个连续的过程。RUP描述了如何提取、组织系统的功能性需求和约束条件并把它们文档化。经验表明,使用用例和脚本是捕获功能性需求的有效方法,RUP采用用例分析来捕获需求,并由它们驱动设计和实现。

(3)使用基于组件的架构

所谓组件就是功能清晰的模块或子系统。系统可以由已经存在的、由第三方开发商提供的组件构成,因此组件使软件重用成为可能。RUP提供了使用现有的或新开发的组件定义架构的系统化方法,从而有助于降低软件开发的复杂性,提高软件重用率。

(4)可视化建模

为了更好地理解问题,人们常常采用建立问题模型的方法。所谓模型,就是为了理解事物而对事物作出的一种抽象,是对事物的一种无歧义的书面描述。由于应用领域不同,模型可以有文字、图形、数学表达式等多种形式,一般说来,使用可视化的图形更容易令人理解。

RUP与可视化的统一建模语言(Unified Modeling Language,UML)紧密地联系在一起,在开发过程中建立起软件系统的可视化模型,可以帮助人们提高管理软件复杂性的能力。

(5)验证软件质量

某些软件不受用户欢迎的一个重要原因,是其质量低下。在软件投入运行后再去查找和修改出现的问题,比在开发的早期阶段就进行这项工作需要花费更多的人力和时间。在RUP中,软件质量评估不再是一种事后的行为或由单独小组进行的孤立活动,而是内建在贯穿于整个开发过程的、由全体成员参与的所有活动中。

(6)控制软件变更

在变更是不可避免的环境中,必须具有管理变更的能力,才能确保每个修改都是可接受的而且能被跟踪的。RUP描述了如何控制、跟踪和监控修改,以确保迭代开发的成功。

2.7.2 RUP的十大要素

通常我们在软件的质量和开发效率之间需要达到一个平衡。这里的关键就是我们需要了解软件过程中一些必要的元素,并且遵循某些原则来定制软件过程来满足项目的特定需求。下面讲述RUP的十大要素。

(1)前景:制定前景

有一个清晰的前景是开发一个满足项目干系人(stakeholder)需求的产品的关键。

前景(vision)给更详细的技术需求提供了一个高层的、有时候是合同式的基础。正像这个术语隐含的那样,前景是软件项目的一个清晰的、通常是高层的视图,它能在过程中被任意一个决策者或实施者借用。前景捕获了非常高层的需求和设计约束,让它的读者能够理解即将开发的系统。前景向项目审批流程提供输入信息,因此与商业理由密切相关。前景传达了有关项目的基本信息,包括为什么要进行这个项目以及这个项目具体做什么,同时前景还是验证未来决策的标尺。

前景的内容将回答以下问题:

  • 关键术语是什么?(词汇表)
  • 我们要尝试解决什么问题?(问题声明)
  • 谁是项目干系人?谁是用户?他们的需要是什么?
  • 产品的特性是什么?
  • 功能性需求是什么?(用例)
  • 非功能性需求是什么?
  • 设计约束是什么?

制定一个清晰的前景和一组让人可以理解的需求,是需求规程的基础,也是用来平衡相互竞争的项目干系人之间的优先级的一个原则。这里包括分析问题,理解项目干系人的需求,定义系统以及管理需求变化。

(2)计划:按计划管理

产品的质量是和产品的计划息息相关的。

在RUP中,软件开发计划(software development plan,SDP)综合了管理项目所需的各种信息,也许会包括一些在先启阶段开发的单独的内容。SDP必须在整个项目中被维护和更新。

SDP定义了项目时间表(包括项目计划和迭代计划)和资源需求(资源和工具),可以根据项目进度表来跟踪项目进展。同时也指导了其他过程内容的计划:项目组织、需求管理计划、配置管理计划、问题解决计划、QA计划、测试计划、评估计划以及产品验收计划。

软件开发计划的格式远远没有计划活动本身以及驱动这些活动的思想重要。正如 Dwight D. Eisenhower所说:“计划并不重要,重要的是实施计划。”

计划、风险、业务案例、架构以及控制变更一起成为RUP中项目管理流程的要点。项目管理流程包括以下活动:构思项目、评估项目规模和风险、监测与控制项目、计划和评估每个迭代和阶段。

(3)风险:降低风险并跟踪相关问题

RUP的要点之一是在项目早期就标识并处理最大的风险。项目组标识的每一个风险都应该有一个相应的缓解或解决计划。风险列表应该既作为项目活动的计划工具,又作为组织迭代的基础。

(4)业务案例:检验业务案例

业务案例从业务的立场提供了确定该项目是否值得投资的必要信息。

业务案例主要用于为实现项目前景而制定经济计划。一旦制定之后,业务案例就用来对项目提供的投资收益率(ROI)进行精确的评估。它提供项目的合理依据,并确定对项目的有关经济约束。它向经济决策者提供关于项目价值的信息,并用于确定该项目是否应继续前进。

业务案例的描述不应深挖问题的细节,而应就为什么需要该产品树立一个有说服力的论点。它必须简短,这样就容易让所有项目团队成员理解并牢记。在关键里程碑处,将重新检验业务案例,以查看预期收益和成本的估计值是否仍然准确,以及该项目是否应继续。

(5)架构:设计组件架构

在RUP中,软件系统的架构是指一个系统关键部件的组织或结构,组件之间通过接口交互,而组件是由一些更小的组件和接口组成的。

RUP提供了一种设计、开发、验证架构的系统化的方法。在分析和设计流程中包括以下步骤:定义候选架构、精化架构、分析行为(用例分析)和设计组件。

要陈述和讨论软件架构,必须先定义一种架构表示法,以便描述架构的重要方面。在 RUP中,架构由软件架构文档通过多个视图表示。每个视图都描述了某一组项目干系人所关心的系统的某个方面。项目干系人有最终用户、设计人员、经理、系统工程师、系统管理员等。软件架构文档使系统架构师和其他项目组成员能就与架构相关的重大决策进行有效的交流。

(6)原型:增量地构建和测试产品

RUP是为了尽早排除问题和解决风险和问题而构建、测试和评估产品的可执行版本的一种迭代方法。

递增地构造和测试系统的组件,这是实施和测试规程及原则通过迭代证明价值的“要素”。

(7)评估:定期评估结果

顾名思义,RUP的迭代评估审查了迭代的结果。评估得出了迭代满足需求规范的程度,同时还包括学到的教训和实施的过程改进。

根据项目的规模、风险以及迭代的特点,评估可以是对演示及其结果的一条简单的记录,也可能是一个完整的、正式的测试评审记录。

这里的关键是既关注过程问题又关注产品问题。越早发现问题就减少越多的问题。

(8)变更请求:管理并控制变更

RUP的配置和变更管理流程的要点是当变化发生时管理和控制项目的规模,并且贯穿整个生命周期。其目的是考虑所有的涉众需求,在尽量满足需求的同时又能及时地交付合格的产品。

用户拿到产品的第一个原型后(往往在这之前就会要求变更),他们会要求变更。重要的是,变更的提出和管理过程始终保持一致。

在RUP中,变更请求通常用于记录和跟踪缺陷和增强功能的要求,或者对产品提出的任何其他类型的变更请求。变更请求提供了相应的手段来评估一个变更的潜在影响,同时记录就这些变更所作出的决策。他们也帮助确保所有的项目组成员都能理解变更的潜在影响。

(9)用户支持:部署可用的产品

在RUP中,部署流程的要点是包装和交付产品,同时交付有助于最终用户学习、使用和维护产品的所有必要的材料。

项目组至少要给用户提供一个用户指南(也许是通过联机帮助的方式提供),可能还有一个安装指南和版本发布说明。

根据产品的复杂度,用户也许还需要相应的培训材料。最后,通过一个材料清单(bill of materials,BOM)清楚地记录哪些材料应该和产品一起交付。

(10)过程:采用适合项目的过程

选择适合正开发的产品类型的流程是非常必要的。即使在选定一个流程后,也不能盲目遵循这个流程——必须应用常理和经验来配置流程和工具,以满足组织和项目的需要。

2.7.3 RUP生命周期

(1)核心工作流

RUP中有9个核心工作流,如图2.8所示。其中前6个为核心过程工作流程,后3个为核心支持工作流程。下面简要地叙述各个工作流程的基本任务。

0208

图2.8 方法内容定义与方法内容在流程中的应用

业务建模:深入了解使用目标系统的机构及其商业运作,评估目标系统对使用它的机构的影响。

需求:捕获客户的需求,并且使开发人员和用户达成对需求描述的共识。

分析与设计:把需求分析的结果转化成分析模型与设计模型。

实现:把设计模型转换成实现结果(形式化地定义代码结构;用构件实现类和对象;对开发出的构件进行单元测试;把不同实现人员开发出的模块集成为可执行的系统)。

测试:检查各个子系统的交互与集成,验证所有需求是否都被正确地实现了,识别、确认缺陷并确保在软件部署之前消除缺陷。

部署:成功地生成目标系统的可运行的版本,并把软件移交给最终用户。

配置与变更管理:跟踪并维护在软件开发过程中产生的所有制品的完整性和一致性。

项目管理:提供项目管理框架,为软件开发项目制定计划、人员配备、执行和监控等方面的实用准则,并为风险管理提供框架。

环境:向软件开发机构提供软件开发环境,包括过程管理和工具支持。

(2)工作阶段

RUP的软件生命周期按时间分成4个顺序阶段,每个阶段以一个主要里程碑结束;每个阶段的目标通过一次或多次迭代来完成。在每个阶段结束时执行一个评估,确定是否符合该阶段的目标。如果评估令人满意,则允许项目进入下一个阶段。如果未能通过评估,则决策者应该作出决定,要么中止该项目,要么重做该阶段的工作。

下面简述4个阶段的工作目标。

先启阶段:建立业务模型,定义最终产品视图,并且确定项目的范围。

精化阶段:设计并确定系统的体系结构,制定项目计划,确定资源需求。

构建阶段:开发出所有构件和应用程序,把它们集成为客户需要的产品,并且详尽地测试所有功能。

移交阶段:把开发出的产品提交给用户使用。

0209

图2.9 项目的阶段和里程碑

(3)RUP迭代式开发

RUP强调采用迭代和渐增的方式来开发软件,整个项目开发过程由多个迭代过程组成。在每次迭代中只考虑系统的一部分需求,针对这部分需求进行分析、设计、实现、测试、部署等工作,每次迭代都是在系统已完成部分的基础上进行的,每次给系统增加一些新的功能,如此循环往复地进行下去,直至完成最终项目。

事实上,RUP重复一系列组成软件生命周期的循环。每次循环都经历一个完整的生命周期,每次循环结束都向用户交付产品的一个可运行的版本。前面已经讲过,每个生命周期包含4个连续的阶段,在每个阶段结束前有一个里程碑来评估该阶段的目标是否已经实现,如果评估结果令人满意,则可以开始下一阶段的工作。

每个阶段又进一步细分为一次或多次迭代过程。项目经理根据当前迭代所处的阶段以及上一次迭代的结果,对核心工作流程中的活动进行适当的参见,以完成一次具体的迭代过程。在每个生命周期中都一次次地轮流访问这些核心工作流程,但是,在不同的迭代过程中是以不同的工作重点和强度对这些核心工作流程进行访问的。例如,在构件阶段的最后一次迭代过程中,可能还需要做一点需求分析工作,但是需求分析已经不像初始阶段和精化阶段的第1个迭代过程中那样是主要工作了,而在移交阶段的第2个迭代过程中,就完全没有需求分析工作了。同样,在精化阶段的第2个迭代过程及构件阶段中,主要工作是实现,而在移交阶段的第2个迭代过程中,实现工作已经很少了。

2.8 敏捷过程与极限编程

2.8.1 敏捷过程概述

在20世纪90年代后期出现了一些不同于传统观念的引人注目的软件开发方法。它们虽然形式各异,但都强调一些共同观念,包括程序员团队和业务专家的紧密协作,面对面交流(比书面文档更有效),不断发布可部署的版本,紧密和自组织的团队,依靠新的编程模式和团队组织使得不断变化的需求不再成为一种危机。

到了2001年2月,17位著名的软件专家联合起草了敏捷软件开发宣言。敏捷软件开发宣言由下述4个简单的价值观声明组成(参考:http://www.agilemanifesto.org)。

(1)“个体和交互”胜过“过程和工具”

优秀的团队成员是软件开发项目获得成功的最重要因素,但不好的过程和工具也会使最优秀的团队成员无法发挥作用。

团队成员的合作、沟通以及交互能力要比单纯的软件编程能力更为重要。

正确的做法是:受限制利于构建软件开发团队(包括成员和交互方式等),然后再根据需要为团队配置项目环境(包括过程和工具)。

(2)“可以使用的软件”胜过“面面俱到的文档”

软件开发的主要目标是向用户提供可以使用的软件而不是文档,但是,完全没有文档的软件也是一种灾难。开发人员应该把主要精力放在创建可使用的软件上面,仅当迫切需要并且具有重大意义时,才进行文档编制工作,而且所编织的内部文档应该尽量简明扼要和主题突出。

(3)“客户合作”胜过“合同谈判”

客户通常不可能做到一次性地把他们的需求完整准确地表述在合同中。能够满足客户不断变化的需求的切实可行的途径是:开发团队与客户密切协作。因此,能指导开发团队与客户协同工作的合同才是最好的合同。

(4)“响应变化”胜过“遵循计划”

软件开发过程总会有变化,这是客观存在的现实。一个软件过程必须反映现实,因此,软件过程应该有足够的能力及时响应变化。然而没有计划的项目也会因陷入混乱而失败,关键是计划必须有足够的灵活性和可塑性,在形势发生变化时能迅速调整,以适应业务、技术等方面的变化。

在理解上述4个价值观声明时应该注意,声明只不过是对不同因素在保证软件开发成功方面所起作用的大小做了比较,说一个因素更重要并不是说其他因素不重要,更不是说某个因素可以被其他因素代替。

另外,“敏捷宣言”中还包含以下原则。

① 最重要的是通过尽早和持续地交付有价值的软件以满足客户需要。

② 即使在开发后期也欢迎需求的变化。敏捷过程驾驭变化带给客户竞争优势。

③ 经常交付可以使用的软件,间隔可以从几星期到几个月,时间尺度越短越好。

④ 业务人员和开发人员应该在整个项目过程中每天都在一起工作。

⑤ 使用积极的开发人员进行项目,给他们提供所需环境和支持,并信任他们能够完成任务。

⑥ 在开发小组中最有效率和效果的信息传达方式是面对面的交谈。

⑦ 可以使用的软件是度量进度的主要标准。

⑧ 敏捷过程提倡的是持续开发过程。投资人、开发人员和用户应该维持一个长期稳定的步调。

⑨ 持续地追求卓越的技术与良好的设计会增加敏捷性。

⑩ 简单(尽可能减少工作量)是最重要的。

⑪ 最好的架构、需求和设计都来自于自组织的团队。

⑫ 团队要定期总结如何提高效率,然后相应地调整自己的行为。

根据上述价值观提出的软件过程统称为敏捷过程,其中应用比较广泛的是极限编程和Scrum。

2.8.2 极限编程

极限编程(extreme programming)是敏捷过程中最负盛名的一个,其名称中“极限”二字的含义是指把好的开发实践运用到极致。目前,极限编程已经成为一个典型的开发方法,广泛应用于需求模糊且经常改变的场合。

1.极限编程的有效实践

下面简述极限编程方法采用的有效的开发实践。

  • 客户作为开发团队的成员。必须至少有一名客户代表在项目的整个开发周期中与开发人员在一起紧密地配合工作,客户代表负责确定需求、回答开发人员的问题并且设计功能验收测试方案。
  • 使用用户素材。所谓用户素材就是正在进行的关于需求的谈话内容的助记符。根据用户素材可以合理地安排实现该项需求的时间。
  • 短交付周期。每两周完成一次的迭代过程实现了用户的一些需求,交付出目标系统的一个可工作的版本。通过向有关的用户演示迭代生成的系统,获得他们的反馈意见。
  • 验收测试。通过执行由客户制定的验收测试来捕获用户素材的细节。
  • 结对编程。结对编程就是由两名开发人员在同一台计算机上共同编写解决同一个问题的程序代码,通常一个人编码,另一个人对代码进行审查与测试,以保证代码的正确性与可读性。结对编程是加强开发人员相互沟通与评审的一种方式。
  • 测试驱动开发。极限编程强调“测试先行”。在编码之前应该首先设计好测试方案,然后再编程,直至所有测试都获得通过之后才可以结束工作。
  • 集体所有。极限编程强调程序代码属于整个开发小组集体所有,小组每个成员都有更改代码的权利,每个成员都对全部代码的质量负责。
  • 持续集成。极限编程主张在一天之内多次集成系统,而且随着需求的变更,应该不断地进行回归测试。
  • 可持续的开发速度。开发人员以能够长期维持的速度努力工作。XP(extreme programming)规定开发人员每周工作时间不超过40h,连续加班不可以超过两周,以免降低生产率。
  • 开放的工作空间。XP项目的全体参与者(开发人员、客户等)一起在一个开放的场所中工作,项目组成员在这个场所中自由地交流和讨论。
  • 及时调整计划。计划应该是灵活的、循序渐进的。制订出项目计划之后,必须根据项目进展情况及时进行调整,没有一成不变的计划。
  • 简单的设计。开发人员应该使设计与计划要在本次迭代过程中完成的用户素材完全匹配,设计时不需要考虑未来的用户素材。在一次次的迭代过程中,项目组成员不断变更系统设计,使之相对于正在实现的用户素材而言始终处于最优状态。
  • 重构。所谓代码重构就是在不改变系统行为的前提下,重新调整和优化系统的内部结构,以降低复杂性、消除冗余、增加灵活性和提高性能。应该注意的是,在开发过程中不要过分依赖重构,特别是不能轻视设计,对于大中型系统而言,如果推迟设计或者干脆不做设计,将造成一场灾难。
  • 使用隐喻。可以将隐喻看做是把整个系统联系在一起的全局视图,它描述系统如何运作,以及用何种方式把新功能加入到系统中。

2.极限编程的整体开发过程

图2.10描述了极限编程的整体开发过程。首先,项目组针对客户代表提出的“用户故事”(用户故事类似于用例,但比用例更简单,通常仅描述功能需求)进行讨论,提出隐喻,在此项活动中可能需要对体系结构进行“试探”(所谓试探就是提出相关技术难点的试探性解决方案)。然后,项目组在隐喻和用户故事的基础上,根据客户设定的优先级制订交付计划(为了制订切实可行的交付计划,可能需要对某些技术难点进行试探)。接下来开始多个迭代过程(通常,每个迭代历时1~3周),在迭代期内产生的新用户故事不在本次迭代内解决,以保证本次开发过程不受干扰。开发出的新版本软件通过验收测试之后交付用户使用。

图像说明文字

图2.10 极限编程的整体开发过程

3.极限编程的迭代过程

图2.11描述了极限编程的迭代开发过程。项目组根据交付计划和“项目速率”(即实际开发时间和估计时间的比值),选择需要有限完成的用户故事或待消除的差错,将其分解成可在1~2天内完成的任务,制订出本次迭代计划。然后通过每天举行一次的“站立会议”(与会人员站着以缩短会议时间,提高工作效率),解决遇到的问题,调整迭代计划,会后进行代码共享式的开发工作。所开发出的新功能必须100%通过单元测试,并且立即进行集成,得到的新的可运行版本由客户代表进行验收测试。开发人员与客户代表交流此次代码共享式编程的情况,讨论所发现的问题,提出新的用户故事,算出新的项目速率,并把相关的信息提交给站立会议。

0211

图2.11 极限编程的迭代过程

综上所述,以极限编程为杰出代表的敏捷过程,可以快速、敏捷地响应变化和不确定的需求,同时仍然能够保持可持续的开发速度。上述这些特点使得敏捷过程能够较好地适应商业竞争环境下对项目提出的有限资源和有限开发时间的约束。

2.9 能力成熟度模型

能力成熟度模型(capability maturity model,CMM)并不是一个软件生命周期模型,而是改进软件过程的一种策略,它与实际使用的过程模型无关。1986年美国卡内基—梅隆大学软件工程研究所首次提出能力成熟度模型(CMM),不过在当时它被称为过程成熟度模型。

多年来,软件开发项目不能按期完成,软件产品的质量不能令客户满意,再加上软件开发成本超出预算,这些是许多软件开发组织都遇到过的难题。不少人试图通过采用新的软件开发技术来解决在软件生产率和软件质量等方面存在的问题,但效果并不令人十分满意。上述事实促使人们进一步考察软件过程,从而发现关键问题在于对软件过程的管理不尽人意。事实表明,在无规则和混乱的管理之下,先进的技术和工具并不能发挥应有的作用。人们认识到,改进对软件过程的管理是解决上述难题的突破口,再也不能忽视软件过程中管理的关键作用了。

能力成熟度模型的基本思想是,因为问题是由管理软件过程的方法不当引起的,所以新软件技术的运用并不会自动提高生产率和软件质量。能力成熟度模型有助于软件开发组织建立一个有规律的、成熟的软件过程。改进后的过程将开发出质量更好的软件,使更多的软件项目免受时间和费用超支之苦。

软件过程包括各种活动、技术和工具,因此,它实际上既包括了软件生产的技术方面又包括了管理方面。CMM策略力图改进软件过程的管理,而在技术方面的改进是其必然的结果。

必须记住,对软件过程的改进不可能在一夜之间完成,CMM是以增量方式逐步引入变化的。CMM明确地定义了5个不同的成熟度等级,一个软件开发组织可用一系列小的改良性步骤向更高的成熟度等级迈进。

2.9.1 能力成熟度模型的结构

能力成熟度模型包括以下组成成分。

  • 成熟度等级(maturity levels):一个成熟度等级是在朝着实现成熟软件过程进化途中的一个妥善定义的平台。5个成熟度等级构成了CMM的顶层结构。
  • 过程能力(process capability):软件过程能力描述,通过遵循软件过程能实现预期结果的程度。一个组织的软件过程能力提供一种“预测该组织承担下一个软件项目时,预期最可能得到的结果”的方法。
  • 关键过程域(key process areas,KPA):每个成熟度等级由若干关键过程域组成。每个关键过程域都标识出一串相关的活动,当把这些活动都完成时所达到的一组目标,对建立该过程成熟度等级是至关重要的。关键过程域分别定义在各个成熟度等级之中,并与之关联在一起,例如,等级2的一个关键过程域是软件项目计划。
  • 目标(goals):目标概括了关键过程域中的关键实践,并可用于确定一个组织或项目是否已有效地实施了该关键过程域。目标表示每个关键过程域的范围、边界和意图,例如,关键过程域“软件项目计划”的一个目标是,“软件估算已经文档化,供计划和跟踪软件项目使用。”
  • 公共特性(common features):CMM把关键实践分别归入下列5个公共特性之中:执行约定、执行能力、执行的活动、测量和分析以及验证实施。公共特性是一种属性,它能指示一个关键过程域的实施和规范化是否是有效的、可重复的和持久的。
  • 关键实践(key practices):每个关键过程域都用若干关键实践描述,实施关键实践有助于实现相应的关键过程域的目标。关键实践描述对关键过程域的有效实施和规范化贡献最大的基础设施和活动。例如,在关键过程域“软件项目计划”中,一个关键实践是“按照已文档化的规程制订项目的软件开发计划”。

图2.12所示描绘了CMM的结构。

0212

图2.12 CMM结构

2.9.2 能力成熟度等级

对软件过程的改进是在完成一个一个小的改进步骤基础之上不断进行的渐进过程,而不是一蹴而就的彻底革命。在CMM中把软件过程从无序到有序的进化过程分成5个阶段,并把这些阶段排序,形成5个逐层提高的等级。这5个成熟度等级定义了一个有序的尺度,用以测量软件组织的软件过程成熟度和评价其软件过程能力,这些等级还能帮助软件组织把应做的改进工作排出优先次序。成熟度等级是妥善定义的向成熟软件组织前进途中的平台,每一个成熟度等级都为过程的继续改进提供一个台阶。CMM通过定义能力成熟度的5个等级,引导软件开发组织不断识别出其软件过程的缺陷,并指出应该做哪些改进,但是,它并不提供做这些改进的具体措施。

能力成熟度的5个等级从低到高是:初始级、可重复级、已定义级、已管理级和优化级。下面介绍能力成熟度的这5个等级。

1.初始级

软件过程的特征是无序的,有时甚至是混乱的。几乎没有什么过程是经过定义的,项目能否成功完全取决于个人能力。

处于这个最低成熟度等级的组织,基本上没有健全的软件工程管理制度。每件事情都以特殊的方法来做。如果一个项目碰巧由一个有能力的管理员和一个优秀的软件开发组承担,则这个项目可能是成功的。但是,通常的情况是,由于缺乏健全的总体管理和详细计划,延期交付和费用超支的情况经常发生。结果,大多数行动只是应付危机,而不是执行事先计划好的任务。处于成熟度等级1的组织,由于软件过程完全取决于当前的人员配备,所以具有不可预测性,人员变了过程也随之改变,因此,不可能准确地预测产品的开发时间和成本。

目前,世界上大多数软件开发公司都处于成熟度等级1。

2.可重复级

建立了基本的项目管理过程,以追踪成本、进度和功能性。必要的过程规范已经建立起来了,使得可以重复以前类似项目所取得的成功。

在这一级,有些基本的软件项目管理行为、设计和管理技术,是基于相似产品中的经验确定的,因此称为“可重复”。在这一级采取了一些措施,这些措施是实现一个完备过程必不可少的第1步。典型的措施包括仔细地跟踪费用和进度。不像在第1级那样,处于危机状态下才采取行动,管理人员在问题出现时可及时发现,并立即采取补救行动,以防止问题变成危机。关键是,如果没有采取这些措施,要在问题变得无法收拾前发现它们是不可能的。在一个项目中采取的措施,也可用来为未来的项目制定实现期限和费用的计划。

3.已定义级

用于管理和工程活动的软件过程已经文档化和标准化,并且已经集成到整个组织的软件过程中。所有项目都使用文档化的、组织批准的过程来开发和维护软件。这一级包含了第2级的所有特征。

在这一级已经为软件过程编制了完整的文档。对软件过程的管理方面和技术方面都明确地做了定义,并按需要不断地改进软件过程。已经采用评审的办法来保证软件的质量。在这一级可采用诸如CASE环境之类的软件工具或开发环境来进一步提高软件质量和生产率。而在第1级(初始级)中,采用“高技术”只会使这一危机驱动的软件过程更混乱。

4.已管理级

已收集了软件过程和产品质量的详细度量数据,使用这些详细的度量数据,能够定量地理解和控制软件过程和产品。这一级包含了第3级的所有特征。

处于第4级的公司为每个项目都设定质量和生产目标,并不断地测量这两个量,当偏离目标太多时,就采取行动来修正。

5.优化级

通过定量的反馈能够实现持续的过程改进,这些反馈是从过程及对新想法和技术的测试中获得的。这一级包含了第4级的所有特征。

处于第5级的组织的目标是持续地改进软件过程。这样的组织使用统计质量和过程控制技术。从各个方面获得的知识将运用在未来的项目中,从而使软件过程进入良性循环,使生产率和质量稳步提高。

经验表明,提高一个完整的成熟度等级通常需要花18个月到3年的时间,但是从第1级上升到第2级有时要花3年甚至5年时间。这表明要向一个迄今仍处于特殊的和被动的行动方式的公司灌输系统的方式,将多么困难。

2.9.3 关键过程域

能力成熟度模型并不详细描述所有与软件开发和维护有关的过程,但是,有一些过程是决定过程能力的关键因素,这就是CMM所称的关键过程域。关键过程域是达到一个成熟度等级的必要条件。

除第1级成熟度之外,每个成熟度等级都包含几个关键过程域,指明了为改进其软件过程,软件开发组织应该重视的区域,同时也指明了为达到某个成熟度等级所必须解决的问题。下面给出在每个成熟度等级应该实现的关键过程域。注意,下面列出的关键过程域是累加的,例如,第3级中包含了第2级的所有关键过程域再加上第3级特有的关键过程域。

1.成熟度第2级

① 软件配置管理。

② 软件质量保证。

③ 软件子合同管理。

④ 软件项目跟踪和监督软件。

⑤ 项目计划。

⑥ 需求管理。

2.成熟度第3级

① 同事复审。

② 组间协作。

③ 软件产品工程。

④ 集成的软件管理。

⑤ 培训计划。

⑥ 组织过程定义。

⑦ 组织过程焦点。

3.成熟度第4级

① 软件质量管理。

② 定量的过程管理。

4.成熟度第5级

① 过程变化管理。

② 技术变化管理。

③ 错误预防。

2.9.4 应用CMM

美国国防部(DoD)投资研究CMM的最初目标之一是,评价投标为DoD生产软件的承包商的软件过程,将合同给那些过程较成熟的承包商,以此来提高国防软件的质量。现在,CMM的应用已经远远超出了改进DoD软件过程这个目标,正在被众多希望提高软件质量和生产率的软件开发组织所应用。

CMM的用途主要有两个:软件开发组织用它来改进开发和维护软件的过程;政府或商业企业用它来评价与一个特定的软件公司签订软件项目合同的风险。

为了帮助各个软件组织达到更高成熟度等级,软件工程研究所已经设计了一系列成熟度提问单,作为成熟度等级评估的基础。评估的目标是,明确一个组织当前使用的软件过程的缺点,并指出该组织改进其软件过程的方法。

小结

软件过程是为了获得高质量软件产品所需要完成的一系列任务的框架,它规定了完成各项任务的工作步骤。软件过程必须科学、合理,才能开发出高质量的软件产品。

按照在软件生命周期全过程中应完成的任务的性质,在概念上可以把软件生命周期划分成问题定义、可行性研究、需求分析、概要设计、详细设计、编码和单元测试、综合测试以及维护8个阶段。实际从事软件开发工作时,软件规模、种类、开发环境、使用的技术方法等因素,都影响阶段的划分,因此,一个科学、有效的软件过程应该定义一组适合于所承担的项目特点的任务集合。

生命周期模型(即软件过程模型)规定了把生命周期划分成的阶段及各个阶段的执行顺序。本章介绍了5类典型的软件生命周期模型。瀑布模型历史悠久、广为人知,它的优势在于它是规范的、文档驱动的方法。这种模型的问题是,最终交付的产品可能不是用户真正需要的。

快速原型模型正是为了克服瀑布模型的缺点而提出来的。它通过快速构建起一个可运行的原型系统,让用户试用原型并收集用户反馈意见的办法,获取用户的真实需求。

增量模型具有能在软件开发的早期阶段使投资获得明显回报和易于维护的优点。但是,要求软件具有开放结构是使用这种模型时固有的困难。

风险驱动的螺旋模型适用于大规模的内部开发项目,但是,只有在开发人员具有风险分析和排除风险的经验及专门知识时,使用这种模型才会获得成功。

当使用面向对象范型开发软件时,软件生命周期必须是循环的。也就是说,软件过程必须支持反馈和迭代。喷泉模型是一种典型的适合于面向对象范型的过程模型。

能力成熟度模型(CMM),是改进软件过程的一种策略。它的基本思想是,因为问题是管理软件过程的方法不恰当引起的,所以运用新软件技术并不会自动提高软件生产率和软件质量,应当下大力气改进对软件过程的管理。对软件过程的改进不可能一蹴而就,因此,CMM以增量方式逐步引入变化,它明确地定义了5个不同的成熟度等级,一个软件开发组织可用一系列小的改良性步骤迈入更高的成熟度等级。

每个软件开发组织都应该选择适合于本组织及所要开发的软件特点的软件生命周期模型。这样的模型应该把各种生命周期模型的合适特性有机地结合起来,以便尽量减少它们的缺点,充分利用它们的优点。

习题

一、判断题

1.瀑布模型的最大优点是将软件开发的各个阶段划分得十分清晰。

(  )

2.原型化开发方法包括生成原型和实现原型两个步骤。

(  )

3.软件过程改进也是软件工程的范畴。   

(  )

4.在软件开发中采用原型系统策略的主要困难是成本问题。

(  )

二、选择题

1.软件生命周期模型不包括(  )。

  A.瀑布模型 B.用例模型 C.增量模型 D.螺旋模型

2.包含风险分析的软件工程模型是(  )。

  A.喷泉模型 B.瀑布模型 C.增量模型 D.螺旋模型

3.软件过程是(  )。

  A.特定的开发模型   B.一种软件求解的计算逻辑

  C.软件开发活动的集合 D.软件生命周期模型

4.软件工程中描述生命周期的瀑布模型一般包括计划、需求分析、设计、编码、(  )、维护等几个阶段。

  A.产品发布 B.版本更新 C.可行性分析 D.测试

5.软件开发的瀑布模型,一般都将开发过程划分为:分析、设计、编码和测试等阶段,一般认为可能占用人员最多的阶段是(  )。

  A.分析阶段 B.设计阶段 C.编码阶段 D.测试阶段

6.增量模型本质上是一种(  )。

  A.线性顺序模型 B.整体开发模型 C.非整体开发模型 D.螺旋模型

7.螺旋模型综合了(  )的优点,并增加了风险分析。

  A.增量模型和喷泉模型 B.瀑布模型和演化模型

  C.演化模型和喷泉模型 D.原型和喷泉模型

8.CMM模型将软件过程的成熟度分为5个等级。在(  )使用定量分析来不断地改进和管理软件过程。

  A.管理级 B.优化级 C.定义级 D.可重复级

三、简答题

1.如何理解软件生命周期的内在特征?

2.对比瀑布模型、原型模型、增量模型和螺旋模型。

3.当需求不能一次搞清楚,且系统需求比较复杂时应选用哪种开发模型比较适合?

4.RUP包含了哪些核心工作流和哪些核心支持工作流?

5.XP是一种什么样的模型?

6.每个软件企业遵循的软件开发过程都是一样的吗?

7.请简述软件过程。

8.敏捷方法的核心价值观有哪些?它对传统方法的“反叛”体现在哪些方面?

9.请简述CMM的作用。

10.请简述CMM软件过程成熟度的5个级别,以及每个级别对应的标准。

11.假设你要开发一个软件,它的功能是把73624.9385这个数开平方,所得到的结果应该精确到小数点后4位。一旦实现并测试完之后,该产品将被抛弃。你打算选用哪种软件生命周期模型?请说明你做出这样选择的理由。

目录

  • 版权
  • 内容提要
  • 出版者的话
  • 第4版前言
  • 第1篇 软件工程与软件过程
  • 第1章 软件工程概述
  • 第2章 软件过程
  • 第2篇 传统方法学
  • 第3章 结构化分析
  • 第4章 结构化设计
  • 第5章 结构化实现
  • 第3篇 面向对象方法学
  • 第6章 面向对象方法学导论
  • 第7章 面向对象分析
  • 第8章 面向对象设计
  • 第9章 面向对象实现
  • 第10章 统一建模语言
  • 第4篇 软件项目管理
  • 第11章 计划
  • 第12章 组织
  • 第13章 控制
  • 第14章 软件维护与软件文档
  • 第5篇 高级课题
  • 第15章 形式化方法
  • 第16章 软件重用
  • 参考文献

推荐用户

同系列书

人邮微信
本地服务
教师服务
教师服务
读者服务
读者服务
返回顶部
返回顶部