软件维护概述
软件维护如今已成为 SDLC 中被广泛接受的一部分。它代表软件产品交付后进行的所有修改和更新。需要修改的原因有很多,下面简要提到其中一些:
市场条件 - 政策会随时间而变化,例如税收和新引入的限制,例如如何维护簿记,可能会引发修改的需要。
客户要求 - 随着时间的推移,客户可能会要求软件提供新特性或功能。
主机修改 - 如果目标主机的任何硬件和/或平台(例如操作系统)发生变化,则需要更改软件以保持适应性。
组织变更 - 如果客户端发生任何业务级别变化,例如组织实力下降、收购另一家公司、组织开展新业务,则可能需要修改原始软件。
维护类型
在软件生命周期中,维护类型可能因其性质而异。它可能只是一些用户发现的 bug 的例行维护任务,也可能根据维护规模或性质本身就是一个大事件。以下是根据其特征划分的一些维护类型:
纠正性维护 - 这包括为纠正或修复问题而进行的修改和更新,这些问题由用户发现或由用户错误报告得出。
适应性维护 - 这包括为使软件产品保持最新状态并适应不断变化的技术和商业环境而进行的修改和更新。
完善性维护 - 这包括为使软件长期可用而进行的修改和更新。它包括新功能、新用户需求,用于改进软件并提高其可靠性和性能。
预防性维护 - 这包括修改和更新,以防止软件将来出现问题。它旨在解决目前并不重要但可能在未来引起严重问题的问题。
维护成本
报告表明维护成本很高。一项关于估算软件维护的研究发现,维护成本高达整个软件过程周期成本的 67%。

平均而言,软件维护成本占所有 SDLC 阶段的 50% 以上。有各种因素会导致维护成本升高,例如:
影响维护成本的现实因素
- 任何软件的标准使用年限都被认为是 10 到 15 年。
- 较旧的软件旨在在内存和存储容量较少的慢速机器上运行,无法与现代硬件上新出现的增强型软件相抗衡。
- 随着技术的进步,维护旧软件的成本变得很高。
- 大多数维护工程师都是新手,并使用反复试验的方法来纠正问题。
- 通常,所做的更改很容易损害软件的原始结构,使任何后续更改变得困难。
- 更改通常没有记录,这可能会在将来引起更多冲突。
影响维护成本的软件端因素
- 软件程序的结构
- 编程语言
- 对外部环境的依赖
- 人员可靠性和可用性
维护活动
IEEE 为顺序维护过程活动提供了一个框架。它可以以迭代方式使用,并且可以扩展,以便包含定制的项目和流程。

这些活动与以下每个阶段密切相关:
识别和跟踪 - 它涉及与识别修改或维护要求有关的活动。它由用户生成,或者系统本身可以通过日志或错误消息报告。这里,维护类型也被分类。
分析 - 分析修改对系统的影响,包括安全和保障影响。如果可能的影响很严重,则寻找替代解决方案。然后将一组所需的修改具体化为需求规范。分析修改/维护的成本并得出估算。
设计 - 根据上一阶段设定的需求规范设计需要替换或修改的新模块。创建测试用例以进行验证和确认。
实施 - 在设计步骤中创建的结构化设计的帮助下对新模块进行编码。每个程序员都应该并行进行单元测试。
系统测试 - 在新创建的模块之间进行集成测试。新模块和系统之间也进行集成测试。最后,按照回归测试程序对系统进行整体测试。
验收测试 - 在内部测试系统后,在用户的帮助下进行验收测试。如果在此状态下,用户抱怨一些问题,则会解决这些问题或注意到在下一次迭代中解决这些问题。
交付 - 验收测试后,系统将通过小型更新包或全新安装部署到整个组织。软件交付后,在客户端进行最终测试。
除用户手册的硬拷贝外,如果需要,还提供培训设施。
维护管理 - 配置管理是系统维护的重要组成部分。它借助版本控制工具来控制版本、半版本或补丁管理。
软件再造
当我们需要更新软件以使其符合当前市场,而不影响其功能时,这称为软件再造。这是一个彻底的过程,其中软件设计被改变,程序被重写。
旧版软件无法跟上市场上最新的技术。随着硬件的过时,软件更新成为一个令人头疼的问题。即使软件随着时间的推移而变旧,其功能也不会变旧。
例如,Unix 最初是用汇编语言开发的。当 C 语言出现时,Unix 用 C 语言重新设计,因为用汇编语言工作很困难。
除此之外,有时程序员会注意到软件的某些部分比其他部分需要更多的维护,它们也需要重新设计。

重新设计过程
- 决定要重新设计什么。是整个软件还是其中的一部分?
- 执行逆向工程,以获得现有软件的规范。
- 如果需要,重组程序。例如,将面向功能的程序更改为面向对象的程序。
- 根据需要重新构造数据。
- 应用正向工程概念以获得重新设计的软件。
软件再工程中使用了一些重要术语
逆向工程
这是一个通过彻底分析、理解现有系统来实现系统规范的过程。这个过程可以看作是逆向 SDLC 模型,即我们试图通过分析较低的抽象级别来获得更高的抽象级别。
现有系统是以前实现的设计,我们对此一无所知。然后,设计师通过查看代码进行逆向工程并尝试获得设计。有了设计,他们试图得出规范。因此,从代码到系统规范的逆向。

程序重构
这是一个重新构建和重建现有软件的过程。它都是关于重新安排源代码,无论是使用相同的编程语言还是从一种编程语言到另一种编程语言。重构可以是源代码重构和数据重构,也可以是两者兼而有之。
重构不会影响软件的功能,但可以提高可靠性和可维护性。经常导致错误的程序组件可以通过重构进行更改或更新。
通过重构可以消除软件在过时硬件平台上的依赖性。
正向工程
正向工程是从通过逆向工程获得的现有规范中获取所需软件的过程。它假设过去已经完成了一些软件工程。
正向工程与软件工程过程相同,只有一个区别 - 它总是在逆向工程之后进行。

组件可重用性
组件是软件程序代码的一部分,它在系统中执行独立任务。它可以是一个小模块或子系统本身。
示例
网络上使用的登录程序可以被视为组件,软件中的打印系统可以看作是软件的一个组件。
组件具有高功能内聚性和较低的耦合率,即它们独立工作并且可以执行任务而不依赖于其他模块。
在 OOP 中,对象的设计非常具体,并且很少有机会在其他软件中使用。
在模块化编程中,模块被编码以执行特定任务,这些任务可以在许多其他软件程序中使用。
有一个全新的垂直领域,它基于软件组件的重用,被称为基于组件的软件工程 (CBSE)。

重用可以在各个级别进行
应用程序级别 - 整个应用程序用作新软件的子系统。
组件级别 - 使用应用程序的子系统。
模块级别 - 功能模块被重用。
软件组件提供接口,可用于在不同组件之间建立通信。
重用过程
可以采用两种方法:保持需求不变并调整组件,或保持组件不变并修改需求。

需求规范 - 借助现有系统、用户输入或两者,指定软件产品必须符合的功能性和非功能性需求。
设计 - 这也是标准的 SDLC 流程步骤,其中需求以软件术语定义。创建整个系统及其子系统的基本架构。
指定组件 - 通过研究软件设计,设计人员将整个系统划分为较小的组件或子系统。一个完整的软件设计变成了一组协同工作的庞大组件的集合。
搜索合适的组件 - 设计人员参考软件组件库,根据功能和预期的软件要求搜索匹配的组件。
合并组件 - 将所有匹配的组件打包在一起,形成完整的软件。