资源描述
,Click to edit Master text styles,Second level,Third level,Fourth level,Click to edit Master title style,软件工程导论,(第,5,版),Click to edit Master text styles,Second level,Third level,Fourth level,Click to edit Master title style,第,8,章 维护,软件生存周期,第,8,章 维护,软件维护是软件生命周期的,最后一个阶段,,它处于系统投入生产性运行以后的时期中,因此不属于系统开发过程。,软件维护的,基本任务,是保证软件在一个相当长的时期能够正常运行。,软件维护,需要的工作量非常大,,虽然在不同应用领域维护成本差别很大,但是,平均说来,大型软件的维护成本高达开发成本的,四倍左右,。,8.1.1,软件维护定义,所谓软件,维护,就是在软件已经交付使用之后,为了改正错误或满足新的需要而修改软件的过程。,软件维护包括下述,4,项,活动。,诊断和改正错误的过程:,改正性维护,为了和变化了的环境适当地配合而进行的修改软件的活动:,适应性维护,为了满足在使用软件的过程中用户的建议和改进意见而作的维护:,完善性维护,为了给未来的改进奠定更好的基础而修改软件:,预防性维护,在软件交付使用后,因开发时测试的,不彻底,、,不完全,,必然会有部分隐藏的错误遗留到运行阶段。,这些隐藏下来的错误,在某些特定的使用环境下就会暴露出来,。,为了,识别和纠正软件错误,、,改正软件性能上的缺陷,、,排除实施中的误使用,,应当进行的诊断和改正错误的过程就叫做改正性维护。,改正性维护的工作量占全部维护活动的17%21%。,1,、改正(纠错)性维护,适应性维护,也就是为了和,变化了的环境适当地配合,而进行的修改软件的活动,是既必要又经常的维护活动。,外部环境,(,新的硬、软件配置,),数据环境,(,数据库、数据格式、数据输入/输出方式、数据存储介质,),可能发生变化。,适应性维护的工作量占全部维护活动的18%25%,2,、适应性维护,在软件的使用过程中,用户往往会对软件提出新的,功能,与,性能,要求。,为了满足这些要求,需要修改或再开发软件,以,扩充软件功能,、,增强软件性能,、,改进加工效率,、,提高软件的可维护性,。,这种情况下进行的维护活动叫做完善性维护。,3,、完善性维护,实践表明,在几种维护活动中,完善性维护所占的比重最大。,即大部分维护工作是改变和加强软件,而不是纠错,。,完善性维护不一定是救火式的紧急维修,而可以,是有计划、有预谋的一种再开发活动,。,事实证明,来自用户要求扩充、加强软件功能、性能的维护活动约占整个维护工作的50以上。,3,、完善性性维护,预防性维护是为了,提高软件的可维护性,、,可靠性等,,为以后进一步改进软件打下良好基础。,预防性维护定义为:,采用先进的软件工程方法对需要维护的软件或软件中的某一部分(重新)进行设计、编制和测试。,在整个维护活动中,预防性维护占很小的比例,只占5%。,4,、预防性维护,综 述,在整个软件维护阶段所花费的全部工作量中,,完善性维护占了几乎一半的工作量。,软件维护活动所花费的工作占整个生存期工作量的70%以上,,这是由于在漫长的软件运行过程中需要不断对软件进行修改,以,改正新发现的错误,、适应新的环境和用户新的要求,这些修改需要花费很多精力和时间,而且有时会引入新的错误。,8.1.1,软件维护定义,三类维护占 维护在软件生 总维护比例 存期所占比例,8.2,维护的特点,结构化维护与非结构化维护的差别巨大,1.,非结构化维护,如果,软件配置的唯一成分是程序代码,,那么维护活动从艰苦地评价程序代码开始,而且常常由于程序内部文档不足而使评价更困难。而且对程序代码所做的改动的后果是难于估量的:因为没有测试方面的文档,所以不可能进行回归测试。,非结构化维护付出代价高昂。,8.2,维护的特点,2.,结构化维护,如果,有一个完整的软件配置存在,,那么维护工作从评价设计文档开始,确定软件重要的结构特点、性能特点以及接口特点;估量要求的改动将带来的影响,并且计划实施途径。然后首先修改设计并且对所做的修改进行仔细复查。接下来编写相应的源程序代码;使用在测试说明书中包含的信息进行回归测试;最后,把修改后的软件再次交付使用。,结构化维护,能减少精力浪费并且能提高维护的总体质量。,8.2,维护的特点,二、,维护成本,有形的软件维护成本,是花费了多少钱,,无形的维护成本,有更大的影响。,一些,合理的修复或修改请求不能及时安排,,使得客户不满意;,变更的结果,引入新的故障,,使得软件整体质量下降;,把软件人员抽调到维护工作中,干扰了软件开发工作。,软件维护的,代价,是,降低了生产率,,在做老程序的维护时非常明显。,例如,,开发每一行源代码耗资,25美元,,,维护每一行源代码需要耗资,1000美元,。,8.2,维护的特点,维护工作量的一个模型:,M,P,K*exp,(,c,-,d,),其中:,M,是维护用的总工作量,,P,是生产性工作量,,K,是经验常数,,c,是因缺乏好的设计和文档而导致复杂性的度量),,d,是维护人员对软件的熟悉程度。,模型表明,如果软件的开发途径不好,(,即,没有使用软件工程方法学,),,而且原来的开发人员不能参加维护工作,那么维护工作量和费用将指数地增加。,影响维护工作量的因素,在软件的维护过程中,需要花费大量的工作量,从而直,接影响了软件维护的成本,。,许多软件在开发时并未考虑将来的修改,为软件的维护带来许多问题。,系统大小,:系统越大,理解掌握起来越困难。系统越大,所执行功能越复杂。因而需要更多的维护工作量。,程序设计语言,:使用强功能的程序设计语言可以控制程序的规模。语言的功能越强,生成程序的模块化和结构化程度越高,所需的指令数就越少,程序的可读性越好。,系统年龄:,老系统随着不断的修改,结构越来越乱;,维护人员经常更换,程序又变得越来越难于理解。,许多老系统在当初并未按照软件工程的要求进行开发,因而没有文档,或文档太少。,在长期的维护过程中文档在许多地方与程序实现变得不一致,在维护时就会遇到很大困难。,数据库技术的应用,:使用数据库,可以简单而有效地管理和存储用户程序中的数据,还可以减少生成用户报表应用软件的维护工作量。,先进的软件开发技术,:在软件开发时,若使用能使软件结构比较稳定的分析与设计技术,及程序设计技术,如面向对象技术、复用技术等,可减少大量的工作量。,8.2,维护的特点,维护的问题,与软件维护有关的绝大多数问题,都可归因于,软件定义和软件开发的方法有缺点,。,在软件生命周期的头两个时期没有严格而又科学的管理和规划,几乎必然会导致在最后阶段出现问题。,8.2,维护的特点,和软件维护有关的部分问题:,理解别人写的程序通常非常困难,而且困难程度随着软件配置成分的减少而迅速增加。如果仅有程序代码没有说明文档,则会出现严重的问题。,需要维护的软件往往没有合格的文档,或者文档资料显著不足。认识到软件必须有文档仅仅是第一步,容易理解的并且和程序代码完全一致的文档才真正有价值。,当要求对软件进行维护时,不能指望由开发人员给我们仔细说明软件。由于维护,“,阶段持续的时间很长,因此,当需要解释软件时,往往原来写程序的人已经不在附近了。,8.2,维护的特点,绝大多数软件在设计时没有考虑将来的修改。除非使用强调模块独立原理的设计方法论,否则修改软件既困难又容易发生差错。,软件维护不是一项吸引人的工作。形成这种观念很大程度上是因为维护工作经常遭受挫折。,8.3,软件维护过程,维护过程本质上是,修改和压缩了的软件定义和开发过程。,为了有效地进行软件维护,应事先就开始做组织工作。,首先建立一个维护组织,确定报告及评价的过程,为每一个维护要求规定一个标准化的事件序列,建立一个适用于维护活动的记录保管过程,并且规定复审标准,8.3,软件维护过程,维护组织,维护组织,维护申请,提交给,维护管理员,,他把申请交给某个,系统监督员,去,评价,。,一旦做出评价,由,修改负责人,确定,如何进行修改,。,在修改程序的过程中,由,配置管理员,严格把关,,控制修改的范围,,,对软件配置进行审计,。,在维护之前,就把责任明确下来,可以减少维护过程中的混乱。,维护修改建议,分析修改建议,是否合理,提交管理部门审查,是否同意,修改,撤销,N,Y,N,Y,进行测试,提交管理部门审批,是否批准,更新主文档,Y,更新其他文档,提交使用,修改,N,软件维护的管理流程,8.3,软件维护过程,维护报告,应该,用标准化的格式表达所有软件维护要求,。,软件维护人员给用户提供空白的维护要求,有时称为软件问题报告表,由要求一项维护活动的用户填写。,如果遇到了一个错误,那么必须完整描述导致出现错误的环境(包括输入数据,全部输出数据,以及其他有关信息)。,对于适应性或完善性的维护要求,应该提出一个简短的需求说明书。,由维护管理员和系统管理员评价用户提交的维护要求表。,8.3,软件维护过程,维护的事件流,8.3,软件维护过程,保存维护记录,应该为每项维护工作都收集下述数据:,(,1,)程序标识;(,2,)源语句数;,(,3,)机器指令条数;(,4,)使用的程序设计语言;,(,5,)程序安装的日期;(,6,)自从安装以来程序运行的次数;,(,7,)自从安装以来程序失效的次数;(,8,)程序变动的层次和标识;,(,9,)因程序变动而增加的源语句数;(,10,)因程序变动而删除的源语句数;,(,11,)每个改动耗费的人时数;(,12,)程序改动的日期;,(,13,)软件工程师的名字;(,14,)维护要求表的标识;,(,15,)维护类型;(,l6,)维护开始和完成的日期;,(,17,)累计用于维护的人时数;(,18,)与完成的维护相联系的纯效益。,8.3,软件维护过程,评价维护活动,从下述七个方面度量维护工作:,(,1,)每次程序运行平均失效的次数;,(,2,)用于每一类维护活动的总人时数;,(,3,)平均每个程序、每种语言、每种维护类型所做的程序变动效;,(,4,)维护过程中增加或删除一个源语句平均花费的人时数;,(,5,)维护每种语言平均花费的人时数;,(,6,)一张维护要求表的平均周转时间;,(,7,)不同维护类型所占的百分比。,8.4,程序修改的步骤及修改的副作用,在软件维护时,必然会对源程序进行修改。,通常对源程序的修改不能无计划地仓促上阵,为了正确、有效地修改,需要经历以下三个步骤。,分析和理解程序,修改程序,重新验证程序,分析和理解程序,经过分析,,全面、准确、迅速地理解程序是决定维护成败和质量好坏的关键,。在这方面,软件的可理解性和文档的质量非常重要。,修改程序,对程序的修改,必须事先做出计划,有预谋地、周密有效地实施修改。,1.设计程序的修改计划,程序的修改计划要考虑人员和资源的安排。小的修改可以不需要详细的计划,而对于需要耗时数月的修改,就需要计划立案。,2.修改代码,以适应变化,在修改时,要求:,(1),正确、有效地编写修改代码;,(2),要谨慎地修改程序,尽量保持程序的风格及格式,要在程序清单上注明改动的指令;,(3),不要删除程序语句,除非完全肯定它是无用的;,(4),不要试图共用程序中已有的临时变量或工作区,为了避免冲突或混淆用途,应设置自己的变量;,(5),插入错误检测语句;,(6),在修改过程中做好修改的详细记录,消除变更中任何有害的副作用(波动效应);,3.修改程序的副作用,所谓副作用是指因修改软件而造成的错误或其它不希望发生的情况。副作用有三种:,修改代码的副作用,、,修改数据的副作用,、,文档的副作用,。,在修改源代码时,都可能引入错误。例如,,删除或修改一个子程序,、,删除或修改一个标号,、,删除或修改一个标识符,、,改变程序代码的时序关系,、,改变占用存储的大小,、,改变逻辑运算符,、,修改文件的打开或关闭,、,改进程序的执行效率,,以及,把设计上的改变翻译成代码的改变,时,都容易引入错误。,(1)修改代码的副作用,(2)修改数据的副作用,在,修改数据结构,时,有可能造成,软件设计与数据结构不匹配,,因而导致软件出错。,数据副作用就是修改软件信息结构导致的结果。,容易导致设计与数据不相容的错误可以有:,重新定义局部的或全局的常量,重新定义记录或文件的格式,增大或减小一个数组或高层数据结构的大小,修改全局或公共数据,重新初始化控制标志或指针,重新排列输入输出或子程序的参数,(3)文档的副作用,对,数据流,、,软件结构,、,模块逻辑,或,任何其它有关特性,进行修改时,必须,对相关技术文档进行相应修改,。否则会导致,文档与程序功能不匹配,,,缺省条件改变,,,新错误信息不正确,等错误。使得,软件文档不能反映软件的当前状态,。,对于用户来说,软件事实上就是文档。,如果对可执行软件的修改不反映在文档里,就会产生文档的副作用。,对交互输入的顺序或格式进行修改,如果没有正确地记入文档中,就可能引起重大的问题。,过时的文档内容、索引和文本可能造成冲突,引起用户失败和不满。,因此,,必须在软件交付之前对整个软件配置进行评审,,以减少文档的副作用。,重新验证程序,在将修改后的程序提交用户之前,需要进行,充分的确认和测试,,以保证整个修改后程序的正确性。,静态确认,修改软件,伴随着引起新的错误的危险,。为了能够做出正确的判断,验证修改后的程序至少需要两个人参加。要检查:,(1),修改是否涉及到规格说明?修改结果是否符合规格说明?有没有歪曲规格说明?,(2),程序的修改是否足以修正软件中的问题?源程序代码有无逻辑错误?修改时有无修补失误?,(3),修改部分对其它部分有无不良影响(副作用)?,对软件进行修改,常常会引发别的问题,有必要检查修改的影响范围,。,计算机确认,在进行了以上确认的基础上,用计算机对修改程序进行确认测试:,(1)确认测试顺序,:先对修改部分进行测试,然后隔离修改部分,测试程序的未修改部分,最后再把它们集成起来进行测试。这种测试称为回归测试。,(2),准备标准的测试用例,。,(3)充分利用软件工具帮助重新验证过程,。,(4)在重新确认过程中,需邀请用户参加,。,维护后的验收,在交付新软件之前,维护主管部门要检验:,(1),全部文档是否完备,并已更新;,(2),所有测试用例和测试结果已经正确记载;,(3),记录软件配置所有副本的工作已经完成;,(4),维护工序和责任已经确定。,8.5,软件的可维护性,许多软件的维护十分困难,原因在于这些软件的文档不全、质量差、开发过程不注意采用好的方法,忽视程序设计风格等。,许多维护要求并不是因为程序中出错而提出的,而是为适应环境变化或,需求变化,而提出的。,为了使得软件能够易于维护,必须考虑使软件具有,可维护性,。,8.5,软件的可维护性,软件可维护性可以定性地定义为:,维护人员理解、改正、改动和改进这个软件的难易程度。,软件的,可维护性,是,软件开发阶段各个时期的关键目标,。,8.5.1,软件可维护性的因素,目前广泛使用的是用如下的七个特性来衡量程序的可维护性。,可理解性可使用性,可测试性可移植性,可修改性效率,可靠性,而且对于不同类型的维护,这七种特性的侧重点也不相同,。,8.5.1,软件可维护性的因素,8.5.2,软件可维护性的度量,人们一直期望,对软件的可维护性做出定量度量,,但要做到这一点并不容易。,常用的度量一个可维护的程序的七种特性的方法。,1.可理解性,可理解性表明人们通过阅读源代码和相关文档,了解程序功能及其如何运行的容易程度。,一个可理解的程序应具备以下一些特性:,模块化,,,风格一致性,,,不使用令人捉摸不定或含糊不清的代码,,,使用有意义的数据名和过程名,,,结构化,,,完整性,等。,2.可靠性,可靠性表明一个程序按照用户的要求和设计目标,在给定的一段时间内正确执行的概率。,关于可靠性,度量的标准主要有:,平均失效间隔时间,MTTF,平均修复时间,MTTR,有效性,A,=,MTBD/(MTBD+MDT),注:系统平均不工作间隔时间,MTBD(Mean Time Between System Downs),、平均停机时间,MDT(Mean Down Time),3.可测试性,可测试性表明论证程序正确性的容易程度,。程序越简单,证明其正确性就越容易。而且设计合用的测试用例,取决于对程序的全面理解。,一个可测试的程序应当是,可理解的,,,可靠的,,,简单的,。,用于可测试性度量的检查项目如下:,程序是否模块化?结构是否良好?,程序是否可理解?程序是否可靠?,程序是否能显示任意中间结果?,程序是否能以清楚的方式描述它的输出?,程序是否能及时地按照要求显示所有的输入?,程序是否有跟踪及显示逻辑控制流程的能力,?,程序是否能从检查点再启动?,程序是否能显示带说明的错误信息?,4.可修改性,可修改性表明程序容易修改的程度,。,一个可修改的程序应当是,可理解的,、,通用的,、,灵活的,、,简单的,。,通用性是指程序适用于各种功能变化而无需修改。,灵活性是指能够容易地对程序进行修改。,5.可移植性,可移植性表明程序转移到一个新的计算环境的可能性的大小,。或者它表明程序可以容易地、有效地在各种各样的计算环境中运行的容易程度。,一个可移植的程序应具有,结构良好,、,灵活,、,不依赖于某一具体计算机或操作系统的性能,。,用于可移植性度量的检查项目如下:,是否是用高级的独立于机器的语言来编写程序?,是否使用广泛使用的标准化的程序设计语言来编写程序?是否仅使用了这种语言的标准版本和特性?,程序中是否使用了标准的普遍使用的库功能和子程序?,程序中是否极少使用或根本不使用操作系统的功能?,程序在执行之前是否初始化内存?,程序在执行之前是否测定当前的输入输出设备?,程序是否把与机器相关的语句分离了出来,集中放在了一些单独的程序模块中,并有说明文件?,程序是否结构化?并允许在小一些的计算机上分段(覆盖)运行?,程序中是否避免了依赖于字母数字或特殊字符的内部位表示?,6.,效率,效率表明一个程序能执行预定功能而又不浪费机器资源的程度,。,这些机器资源包括,内存容量,、,外存容量,、,通道容量,和,执行时间,。,用于效率度量的检查项目如下,:,程序是否模块化?结构是否良好?,是否消除了无用的标号与表达式,以充分发挥编译器优化作用?,程序的编译器是否有优化功能?,是否把特殊子程序和错误处理子程序都归入了单独的模块中?,是否以快速的数学运算代替了较慢的数学运算?,是否尽可能地使用了整数运算,而不是实数运算?,是否在表达式中避免了混合数据类型的使用,消除了不必要的类型转换?,程序是否避免了非标准的函数或子程序的调用?,在几条分支结构中,是否最有可能为“真”的分支首先得到测试?,在复杂的逻辑条件中,是否最有可能为,“,真,“,的表达式首先得到测试?,7.可使用性,从用户观点出发,,可使用性定义为程序方便、实用、及易于使用的程度,。一个可使用的程序应是,易于使用的,、,能允许用户出错和改变,,并,尽可能不使用户陷入混乱状态的,程序。,用于可使用性度量的检查项目如下:,程序是否具有自描述性?,程序是否能始终如一地按照用户的要求运行?,程序是否让用户对数据处理有一个满意的和适当的控制?,程序是否容易学会使用?,程序是否使用数据管理系统来自动地处理事务性工作和管理格式化、地址分配及存储器组织。,程序是否具有容错性?,程序是否灵活?,8.5.3,提高软件可维护性的方法,建立明确的软件质量目标和优先级,使用提高软件质量的技术和工具,进行明确的质量保证审查,选择可维护的程序设计语言,改进程序的文档,8.5,软件再工程过程,图,8.3,软件再工程过程模型,8.5,软件再工程过程,典型的软件再工程过程模型如图,8.3,所示,该模型定义了,6,类活动,。,再工程范型是一个,循环模型,。这意味着作为该范型的组成部分的每个活动都可能被重复,而且对于任意一个特定的循环来说,过程可以在完成任意一个活动之后终止。,8.5,软件再工程过程,1.,库存目录分析,每个软件组织都应该保存其拥有的所有应用系统的库存目录。该目录包含关于每个应用系统的基本信息。,对库中每个程序都做逆向工程或再工程是不现实的。下述,3,类程序有可能成为预防性维护的对象:,(,1,)预定将使用多年的程序;,(,2,)当前正在成功地使用着的程序;,(,3,)在最近的将来可能要做重大修改或增强的程序。,8.5,软件再工程过程,应该仔细分析库存目录,按照业务重要程度、寿命、当前可维护性、预期的修改次数等标准,把库中的应用系统排序,从中选出再工程的候选者,然后明智地分配再工程所需要的资源。,8.5,软件再工程过程,2.,文档重构,老程序固有的特点是缺乏文档。具体情况不同,处理这个问题的方法也不同:,软件稳定或者生命周期临近结束,保持现状,首先建立起正在修改部分的文档,如果某应用系统是完成业务工作的关键,而且必须重构全部文档,则仍然应该设法把文档工作减少到必需的最小量。,8.5,软件再工程过程,3.,逆向工程,软件的,逆向工程,是分析程序以便在比源代码更高的抽象层次上创建出程序的某种表示的过程。,逆向工程是一个恢复设计结果的过程,逆向工程工具从现存的程序代码中抽取有关数据、体系结构和处理过程的设计信息。,8.5,软件再工程过程,4.,代码重构,重构难于理解、测试和维护的模块的代码。,为了完成代码重构活动,首先用重构工具分析源代码,标注出和结构化程序设计概念相违背的部分。然后重构有问题的代码。最后,复审和测试生成的重构代码并更新代码文档。,重构并不修改整体的程序体系结构,,它仅关注个体模块的设计细节以及在模块中定义的局部数据结构。,如果重构扩展到模块边界之外并涉及软件体系结构,则重构变成了正向工程。,8.5,软件再工程过程,5.,数据重构,数据重构是一种全范围的再工程活动。,数据重构始于逆向工程活动,分解当前使用的数据体系结构,必要时定义数据模型,标识数据对象和属性,并从软件质量的角度复审现存的数据结构。,当数据结构较差时,应该对数据进行再工程。,由于数据体系结构对程序体系结构及程序中的算法有很大影响,对数据的修改必然会导致体系结构或代码层的改变。,8.5,软件再工程过程,6.,正向工程,从现有程序中恢复设计信息,而且使用该信息去改变或重构现有系统,以提高其整体质量。,正向工程过程应用软件工程的原理、概念、技术和方法来重新开发某个现有的应用系统,。在大多数情况下,被再工程的软件不仅重新实现现有系统的功能,而且加入了新功能和提高了整体性能。,End,Thank You!,
展开阅读全文