【软件工程】深入浅出常见软件过程模型(瀑布模型 / 原型化模型 / 演化模型 / 迭代模型...)

软件过程模型

软件过程是为了获得高质量软件,所需要完成的一系列任务。它定义了完成各项任务的工作步骤,把任务、人员和工具密切地结合在一起。

软件过程模型就是对软件过程的一个抽象描述,常见的软件过程模型,包括瀑布模型、原型化模型、迭代式开发和可转换模型。

  • 瀑布模型:瀑布模型将软件开发的基本活动看成是一系列相互独立的阶段,这些活动以线性的方式顺序执行;
  • 原型化模型:主要是解决需求不确定问题,原型是一个部分开发的产品,通过原型实现对系统的理解,有助于明确需求和选择可行的设计策略;
  • 迭代式开发:把描述、开发和验证等不同活动交织在一起,通过在开发过程中建立一系列版本,将系统进行逐步的交付和演化,从而实现软件的快速交付;
  • 可转换模型:利用自动化的手段,通过一系列的转换,把需求规格说明转化为一个可交付使用的系统;

瀑布模型

瀑布模型于 1970 年提出,直到 20 世纪 80 年代早期它一直是唯一被广泛采用的软件开发模型,它把软件的生命周期划分为需求定义与分析、软件设计、软件构造、软件测试和运行维护等若干基本活动,并且规定了这些活动自上而下相互衔接的固定次序,如同瀑布流水一般。

在瀑布模型中,软件开发的各项活动严格按照线性方式进行,当前活动接受上一项活动的工作结果,实施完成所需的工作内容。当前活动的工作结果再进行验证,如果验证通过,就把这个结果作为下一项活动的输入,从而继续进行下一项活动,否则返回修改。

瀑布模型强调软件文档的作用,要求每个阶段都要仔细地进行验证。

由于软件的行为只有在运行过程中才能显现出来,因此瀑布模型只有到测试阶段才能真正地验证和确认软件的功能和性能,但这时所有的代码都已经开发完成,很难返回去纠正需求的问题和设计的缺陷。显然这种模型虽然对各个阶段进行严格控制,但是却缺少了对变化的适应。

瀑布模型看似美丽却不现实,目前已经很少在业界使用。它的主要问题在于:

  • 各个阶段的划分完全固定,阶段之间产生大量的文档,增加了开发工作量。
  • 由于开发过程是线性的,用户只有在整个过程结束时才能看到开发成果,开发过程中间很难响应用户的变更要求,早期的错误也要等到开发后期的测试阶段才能发现,这样会产生严重的后果。

因此,瀑布模型仅适用于软件需求在开发初期就可以被完整地确定的软件项目,而且用户使用的环境也要很稳定。显然这样的要求是不现实的。

软件开发作为一个问题求解过程,应当具备什么特点?

一般来说,软件需要解决以前从未解决的问题,或者当前的解决方案需要不断更新,以适应业务环境的不断变化,因此软件开发具有迭代性,需要不断的反复尝试,通过比较和选择不同的设计,最终确定令人满意的问题解决方案。

从瀑布模型的起源来看,它借鉴了硬件领域的做法,是从制造业的角度看待软件开发。制造业是重复生产某一特定的产品,但是软件开发并不是这样。随着人们对问题的逐步理解,以及对可选方案的评估,软件在不断地演化。因此软件开发是一个创造的过程,而不是一个制造的过程。


原型化模型

在实际的软件开发过程中,最常见的问题是需求的不确定性。用户往往可以很清楚地描述现实中遇到的问题,但是由于所开发的软件在现实中并不存在,因此用户也说不清楚到底需要什么样的功能才能解决当前的问题。这种情况下,应该怎么办呢?

如果用户能够看到软件的操作界面并且实际操作的话,他马上就会明白这些功能是不是自己需要的,另外设计的原型化也可以帮助开发人员评价和分析不同方案的实现效果,最终决定更为合适的设计策略。在上述情况下,我们都实现了产品的一部分,这个部分的产品就称为原型

原型化模型需要迅速建造一个可运行的软件原型,使用户和开发人员对系统的相关方面进行检查,以决定是否合适和恰当。原型化开发指很多种方法,既可以是可操作的软件界面,也可以是纸上原型。

纸上原型即在纸张和卡片上手绘或打印界面的元素,再把他们组合拼接,粘贴到一个背景板上,构造成模拟真实产品界面的原型。

相比于可操作的软件界面来说,纸上原型可以构建得更快,修改更灵活。

原型化模型(Prototyping Model)有两条分支

