软件工程SoftwareEngineering第十五章软件维护15.1软件维护的概念15.2软件维护的内容15.3软件可维护性15.4软件维护的特点15.5软件维护的实施15.6维护“老化代码“15.7逆向工程和再工程小结15.1软件维护的概念15.1.1软件维护的定义属于软件维护工作的活动不只是对软件中的错误进行修改,只要是因为以下的原因之一产生的活动都属于软件维护:(1)对软件中的错误进行修改(2)因软件在使用过程中的软硬件环境发生变化,需要修改软件以适应这种变化。(3)用户要求增加新的功能,提高软件的性能等。(4)为适应新的工作要求而对软件部分或整体进行再工程(reengineer)由这些原因引起的维护活动可以归为以下几类:(1)改正性维护(Correctivemaintenance)(2)适应性维护(Adaptivemaintenance)(3)完善性维护(Perfectivemaintenance)(4)预防性维护(Preventivemaintenance)15.1.2影响维护工作的因素(1)系统大小。(2)系统的开发文档。(3)在程序中使用的、数学模型、任务的难度、IF嵌套深度、索引或下标数等,对维护工作量都有影响。15.1.3维护成本软件的维护成本体现为有形和无形两类。15.2软件维护的内容软件维护有改正性维护、适应性维护、完善性维护和预防性维护。1.改正性维护测试并不能发现所有的错误,因此必然有一部分隐含的错误在使用时才会被发现。对此类错误进行确定和修改的过程,就称为改正性维护。2.适应性维护随着计算机的飞速发展,计算机的软硬件环境在不断发生变化,硬件的性价比越来越高,操作系统的功能越来越强,越稳定,使用越来越方便。为了使应用软件适应这种变化而修改软件的过程称为适应性维护。3.完善性维护用户在使用软件的过程中,用户的工作流程、应用环境都会发生变化,因此会提出增加新的功能和改善性能的要求。这种增加软件功能、增强软件性能和提高软件运行效率而进行的维护活动称为完善性维护。4.预防性维护为了提高软件的可维护性和可靠性而对软件进行的修改称为预防性维护。15.3软件可维护性15.3.1软件可维护性的定义软件可维护性就是指进行维护活动时的容易程度。目前广泛使用的是用如下的七个特性来衡量程序的可维护性。而且对于不同类型的维护,这七种特性的侧重点也不相同。表15--1显示了在各类维护中应侧重哪些特性。图中的“√”表示特别需要的特性。表15--1在各类维护中的侧重点改正性维护适应性维护完善性维护可理解性√可测试性√可修改性√√可靠性√可移植性√可使用性√√效率√15.3.2可维护性的度量下面介绍度量一个可维护的程序的七种特性时常用的方法。这就是质量检查表、质量测试、质量标准。质量检查表是一个问题清单,评价者针对检查表上的每一个问题,依据自己的定性判断,回答“Yes”或者“No”。用这个清单对质量进行分析。质量测试与质量标准则用于定量分析和评价程序的质量。下面是对七个软件特性的描述。(1)可理解性可理解性是指人们通过阅读源代码和相关文档,了解程序功能及其如何运行,对源程序的理解的容易程序。(2)可靠性可靠性指按照用户的要求和设计目标,一个程序在给定的一段时间内正确执行的概率。用于衡量软件可靠性的标准主要有MTBF=MTTF+MTTR其中:MTBF是平均失败间隔时间(MeanTimeBetweenFailures)MTTF是平均无效时间(MeanTimeToFailure)MTTR是平均修复时间(MeanTimeToRepairerror)度量可靠性的方法,主要有两类:1)根据程序存在的错误的统计数字,进行可靠性预测。2)根据程序复杂性,预测软件可靠性。3)可测试性4)可修改性5)可移植性6)效率7)可使用性8)其他间接定量度量可维护性的方法Gilb提出了与软件维护期间工作量有关的一些数据,可以使用它们间接地对软件的可维护性做出估计。问题识别的时间;因管理活动拖延的时间;收集维护工具的时间;分析、诊断问题的时间;修改规格说明的时间;具体的改错或修改的时间;局部测试的时间;集成或回归测试的时间;维护和评审时间;恢复时间。15.4软件维护的特点15.4.1非结构化维护和结构化维护1.非结构化维护因为只有源程序,而文档很少或没有文档,维护活动只能从阅读、理解和分析源程序开始。也只有通过阅读源程序来了解系统功能、软件结构、数据结构、系统接口和设计约束等。2.结构化维护用软件工程思想开发的软件具有各个阶段的文档,这对于理解、掌握软件功能、性能、软件结构、数据结构、系统接口和设计约束有很大作用。我们可以从下面的图中看出结构化维护和非结构化维护在维护活动中的区别:图15-2维护要求是否结构化求重编程序阅读源代码评价设计定位错误交付使用计划途径修改设计重编程序回归测试回归测试是否15.4.2维护的困难性造成软件维护困难的根本原因是缺乏和软件有关文档。而缺乏文档又是不按照科学的软件工程方法来开发软件造成的。在软件维护中的困难表现在如下几个方面:(1)读懂别人的源程序是困难的。(2)文档的不一致性。(3)软件开发和软件维护在人员和时间上的差异。(4)软件维护不是一项吸引力的工作。15.4.3软件维护的费用软件维护的费用在总费用中的比重是在不断增加的,据统计数字分析,它在1970年占35%~40%,1980年上升到40%~150%,1990年上升到70%~80%。软件维护费用不断上升,这只是软件维护有形的代价。另外还有无形的代价,即要占用更多的硬件、软件和软件工程师等资源,这样一来,新的开发工作就因投入的资源不足而受到影响。用于软件维护工作的活动可分为生产性活动和非生产性活动两种。生产性活动包括分析评价、修改设计和编写程序代码等。非生产性活动包括理解程序代码功能、解释数据结构、接口特点和设计约束。维护活动总的工作量由下式表示:M=P+K·exp(C-D)其中:M表示维护工作的总工作量;P表示生产性活动工作量;K表示经验常数;C表示复杂性程序;D表示维护人员对软件的熟悉程度。15.5软件维护的实施15.5.1维护的组织为保证软件维护的质量,必须要为软件维护活动建立维护机构。这种维护机构通常以维护小组形式出现。维护小组分为临时维护小组和长期维护小组两种类型。1.临时维护小组临时维护小组执行一些特殊的或临时的维护任务。2.长期维护小组对长期运行的复杂系统进行维护必须有一个稳定的维护小组才可以完成任务。15.5.2维护的流程软件维护活动和软件开发一样,要有严格的规范,才能保证软件的质量。一般执行维护活动的流程如下:(1)制定维护申请报告。(2)审查申请报告并批准。(3)进行维护并做详细记录。(4)复审。1.制定维护申请报告应该以文档的方式提出所有软件维护申请。由申请维护的人员(用户、开发人员)填写。2.维护过程一个维护申请提出之后,经评审需要维护,则按下列过程实施维护:(1)首先确定要进行维护的类型。(2)对改正性维护从评价错误的严重性开始。(3)对适应性和完善性维护。(4)实施维护任务。(5)“救火”维护。3.维护的复审在维护任务完成后,要对维护任务进行复审。进行复审时要回答下列问题;(1)评价维护的情况,即设计、代码和测试的哪些方面已经完成?(2)对软件开发工作有哪些改进要求?(3)对于维护工作,主要的、次要的障碍是什么?15.5.3维护技术在维护活动中,按目的不同分为两类维护技术,分别是面向维护的技术和维护支援技术。1.面向维护的技术面向维护的技术涉及软件开发的所有阶段。在需求分析阶段,保证对用户的需求没有矛盾和易于理解,可以减少软件中的错误。在设计阶段,考虑计算机的发展趋势,充分考虑将来改动或扩充的可能性。在测试阶段,设计完善的测试方法,尽量发现存在的错误,保存测试用例和测试数据等。2.维护支援技术维护支援技术包括下列各方面的技术:(1)信息收集。(2)错误原因分析。(3)软件分析与理解。(4)维护方案评价。(5)代码与文档修改。(6)修改后的确认。(7)远距离的维护。15.5.4维护的副作用维护的目的是为了延长软件的寿命并让其创造更多的价值,经过一段时间的维护,软件的错误被修正了,功能增强了。但同时,因为修改而引入的潜伏的错误也增加了。这种因修改软件而造成的错误或其他不希望出现的情况称为维护的副作用。维护的副作用有编码副作用、数据副作用和文档副作用三种。1.编码副作用在使用程序设计语言修改源代码时可能引入如下错误,这些错误要到运行时才能被发现:(1)删除或修改一个子程序、一个标号和一个标识符。(2)改变程序代码的时序关系,改变占用存储的大小,改变逻辑运算符。(3)为边界条件的逻辑测试做出改变。(4)改进程序的执行效率。(5)把设计上的改变翻译成代码的改变。2.数据副作用在修改数据结构时,有可能造成软件设计与数据结构不匹配,因而导致软件错误。有以下几种情况:(1)重新定义局部或全局的常量,重新定义记录或文件格式。(2)增加或减少一个数组或高层数据结构的大小。(3)修改全局或公共数据。(4)重新初始化控制标志或指针。(5)重新排列输入/输出或子程序的参数。(6)修改数据库的结构3.文档副作用如果对可执行软件的修改没有反映在文档中,就会产生如下文档副作用:(1)修改交互输入的顺序或格式,没有正确的记入文档中。(2)过时的文档内容、索引和文本可能造成冲突等。15.6维护“老化代码“对于那些使用超过15年的程序,这些程序通常称为“老化代码”。对于这样没有完全软件配置和良好设计的“老化代码”,维护人员可能不太熟悉。为了能够有效地维护它们,Yourdon提出了以下的维护建议:(1)在进入“紧急维修”之前,必须研究程序的使用环境及有关资料,尽可能得到更多的背景信息;(2)力图熟悉程序的所有控制流程。最初可以忽略某些编码细节。如果设计存在,则可利用它们来帮助画出结构图和高层流程图;(3)评价现有文档的可用性。若有帮助,可利用它们在源程序清单中插入注释;(4)充分利用交叉引用表、符号表及其他由编译程序或汇编程序等提供的交叉引用信息;(5)必须非常谨慎地对程序进行修改。如果可能,要尊重程序的风格和格式,要说明需要变更的程序指令;(6)在删除某些代码时,要确认代码确实不再使用;(7)不要试图共享程序已有的临时变量或工作区,需要时可插入新的变量以避免冲突;(8)保持详细的维护活动和维护结果记录;(9)如果程序结构混乱,修改受到干扰,可抛弃程序重新编写;(10)插入出错检验。15.7逆向工程和再工程逆向工程过程制从源代码中抽取出来的设计信息。作为逆向工程的评价,要求抽取出来的信息的抽象程度越高越好。下面是逆向工程中得到的信息抽象层次(从低到高):软件过程的设计表示、程序和数据结构信息、数据和控制流模型和实体-关系模型。再工程(reengineer),它不仅能从已存在的程序中重新获得设计信息,而且还能使用这些信息来改建或重构现有的系统,以改进它的综合质量。一般软件人员利用再工程重新实现已存在的程序,同时加进新的功能或改善它的性能。15.7.1预防性维护对于很早以前开发的程序,由于没有科学的软件工程做指导,开发出来的程序结构不好,可能一个模块就有上千条语句,又没有相应的文档。为了修改这类程序以适应用户新的或变更的需求,可以有以下几种选择:(1)通过反复地修改,以实现必要的变更;(2)尽可能多地掌握程序的内部工作细节,以便更有效地做出修改;(3)重新设计、重新编码和测试那些需要变更的软件部分,把软件工程方法应用于有修改的部分;(4)使用CASE工具(逆现工程和再工程工具)对程序全部重新设计、重新编码和测试,。预防性维护方法是由