1、软件危机:是指在计算机软件的开发和维护过程中所遇到的一系列严重问题。软件危机问题:如何开发软件,以满足对软件日益增长的需求;如何维护数量不断膨胀的已有软件。软件危机表现:1 对软件开发成本和进度的估计常常很不准确。2 用户对已完成软件系统不满意的现象经常发生。3 软件产品的质量往往靠不住。4 软件常常是不可维护的。5 软件通常没有适当的文档资料。6 软件成本在计算机系统总成本中所占的比例逐年上升。7 软件开发生产率提高的速度,远远跟不上计算机应用迅速普及及深入的趋势。产生软件危机的原因:在软件开发和维护的过程中存在这么多严重问题,一方面与软件本身的特点有关,另一方面也和软件开发与维护的方法不正
2、确有关。 软件不同于硬件,它是计算机系统中的逻辑部件而不是物理部件。软件不同于一般程序,它的一个显著特点是规模庞大,而且程序复杂性将随着程序规模的增加而旱指数上升。软件生命周期:一个软件从定义、开发、使用和维护,直到最终被废弃,要经历一个漫长的时期,称为生命周期。消除软件危机的途径:为了消除软件危机,首先应该对计算机软件有一个正确的认识。一个软件必须由一个完整的配置组成,事实上,软件是程序、数据及相关文档的完整集合。程序是能够完成预定功能和性能的可执行的指令序列;数据是使程序能够适当地处理信息的数据结构;文档是开发、使用和维护程序所需要的图文资料。更重要的是,必须充分认识到软件开发不是某种个体
3、劳动的神秘技巧,而应该是一种组织良好、管理严密、各类人员协同配合、共同完成的工程项目。 应该推广使用在实践中总结出来的开发软件的成功的技术和方法,并且研究探索更好更有效的技术和方法,尽快消除在计算机系统早期发展阶段形成的一些错误概念和做法。 应该开发和使用更好的软件工具。总之,为了消除软件危机,既要有技术措施(方法和工具 ),又要有必要的组织管理措施。软件工程定义:采用工程的概念、原理、技术和方法来开发与维护软件,把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来,以经济地开发出高质量的软件并有效地维护它,这就是软件工程。本质特性:软件工程关注于大型程序的构造;软件工程的
4、中心课题是控制复杂性; 软件经常化;开发软件的效率非常重要;和谐地合作是开发软件的关键;软件必须有效地支持它的用户;在软件工程领域中是由一种文化背景的人替具有另一种文化背景的人创造产品。基本原理:用分阶段的生命周期计划严格管理;坚持进行阶段评审;实行严格的产品控制;采用现代程序设计的技术;结果应能清楚地审查;开发小组的人员应该少而精;承认不断改进软件工程实践的必要性。软件工程方法学:通常把在软件生命周期全过程中使用的一整套技术方法的集合称为方法学,也称为范型。方法学三要素:方法(完成软件开发的各项任务的技术方法) 工具(为运用方法而提供的自动或半自动的软件工程支持环境)过程(为了获得高质量的软
5、件所需要完成的一系列任务的框架,它规定了完成各任务的工作步骤)传统方法学:也称生命周期方法学或结构化范型。面向对象方法学:把数据和行为看同等重要,它是一种以数据为主线,把数据和对数据的操作紧密地结合起来的方法。4 个要点(面向对象方法=对象+类+继承+用消息通信)1 把对象作为融合了数据及在数据上的操作行为统一的软件结构 2 把所有对象都划分成类 3 按照父类或子类的关系,把若干个相关类组成一个层次结构的系统 4 对象彼此间仅能通过发送消息互相联系。软件定义时期的任务:是确定软件开发工程必须完成的总目标;确定工程的可行性,导出实现工程目标应该采用的策略及系统必须完成的功能;估计完成该项工程需要
6、的资源和成本,并且制定工程进度表。这个时期的工作通常又称为系统分析,由系统分析员负责完成。软件定义时期通常进一步划分成三个阶段,即问题定义、可行性研究和需求分析。开发时期具体设计和实现在前一个时期定义的软件,它通常由下述四个阶段组成:总体设计,详细设计,编码和单元测试,综合测试。前两个为系统设计,后两个为系统实现。维护时期的主要任务是使软件持久地满足用户的需要。软件生命周期每个阶段基本任务:1 问题定义 2 可行性研究 3 需求分析 4 总体设计 5 详细设计 6 编码和单元测试 7 综合测试 8 软件维护。软件过程:概括地说,软件过程描述为了开发出客户需要的软件,什么人(who)、在什么时候
7、(when)、做什么事(what)以及怎样(how) 做这些事以实现某一个特定的具体目标。瀑布模型开发软件特点:1.阶段间具有顺序性和依赖性 2.推迟实现的观点 3.质量保证的观点。快速原型模型能基本上做到线性顺序开发的主要原因如下:(1)原型系统巳经通过与用户交互而得到验证,据此产生的规格说明文档正确地描述了用户需求,因此,在开发过程的后续阶段不会因为发现了规格说明文档的错误而进行较大的返工。(2)开发人员通过建立原型系统已经学到了许多东西(至少知道了“系统不应该做什么,以及怎样不去做不该做的事情” ) ,因此,在设计和编码阶段发生错误的可能性也比较小,这自然减少了在后续阶段需要改正前面阶段
8、所犯错误的可能性。可行性研究三种可行性:技术、经济、操作。可行性研究过程的步骤:1.复查系统规模和目标 2. 研究目前正在使用的系统 3. 导出新系统的高层逻辑模型 4. 进一步定义问题 5. 导出和评价供选择的解法 6. 推荐行动方针 7. 草拟开发计划 8. 书写文档提交审查。系统流程图是概括地描绘物理系统的传统工具。它的基本思想是用图形符号以黑盒子形式描绘组成系统的每个部件。系统流程图表达的是数据在系统各部件之间的流动情况,而不是对数据进行加工处理的过程。数据流图(DFD)是一种图形化技术,它描绘信息流和数据从输入移动到输出的过程中所经受的变换。在数据流图中没有任何具体的物理部件,它只是
9、描绘数据在软件中流动和被处理的逻辑过程。数据流图是系统逻辑功能的图形表示,即使不是专业的计算机技术人员也容易理解它,因此是分析员与用户之间极好的通信工具。数据流图有四种成分:源点或终点、处理、数据存储和数据流。数据字典是关于数据的信息的集合,也就是对数据流图中包含的所有元素的定义的集合。数据字典应该由对下列 4 类元素的定义组成:数据流;数据流分量(即数据元素);数据存储;处理。数据字典其他信息:一般信息 ,定义,使用特点,控制信息,分组信息。由数据元素组成数据的方式只有下述三种基本类型:顺序;选择;重复;可选。需求分析是软件定义时期的最后一个阶段,它的基本任务是准确地回答“系统必须做什么?”
10、这个问题。在需求分析阶段结束之前,系统分析员应该写出软件需求规格说明书,以书面形式准确地描述软件需求。需求分析准则:1) 必须理解并描述问题的信息域,根据这条准则应该建立数据模型。 2) 必须定义软件应完成的功能,这条准则要求建立功能模型。3) 必须描述作为外部事件结果的软件行为,这条准则要求建立行为模型。4) 必须对描述信息、功能和行为的模型进行分解,用层次的方式展示细节。需求分类:1 功能需求 2 性能需求 3 可靠性和可用性需求 4 出错处理需求 5 接口需求 6约束 7 逆向需求 8 将来可能提出的需求。访谈:是最早开始使用的获取用户需求的技术,两种基本形式:正式的和非正式的访谈快速建
11、立软件原型:快速简历起来的旨在演示目标系统主要功能的可运行的程序,构建原型的要点是,它应该实现用户看得见的功能,省略目标系统的“隐含”功能。其具备的两个特性:快速和容易修改。分析建模:模型就是为了理解事物而对事物作出的一种抽象,是对事物的一种无歧义的书面描述。结构化分析实质上是一种创建模型活动。需求分析过程应该建立 3 种模型,分别是数据模型、功能模型和行为模型。数据流图是建立功能模型的基础。状态转换图:通过描绘系统的状态以及引起系统状态转换的事件,来表示系统的行为。描绘了系统的各种行为模型和在不同状态间转换的方式。状态转换图是行为建模的基础。状态:是任何可以被观察到的系统行为模式,一个状态代
12、表系统的一种行为模式。在状态图中定义的状态有:初态(只能有 1 个) , 终态(可以有 0 至多个) ,中间状态 。事件:在某个特定时刻发生的事情,它是对引起系统做动作或从一个状态转换到另一个状态的外界事件的抽象。验证软件需求正确性的方面:1 一致性 2 完整性 3 现实性 4 有效性。总体设计过程两个阶段:由系统设计阶段(确定系统的具体实现方案)和结构设计阶段(确定软件结构)总体设计 9 个步骤:1 设想供选择的方案 2 选取合理的方案 3 推荐最佳方案.4 功能分解5 设计软件结构 6 设计数据库 7 制定测试计划 8 书写文档 9 审查和复审。设计原理:模块化 抽象 逐步求精:为了能集中
13、精力解决主要问题而尽量推迟对问题细节的考虑。MILLER 法则:一个人在任何时候都只能把注意力集中在(7+/2)个知识块上。求精实际上是细化过程。信息隐蔽和局部化 模块独立:是指软件系统中每个模块只涉及软件要求的具体的子功能, 而和软件系统中其它的模块的接口是简单的,是模块化抽象信息隐蔽和局部化概念的直接结果。独立的重要性:1 有效的模块化的软件比较容易开发出来。2 独立的模块比较容易测试和维护。度量模块独立性的两个准则:耦合和内聚。模块独立性比较强的模块应是高内聚低耦合的模块。耦合是模块之间的互相连接的紧密程度的度量。数据耦合:两个模块彼此间通过参数交换信息,而且交换的信息仅仅是数据。控制耦
14、合:如果一个模块通过传送开关、标志、名字等控制信息。控制耦合是中等程度的耦合,它增加了系统的复杂程度。公共环境耦合:当两个或多个模块通过一个公共数据环境相互作用。内容耦合:最高程度耦合,发生条件:(1) 一个模块直接访问另一个模块的内部数据;(2) 一个模块不通过正常入口转到另一模块内部;(3) 两个模块有一部分程序代码重迭(只可能出现在汇编语言中);(4) 一个模块有多个入口。耦合设计原则:尽量使用数据耦合,少用控制耦合和特征耦合,限制公共环境耦合的范围,完全不用内容耦合。内聚是模块功能强度(一个模块内部各个元素彼此结合的紧密程度) 的度量,它是信息隐藏和局部化概念的自然扩展。低内聚分类:1
15、 偶然内聚: 一个模块完成一组任务,这些任务彼此间即使有联系也是很松散的。2 逻辑内聚:如果一个模块完成的任务在逻辑上属于相同或相似的一类。3 时间内聚:如果一个模块包含的任务必须在同一阶段时间内执行。中内聚:1 过程内聚:如果一个模块内的处理元素是相关的,而且必须以特定次序执行。2 通信内聚:如果模块中所有元素都使用同一个输入数据或产生同一个输出数据。高内聚:1 顺序内聚:如果一个模块内的处理元素和同一个功能密切相关,而且这些处理必须顺序执行。2 功能内聚:是最高程度的内聚,如果模块内所有处理元素属于一个整体,完成一个单一的功能。启发式规则:1 改进软件结构提高模块独立性。2 模块规则应该适
16、中。3 深度宽度扇出和扇入都应适当。4 模块的作用域应该在控制域之内。5 力争降低模块接口的复杂程度。6 设计单入口单出口的模块。7 模块功能应该可以预测。面向数据流的设计步骤:1 复查基本系统模型,确保系统的输入数据和输出数据是符合实际。2 复查并精化数据流图,对需求分析阶段得出的数据流图认真复查必要时进行精化, 3 确定数据流图具有变换特性还是事务特性。4 确定输入流和输出流的边界,从而孤立出变换中心。5 完成“第一级分解” ,将数据流图映射成软件结构,这个结构控制输入、变换和输出等信息处理过程,6 完成“第二级分解” ,把数据流图中的每个处理映射成软件结构中的一个适当模块。7 使用设计度
17、量和启发式规则对第一次分割得到的软件结构进行进一步锐化。详细设计的目标和任务:如何具体的实现所要求的系统,得出目标系统的精确描述;详细设计的结果最终决定编码阶段程序的质量。常用的结构程序设计类型:经典的:顺序、选择、循环;扩展的:DO_CASE、DO_UNTIL;修正的:LEAVE 或 BREAK。在设计人机界面的过程中遇到下述 4 个问题:系统响应时间;用户帮助设施;出错信息处理;命令交互。系统响应时间指从用户完成某个控制动作,到软件给出预期的响应之间的这段时间。易变性指系统响应时间相对于平均响应时间的偏差。描述程序处理过程的工具称为过程设计的工具,它们可以分为图形、表格和语言。在流图中用圆
18、表示结点,一个圆代表一条或多条语句。计算环形复杂度 3 种方法:(1) 流图中的区域数等于环形复杂度。(2) 流图 G 的环形复杂度 V(G)=E-N+2,其中,E 是流图中边的条数,N 是结点数。(3) 流图 G 的环形复杂度 V(G)=P+1,其中,P 是流图中判定结点的数目。实现:编码和测试。测试的目的:就是在软件投入生产性运行之前,尽可能多的发现软件中的错误。软件测试在软件生命周期中横跨两个阶段。通常在编写出每个模块之后就对它做必要的测试(称为单元测试) ,模块的编写者和测试者是同一个人,编码和单元测试属于软件生命周期的同一阶段。在这个阶段结束之后,对软件系统还应该进行各种综合测试,通
19、常由专门的测试人员承担这项工作。软件测试的目标或定义:(1) 测试是为了发现程序中的错误而执行程序的过程。(2) 好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案。(3) 成功的测试是发现了至今为止尚未发现的错误的测试。测试方法:1 黑盒测试:如果已经知道了产品应该具有的功能,可以通过测试来检验是否每个功能都能正常使用;2 白盒测试:如果知道产品的内部工作过程,可以通过测试来检验产品内部动作是否按照规格说明书的规定正常进行。测试步骤:模块测试;子系统测试;系统测试;验收测试;平行运行。单元测试集中检测软件设计的最小单元模块。测试重点:模块接口;局部数据结构;重要的执行通路;出错处理通路
20、;边界条件。代码审查比计算机测试优越的是:一次审查会上可以发现许多错误;用计算机测试的方法发现错误之后,通常需要先改正这个错误才能继续测试,因此错误是一个一个地发现并改正的。也就是说,采用代码审查的方法可以减少系统验证的总工作量。集成测试是测试和组装软件的系统化技术,由模块组装成程序时有两种方法。一种方法是先分别测试每个模块,再把所有模块按设计要求放在一起结合成所要的程序,这种方法称为非渐增式测试方法;另一种方法是把下一个要测试的模块同已经测试好的那些模块结合起来进行测试,测试完以后再把下一个应该测试的模块结合进来测试。这种每次增加一个模块的方法称为渐增式测试,这种方法实际上同时完成单元测试和
21、集成测试。当使用渐增方式把模块结合到程序中去时,有自顶向下和自底向上两种集成策略。确认测试也称为验收测试,它的目标是验证软件的有效性。逻辑覆盖:有选择地执行程序中某些最有代表性的通路是对穷尽测试的唯一可行的替代办法。等价划分:是一种黑盒测试技术,这种技术把程序的输入域划分成若干个数据类,据此导出测试用例。调试是在测试发现错误之后排除错误的过程。调试途径:蛮干法;回溯法;原因排除法(对分查找法,归纳法和演绎法) 。软件可靠性是程序在给定的时间间隔内,按照规格说明书的规定成功地运行的概率。软件的可用性是程序在给定的时间点,按照规格说明书的规定成功地运行的概率。可靠性和可用性之间的主要差别是:可靠性
22、意味着 0 到 t 这段时间间隔内系统没有失效,而可用性只意味着在时刻 t,系统是正常运行的。软件工程的主要目的就是要提高软件的可维护性,减少软件维护所需要的工作量,降低软件系统的总成本。所谓软件维护就是在软件已经交付使用之后,为了改正错误或满足新的需要而修改软件的过程。改正性维护:在任何大型程序的使用期间,用户必然会发现程序错误,并且把他们遇到的问题报告给维护人员。把诊断和改正错误的过程称为改正性维护。适应性维护:也就是为了和变化了的环境适当地配合而进行的修改软件的活动,是既必要又经常的维护活动。完善性维护:在使用软件的过程中用户往往提出增加新功能或修改已有功能的建议,还可能提出一般性的改进
23、意见。为了满足这类要求,需要进行完善性维护。预防性维护:当为了改进未来的可维护性或可靠性,或为了给未来的赶紧奠定更好的基础而修改软件时,出现了第四项维护活动称为预防性维护。维护要求表是一个外部产生的文件,它是计划维护活动的基础。软件组织内部应该制定出一个软件修改报告,它给出下述信息。(1) 满足维护要求表中提出的要求所需要的工作量。(2) 维护要求的性质。(3) 这项要求的优先次序。(4) 与修改有关的事后数据。不管维护类型如何,都要进行技术工作。包括修改软件设计、复查、必要的代码修改、单元测试和集成测试、验收测试和复审。决定软件可维护性因素:可理解性;可测试性;可修改性;可移植性;可重用性。