原型化模型的初衷是为了解决用户需求模糊的问题,通过快速做一个"小样(原型)"给用户看。根据看完之后的处理方式,它分成了两派:

  • 抛弃型原型(Throw-away Prototyping): 原型只是个"诱饵"。用户看完了、需求明确了,这个原型就被直接扔掉,开发团队拿着明确的需求,从零开始用瀑布模型等传统方法写正式代码。
  • 演化型原型(Evolutionary Prototyping): 原型是"种子"。用户看完提出意见后,开发团队在原型的基础上不断修改、填充和扩展,直到它最终成长为最终的软件产品。

什么是演化模型(Evolutionary Model)?

演化模型是一种开发思想的统称 。它强调软件不可能一步到位,而是要通过多次迭代、渐进式地演化出来。

只要是符合"迭代、渐进、不断演化"特征的模型,都可以算作演化模型大家庭的成员。这个家族里主要包括:

  1. 演化型原型模型(也就是上面说的那种不抛弃原型的做法)
  2. 螺旋模型(Spiral Model)
  3. 增量模型(Incremental Model)(在广义上也常被归为演化思想)

迭代式开发

今天的商业环境要求软件企业更快速地推出新产品,再加上用户需求存在不确定性和持续变化的特点,传统的瀑布模型无法适应实际需要,必须使用新的过程模型来缩短软件项目的开发周期。

迭代式的开发使得软件系统能够逐步地进行交付,开发人员在完成一部分功能之后形成一个产品版本,然后将其发布给用户使用。当用户使用第一个版本的时候,开发人员继续开发下一个版本,如此迭代循环。这样不仅可以缩短产品的开发周期,还可以更好地获得用户对产品的反馈。

增量模型和迭代模型是迭代式开发的两种形式:

  • 在增量模型中,首先定义一个小的功能系统,然后在每一个新的发布中逐步增加功能,直到构造出全部的功能;
  • 在迭代模型中,一开始就提交一个完整的系统,但每个功能并不完善,在后续的发布中再对各子系统功能补充、完善;

可转换模型

可转换模型 (在很多教材中也被称为变换模型,Transformational Model)是一个走"硬核技术路线"的过程模型。

它试图把软件开发变成一场"数学公式推导",利用自动化工具,将严谨的需求说明直接"转换"成最终的可用系统。

犯错是人的天性,往往是由于人为的错误造成了软件的缺陷,因此可转换模型是采用形式化的数学方法描述系统,并利用自动化手段,通过一系列转换,将形式化的需求规格说明变为可交付使用的系统。

在传统模型(如瀑布模型)中,程序员看懂需求后,需要人工把需求翻译成代码。这中间极易因为"理解偏差"或"粗心大意"写出 Bug。

而可转换模型认为:既然人工写代码容易出错,那能不能用数学的方法,让计算机自己把需求"变"成代码? 因此,它的核心支撑技术是形式化方法(Formal Methods)------用严格的数学语言(如集合论、数理逻辑)来极其精确地描述软件需求。

由于数学方法具有严密性和准确性,形式化方法所交付的系统具有较少的缺陷和较高的安全性。这种模型特别适合于那些对安全性、可靠性和保密性要求极高的软件系统,这些系统需要在投入运行前进行严格的验证。

当然建立形式化的数学描述是一个比较困难的工作,目前这种方法主要还是应用于有限状态的嵌入式系统中。

可转换模型的工作流程就像一个自动化的"流水线":

  1. 形式化规格说明: 开发人员和数学专家一起,用数学语言写出一份毫无歧义、绝对精确的需求规格说明书
  2. 自动化/半自动化变换: 将这份数学说明输入到专用的自动转换工具中。工具会根据预设的变换规则,进行一系列保持正确性的数学变换。
  3. 层层优化: 需求被一步步转换为高级语言代码、再到目标代码,每一次转换都有数学定理保证"新生成的代码绝对符合上一层的需求"。
  4. 得到系统: 最终直接编译生成可交付使用的软件系统。

优点:品质极高

  • 缺陷极少、安全性极高: 因为每一步转换都有数学逻辑做担保,软件几乎不会出现逻辑漏洞或低级 Bug。
  • 无需传统测试: 它不需要做大量的单元测试和集成测试,因为系统在理论上已经被"证明"是正确的。

缺点:难度极大

  • 门槛高到飞起: 要求开发人员必须是"数学大牛",懂得如何用形式化语言写需求(这非常痛苦)。
  • 客户根本看不懂: 没办法跟客户确认需求,因为客户面对一堆数学公式和集合符号只会抓狂。
  • 工具链不成熟: 目前能够实现完全自动转换的领域和工具非常有限。

📌 适用场景

正因为其"高成本、高可靠性"的特点,可转换模型绝对不会用来开发普通的电商网站或手机游戏,它只服务于极端关键系统,例如:

  • 航天航空控制软件(如火箭发射系统)
  • 核电站控制系统
  • 军事防务系统
  • 医疗重症监护设备软件