软件开发模型给出了软件开发活动各阶段之间的关系,它是软件开发过程的概括,是软件工程的重要内容。软件开发模型为软件工程管理提供了里程碑和进度表,为软件开发过程提供了原则和方法。
软件开发模型大体上可分为三种类型。第一种是以软件需求完全确定为前提的瀑布模型;第二种是在软件开发初始阶段只能提供基本需求时采用的迭代式或渐进式开发模型,例如,喷泉模型、螺旋模型、统一开发过程和敏捷方法等;第三种是以形式化开发方法为基础的变换模型。
1. 瀑布模型
软件开发生命周期(Software Development Life Cycle,SDLC)模型的发展体现了软件工程理论的发展。在最早的时候,软件的开发过程处于无序和混乱的情况,人们为了能够控制软件的开发过程,就将软件开发严格区分为多个不同的阶段,并在阶段之间加上严格的审查,这就是瀑布模型产生的起因。瀑布模型是一种严格定义方法,它将软件开发的过程分为软件计划、需求分析、软件设计、程序编码、软件测试和运行维护6个阶段,形如瀑布流水,最终得到软件产品,如图3-1所示。
图 3-1 瀑布模型
瀑布模型是一个线性顺序模型,支持直线开发。它假设当线性序列完成之后就能交付一个完善的系统,并没有考虑软件的演化特征。其优点是强调开发的阶段性、早期计划及需求调查和产品测试,以这样严格的方式构造软件,开发人员很清楚每一步应该做什么,有利于项目管理。然而,在瀑布模型中,依赖于早期进行的需求调查,不能适应需求的变化;由于是单一流程,开发中的经验教训不能反馈应用于本产品的过程;风险往往迟至后期的开发阶段才显露出来,从而失去了及早纠正的机会。在瀑布模型中,需求或设计中的错误往往只有到了项目后期才能够被发现,对于项目风险的控制能力较弱,从而导致项目常常延期完成,开发费用超出预算。
2. 演化模型
演化模型主要针对事先不能完整定义需求的软件开发,是在快速开发一个原型的基础上,根据用户在调用原型的过程中提出的反馈意见和建议,对原型进行改进,获得原型的新版本,重复这一过程,直到演化成最终的软件产品。
演化模型的主要优点是,任何功能一经开发就能进入测试,以便验证是否符合产品需求,可以帮助导引出高质量的产品要求。其主要缺点是,如果不加控制地让用户接触开发中尚未稳定的功能,可能对开发人员及用户都会产生负面的影响。
3. 螺旋模型
螺旋模型是瀑布模型与演化模型相结合,并加入两者所忽略的风险分析所建立的一种软件开发模型。螺旋模型是一种演化软件过程模型,它将原型实现的迭代特征与线性顺序模型中控制的和系统化的方面结合起来,使软件的增量版本的快速开发成为可能。在螺旋模型中,软件开发是一系列的增量发布。
螺旋模型沿着螺线进行若干次迭代,每次迭代都包括制订计划、风险分析、实施工程和客户评估四个方面的工作。螺旋模型强调风险分析,使得开发人员和用户对每个演化层出现的风险有所了解,继而做出应有的反应。因此,特别适用于庞大、复杂并具有高风险的系统。图3-2即为螺旋模型的结构图。
图 3-2 螺旋模型
与瀑布模型相比,螺旋模型支持用户需求的动态变化,为用户参与软件开发的所有关键决策提供了方便,有助于提高软件的适应能力,并且为项目管理人员及时调整管理决策提供了便利,从而降低了软件开发的风险。在使用螺旋模型进行软件开发时,需要开发人员具有相当丰富的风险评估经验和专门知识。另外,过多的迭代次数会增加开发成本,延迟提交时间。
4. 喷泉模型
喷泉模型是一种以用户需求为动力,以对象为驱动的模型,主要用于描述面向对象的软件开发过程。该模型认为软件开发过程自下而上的各阶段是相互重叠和多次反复的,就像水喷上去又可以落下来,类似一个喷泉。各个开发阶段没有特定的次序要求,并且可以交互进行,可以在某个开发阶段中随时补充其他任何开发阶段中的遗漏。
在喷泉模型中,各活动之间无明显边界,例如,分析和设计之间没有明显的边界。这种特性称为无间隙性。由于对象概念的引入,只用类和关系来表达分析、设计和实现等活动,从而可以较容易地实现活动的迭代和无间隙,提高软件项目开发效率,节省开发时间。
5. 变换模型
变换模型是基于形式化规格说明语言和程序变换的软件开发模型,它对形式化的软件规格说明进行一系列自动或半自动的程序变换,最后映射为计算机能够接受的软件系统。为了确认形式化规格说明与软件需求的一致性,往往以形式化规格说明为基础开发一个软件原型,用户可以从人机界面、系统主要功能和性能等方面对原型进行评审。必要时,可以修改软件需求、形式化规格说明和原型,直至原型被确认为止。这时,开发人员即可对形式化的规格说明进行一系列的程序变换,直至生成计算机可以接受的目标代码。
程序变换是软件开发的另一种方法,其基本思想是把程序设计的过程分为生成阶段和改进阶段。首先,通过对问题的分析制订形式规范并生成一个程序,通常是一种函数型的递归方程。然后,通过一系列保持正确性的源程序到源程序的变换,把函数型风格转换成过程型风格,并进行数据结构和算法的求精,最终得到一个有效的面向过程的程序。这种变换过程是一种严格的形式推导过程,所以只需对变换前的程序的规范加以验证,变换后的程序的正确性将由变换法则的正确性来保证。
变换模型的优点是解决了代码结构经多次修改而变坏的问题,减少了许多中间步骤(例如,设计、编码和测试等)。但是,变换模型仍有较大局限,以形式化开发方法为基础的变换模型需要严格的数学理论和一整套开发环境的支持。
6. 智能模型
智能模型也称为基于知识的软件开发模型,它综合了上述若干模型,并把希赛网系统结合在一起。该模型应用基于规则的系统,采用规约和推理机制,帮助开发人员完成开发工作,并使维护在系统规格说明一级进行。为此,需要建立知识库,将模型本身、软件工程知识与特定领域的知识分别存入知识库。
7. V模型
V模型是在快速应用开发模型基础上演变而来,由于将整个开发过程构造成一个V字形而得名。V模型应用在软件测试方面,和瀑布模型有着一些共同的特征。V模型中的过程从左到右,描述了基本的开发过程和测试行为,其价值在于它非常明确地标明了测试过程中存在的不同级别,并且清楚地描述了这些测试阶段和开发过程各阶段的对应关系,如图3-3所示。
图3-3 V模型
在V模型中,单元测试是基于代码的测试,最初由开发人员执行,以验证程序代码的各个部分是否已达到预期的功能要求;集成测试验证了两个以上单元之间的集成是否正确,并有针对性地对详细设计中所定义的各单元之间的接口进行检查;在所有单元测试和集成测试完成后,系统测试开始以客户环境模拟系统的运行,以验证系统是否达到了在概要设计中所定义的功能和性能;最后,当技术部门完成了所有测试工作后,由业务希赛网或用户进行验收测试,以确保产品能真正符合用户业务上的需要。
V模型强调软件开发的协作和速度,将软件实现和验证有机地结合起来,在保证较高的软件质量情况下缩短开发周期。V模型适合企业级的软件开发,它更清楚地揭示了软件开发过程的特性及其本质。
8. 快速应用开发
快速应用开发(Rapid Application Development,RAD)是一种比传统生命周期法快得多的开发方法,它强调极短的开发周期。RAD 模型是瀑布模型的一个高速变种,通过使用基于构件的开发(Component Based Software Development,CBSD)方法获得快速开发。如果需求理解得很好,且约束了项目范围,利用这种模型可以很快开发出功能完善的信息系统。RAD的流程从业务建模开始,随后是数据建模、过程建模、应用生成、测试与交付。有关CBSD方法的详细知识,将在3.2.1节进行介绍。
RAD通过大量使用可复用构件,加快了开发速度。如果一个业务能够被模块化,使得其中的每一个主要功能均可以在不到三个月的时间内完成,那么就适合使用RAD来开发。每个主要功能可由一个单独的RAD组来实现,最后再集成起来,形成一个整体。但是,RAD也具有以下局限性:
(1)并非所有应用都适合RAD。RAD对模块化要求比较高,如果有哪一项功能不能被模块化,那么RAD所需要的构件就会有问题;如果高性能是一个指标,且该指标必须通过调整接口使其适应系统构件才能获得,则RAD也有可能不能奏效。
(2)开发者和客户必须在很短的时间完成一系列的需求分析,任何一方配合不当,都会导致RAD项目失败。
(3)RAD只能用于管理信息系统的开发,不适合技术风险很高的情况。例如,当一个新系统要采用很多新技术,或当新系统要与现有系统有较高的互操作性时,就不适合使用RAD。
9. 统一过程
统一过程(Unified Process,UP)是一个通用过程框架,它是基于构件的,在为软件系统建模时,UP使用的是UML。与其他软件过程相比,UP具有三个显著的特点,即用例驱动、以架构为中心、迭代和增量。有关用例的概念,将在3.17节进行介绍;有关软件架构的详细知识,将在3.2.2节进行介绍。
UP中的软件过程可以划分为四个阶段,分别是初始阶段、细化阶段、构建阶段和交付阶段。每个阶段结束时都要安排一次技术评审,以确定本阶段的目标是否已经满足。如果评审结果令人满意,就可以允许项目进入下一个阶段。基于UP的软件过程是一个迭代过程,每次经过四个阶段就会产生一代软件。除非产品退役,否则通过重复同样的四个阶段,产品将演化为下一代产品,但每一次的侧重点都将放在不同的阶段上。
初始阶段的任务是为系统建立业务模型并确定项目的边界。在初始阶段,必须识别所有与系统交互的外部实体(执行者),定义系统与外部实体交互的特性。在这个阶段中,所关注的是整个项目的业务和需求方面的主要风险。对于建立在原有系统基础上的开发项目来说,初始阶段可能很短。
细化阶段的任务是分析问题领域,建立完善的架构,淘汰项目中较高风险的元素。在细化阶段,必须在理解整个系统的基础上,对架构做出决策,包括其范围、主要功能和诸如性能等非功能需求,同时为项目建立支持环境。在细化阶段,可执行的原型依赖于项目的范围、规模和风险等因素。必须至少处理初始阶段中识别的关键用例,因为关键用例通常揭示了项目的主要技术风险。
在构建阶段,要开发所有剩余的构件和应用程序功能,将这些构件集成为产品,并进行详细测试。从某种意义上说,构建阶段是一个制造过程,其重点放在管理资源及控制操作,以优化成本、进度和质量。构建阶段的主要任务是通过优化资源和避免不必要的报废和返工,使开发成本降到最低;完成所有所需功能的分析、开发和测试,快速完成可用的版本;确定软件、场地和用户是否已经为部署软件作好准备。
当基线已经足够完善,可以安装到最终用户实际环境中时,则进入交付阶段。交付阶段的重点是确保软件对最终用户是可用的。交付阶段的主要任务是进行β测试,制作产品发布版本;对最终用户支持文档定稿;按用户的需求确认新系统;培训用户和维护人员;获得用户对当前版本的反馈,基于反馈调整产品,例如,进行调试、性能或可用性的增强等。
从以上介绍可以看出,UP由于太过于庞大和复杂,相对于轻量级的敏捷方法来说,显得死板和难以实施。UP不但不能快速适应需求的变化,而且变更一个需求要经历复杂的过程和很多额外的工作。对于较小的组织和项目来说,使用敏捷方法可能比较合适,而使用UP似乎有些费力不讨好。
10. 敏捷方法
敏捷方法是一系列方法的总称,虽然这些方法的名称、理念、过程、术语都不尽相同,但相对于“非敏捷”而言,它们更强调开发团队与用户之间的紧密协作、面对面的沟通、频繁交付新的软件版本、紧凑而自我组织型的团队等,也更注重人的作用。敏捷方法强调,让客户满意和软件尽早增量发布;小而高度自主的项目团队;非正式的方法;最小化软件工程工作产品以及整体精简开发。产生这种情况的原因是,在绝大多数软件开发过程中,提前预测哪些需求是稳定的和哪些需求会变化非常困难;对于软件项目构建来说,设计和实现是交错的;从指定计划的角度来看,分析、设计、实现和测试并不容易预测;可执行原型和部分实现的可运行系统是了解用户需求和反馈的有效媒介。
目前,主要的敏捷方法有极限编程(eXtreme Programming,XP)、自适应软件开发(Adaptive Software Development,ASD)、水晶方法(Crystal)、特性驱动开发(Feature Driven Development,FDD)、动态系统开发方法(Dynamic Systems Development Method,DSDM)测试驱动开发(Test-Driven Development,TDD)、敏捷数据库技术(Agile Database Techniques,AD)和精益软件开发(Lean Software Development)和Scrum等。虽然这些过程模型在实践上有差异,但都是遵循了敏捷宣言或者是敏捷联盟所定义的基本原则。
敏捷方法是一种以人为核心、迭代、循序渐进的开发方法。在敏捷方法中,软件项目的构建被切分成多个子项目,各个子项目成果都经过测试,具备集成和可运行的特征。在敏捷方法中,从开发者的角度来看,主要的关注点有短平快的会议、小版本发布、较少的文档、合作为重、 客户直接参与、自动化测试、适应性计划调整和结对编程;从管理者的角度来看,主要的关注点有测试驱动开发、持续集成和重构。
与UP相比,敏捷方法的周期可能更短。敏捷方法在几周或几个月的时间内完成相对较小的功能,强调的是能尽早将尽量小的可用的功能交付使用,并在整个项目周期中持续改善和增强,并且更加强调团队中的高度协作。相对而言,敏捷方法主要适用于以下场合:
(1)项目团队的人数不能太多,适合于规模较小的项目。
(2)项目经常发生变更。敏捷方法适用于需求萌动并且快速改变的情况,如果系统有比较高的关键性、可靠性、安全性方面的要求,则可能不完全适合。
(3)高风险项目的实施。
(4)从组织结构的角度看,组织结构的文化、人员、沟通性决定了敏捷方法是否适用。与这些相关联的关键成功因素有组织文化必须支持谈判、人员彼此信任、人少但是精干、开发人员所作的决定得到认可、环境设施满足团队成员之间快速沟通的需要。