软件工程基础知识
Posted 数学小学霸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件工程基础知识相关的知识,希望对你有一定的参考价值。
软件工程
1、概述
软件
软件的定义和特点
1. 软件的定义
软件是计算机系统中与硬件相互依存的另一部分,是程序、数据及其相关文档的完整集合。一种公认的传统的软件定义为
软件=程序+数据+文档
其中,程序是按事先设计的功能和性能要求执行的指令序列;数据是使程序能够正确地处理信息的数据结构;文档是与程序开发、维护和使用有关的图文资料。
为了更全面、正确地理解计算机和软件,必须了解软件的特点。软件是整个计算机系统中的一个逻辑部件,而硬件是一个物理部件。因此,软件具有与硬件完全不同的特点。
2. 软件的特点
1)形态特性
软件是一种逻辑实体,不具有具体的物理实体形态特性。软件具有抽象性,可以存储在介质中,但是无法看到软件本身的形态,必须经过观察、分析、思考和判断去了解它的功能、性能及其他的特性。
2)生产特性
软件与硬件的生产方式不同。与硬件或传统的制造产品的生产不同,软件一旦设计开发出来,如果需要提供给多个用户,它的复制十分简单,其成本也极为有限,正因为如此,软件产品的生产成本主要是设计开发的成本,同时也不能采用管理制造业生产的办法来解决软件开发的管理问题。
3)维护特性
软件与硬件的维护不同。硬件是有耗损的,其产生的磨损和老化会导致故障率增加甚至使得硬件损坏。软件不存在磨损和老化的问题,但是却存在退化的问题。在软件的生存期中,为了使它能够克服以前没有发现故障、适应软件和软件环境的变化及用户新的要求,必须要对其进行多次修改,而每次的修改都有可能引入新的错误,导致软件失效率升高,从而使软件退化,软硬件失效率曲线大致如下图所示。
(4)复杂特性
软件的复杂性一方面来自它所反映的实际问题复杂性,另一方面也来自程序结构的复杂性。软件技术的发展明显落后于复杂的软件需求,这个差距日益加大。软件复杂性与时间曲线如下图所示。
5)智能特性
软件是复杂的智力产品,它的开发凝聚了人们大量的脑力劳动,它本身也体现了知识、实践经验和人类的智慧,具有一定的智能。它可以帮助我们解决复杂的计算、分析、判断和决策问题。
6)质量特性
软件产品的质量控制存在着一些实际困难,难以克服,表现在以下方面。
(1)软件产品的需求在软件开发之初常常是不确切的,也不容易确切地给出,并且需求还会在开发过程中变更,这就使软件质量控制失去了重要的可参照物。
(2)软件测试技术存在不可克服的局限性。任何测试都只能在极大数量的应用实例数据中选取极为有限的数据,致使我们无法检验大多数实例,也使我们无法得到完全没有缺陷的软件产品。没有在已经长期使用或反复使用的软件中发现问题,并不意味着今后的使用也不会出现问题。
这一特性提醒我们:一定要警惕软件的质量风险,特别是在某些重要的应用场合需要提前准备好应对策略。
7)环境特性
软件的开发和运行都离不开相关的计算机系统环境,包括支持它的开发和运行的相关硬件和软件。软件对计算机系统的环境有着不可摆脱的依赖性。
8)软件的管理特性
上述的几个特点,使得软件的开发管理显得更为重要,也更为独特。这种管理可归结为对大规模知识型工作者的智力劳动管理,其中包括必要的培训、指导、激励、制度化规程的推行、过程的量化分析与监督,以及沟通、协调,甚至是软件文化的建立和实施。
9)软件的废弃特性
等到软件的运行环境变化过大,或是用户提出了更大、更多的需求变更,再对软件实施适应性维护已经不划算,说明该软件已走到它的生存期终点而将废弃(或称为退役),此时用户应考虑采用新的软件代替。因此,与硬件不同,软件并不是由于“用坏”而被废弃的。
10)应用特性
软件的应用极为广泛,如今它已渗透到国民经济和国防的各个领域,现已成为信息产业、先进制造业和现代服务业的核心,占据了无可取代的地位。
11)软件成本比较高
软件的研制工作需要投入大量、复杂、高强度的脑力劳动,研制成本比较高。在20世纪50年代末,软件的开销大约占总开销的百分之十几,大部分成本花在硬件上。但今天,这个比例完全颠倒过来,软件的开销远远超过硬件的开销。软、硬件成本随时间变化而变化的比例如下图所示。
软件的发展
软件工程是在克服20世纪60年代出现的“软件危机”过程中逐渐形成和发展的。在过去的50年时间里,软件工程在理论和实践方面都取得了长足的进步。它的发展已经经历了四个重要阶段。
1.第一代软件技术
20世纪60年代末,软件生产主要采用“生产作坊”方式。随着软件需求量及规模的迅速扩大,生产作坊方式已不能适应软件生产的需要,出现了所谓的“软件危机”,其主要表现为软件生产效率低下、软件产品质量低劣,在大量劣质的软件涌入市场后不久就在开发过程中夭折。由于“软件危机”的不断扩大,国际软件界面临着巨大的灾难,软件产业濒临崩溃。
为了克服“软件危机”,1968年在北大西洋公约组织(NATO)举行的软件可靠性学术会议上第一次提出了“软件工程”的概念,其核心是将软件开发纳入工程化的轨道,以保证软件开发的效率和质量。
此后,逐渐形成了软件工程的基本概念、框架、技术和方法,以结构化开发方法、Jackson方法等为代表的软件开发方法成为这一阶段的主要开发方法。这一阶段又称为传统的软件工程阶段。
2.第二代软件技术
从20世纪80年代中期开始,相继推出以Smalltalk为代表的面向对象的程序设计语言,面向对象的方法与技术得到迅速发展;从20世纪90年代起,软件工程研究的重点从程序设计语言逐渐转移到面向对象的分析与设计,演化为一种完整的软件开发方法和系统的技术体系。
20世纪90年代以来,形成了以Booch方法、OOSE、OMT等许多面向对象开发方法的流派,面向对象的方法逐渐成为软件开发的主流。尤其是1997年1月,综合了各种面向对象方法优点的统一建模语言UML1.0的正式推出,使面向对象的方法得到了进一步发展,所以这一阶段又称为对象工程。
3.第三代软件技术
随着软件工程规模和复杂度的不断增大,开发人员也随之增多,开发周期相应延长,加之软件是知识密集型的逻辑思维产品,这些都增加了软件工程管理的难度。人们在软件开发的实践过程中逐渐认识到:提高软件生产效率、保证软件质量的关键是对“软件过程”的控制和管理,是软件开发和维护的管理和支持能力。因此提出了对软件项目管理的计划、组织、成本估算、质量保证、软件配置管理等技术与策略,逐步形成了软件过程工程。
4.第四代软件技术
20世纪90年代起,软件复用和基于构件(Component)的开发方法取得重要进展,软件系统的开发可通过使用现成的可复用软件组装完成,而无须从头开始构造,以此达到提高效率和质量、降低成本的目的,软件复用技术及构件技术的发展,为克服软件危机提供了一条有效途径,这已成为当前软件工程的重要研究方向,这一阶段就称为构件阶段。
软件危机
软件危机的主要特征
软件危机的主要特征体现在以下几个方面。
1)软件开发进度难以预测
软件开发过程中的拖延工期现象并不罕见,这种现象降低了软件开发组织的信誉。
2)软件开发成本难以控制
软件开发中投资一再追加,往往实际成本要比预算成本高出一个数量级。而为了赶进度和节约成本所采取的一些权宜之计往往又损害了软件产品的质量,从而不可避免地引起用户的不满。
3)产品功能难以满足用户需求
开发人员和用户之间很难沟通,矛盾很难统一,往往软件开发人员不能真正了解用户的需求,而用户又不了解计算机求解问题的模式和能力,双方无法用共同熟悉的语言进行交流和描述。在双方不充分了解的情况下,就仓促上阵设计系统,匆忙着手编写程序,这种“闭门造车”的开发方式必然导致最终的产品不符合用户的实际需要。
4)软件产品质量无法保证
系统中的错误很难消除。软件是逻辑产品,质量问题很难以统一的标准来度量,因而造成质量控制困难。软件产品并不是没有错误,而是盲目检测很难发现错误,而隐藏下来的错误往往是造成重大事故的隐患。
5)软件产品难以维护
软件产品本质上是开发人员的代码化的逻辑思维活动的产物,他人难以替代,除非是开发者本人,否则很难及时检测、排除系统故障。为使系统适应新的硬件环境,或根据用户的需要,要在原系统中增加一些新的功能,这又有可能增加系统中的错误。
6)软件缺少适当的文档资料
文档资料是软件必不可少的组成部分。缺乏必要的文档资料或文档资料不合格,将给软件开发和维护带来许多严重的困难和问题。
软件危机的具体表现
20世纪60年代末期所发生的软件危机,反映在软件可靠性没有保障、软件维护工作量大、费用不断上升、进度无法预测、成本增长无法控制、程序设计人员无限度增加等各个方面,以致形成人们难以控制软件开发的局面。
软件危机主要表现在如下两个方面:
(1)软件产品质量低劣,甚至在开发过程中就夭折;
(2)软件生产率低,不能满足要求。
软件危机所造成的严重后果已使世界各国的软件产业危机四伏,面临崩溃,因此克服软件危机刻不容缓。自从NATO会议以来,世界各国的软件工作者为克服软件危机进行了许多开创性的工作,在软件工程的理论研究和工程实践两个方面都取得了长足的进步,缓解了软件危机。但距离彻底地克服软件危机这个软件工程的最终目标还任重道远,需要软件工作者付出长期艰苦的努力。
软件危机产生的原因
20世纪60年代,计算机已经应用在很多行业,解决问题的规模及难度逐渐增加,由于软件本身的特点及软件开发方法等多方面问题,软件的发展速度远远滞后于硬件的发展速度,不能满足社会日益增长的软件需求。软件开发周期长、成本高、质量差、维护困难,导致20世纪60年代末软件危机的爆发。导致软件危机爆发的原因主要可以概括为以下几点。
1)用户需求不明确
在软件被开发出来之前,用户自己也不清楚软件开发的具体需求;用户对软件开发需求的描述不精确,可能有遗漏、有二义性甚至有错误;在软件开发过程中,用户还会提出修改软件开发功能、界面、支撑环境等方面的要求;软件开发人员对用户需求的理解与用户的本来愿望有差异。
2)缺乏正确的理论指导
由于软件开发不同于大多数其他工业产品,其开发过程是复杂的逻辑思维过程,其产品很大程度上依赖于开发人员高度的智力投入。过分地依靠程序设计人员在软件开发过程中的技巧和创造性,加剧了软件开发产品的个性化,这也是发生软件危机的一个重要原因。
3)软件开发规模越来越大
随着软件开发应用范围的扩大,软件开发规模越来越大。大型软件开发项目需要组织一定的人力共同完成,然而多数管理人员缺乏开发大型软件系统的经验,多数软件开发人员又缺乏管理方面的经验。各类人员的信息交流不及时、不准确,有时还会产生误解。软件开发人员不能有效地、独立自主地处理大型软件开发的全部关系和各个分支,因此容易产生疏漏和错误。
4)软件开发复杂度越来越高
软件开发不仅仅是在规模上快速地发展扩大,而且其复杂性也急剧地增加。软件开发产品的特殊性和人类智力的局限性,导致人们无力处理“复杂问题”。所谓“复杂问题”的概念是相对的,一旦人们采用的先进组织形式、开发方法和工具提高了软件开发效率和能力,新的、更大的、更复杂的问题又会摆在人们面前。
软件危机的解决途径
1968年,计算机科学家在德国第一次讨论软件危机问题,并正式提出“软件工程”一词,从此一门新兴的工程学科为研究和克服软件危机应运而生。作为一个新兴的工程学科,软件工程学主要研究软件产生的客观规律性,建立与系统化软件生产有关的概念、原则、方法、技术和工具,指导和支持软件系统的生产活动,以期达到降低软件生产成本、改进软件产品质量、提高软件生产率水平的目标。软件工程学从硬件工程和其他人类工程中吸收了许多成功的经验,明确提出了软件生命周期的模型,发展了许多软件开发与维护阶段适用的技术和方法,并应用于软件工程实践,取得了良好的效果。
在软件开发过程中,人们开始研制和使用软件工具,用于辅助进行软件项目管理与技术生产,人们还将软件生命周期各阶段使用的软件工具有机地集合成一个整体,形成能够连续支持软件开发与维护全过程的集成化软件支撑环境,以期从管理和技术两方面解决软件危机问题。
软件工程
软件工程的定义
软件工程是一门指导计算机软件开发和维护的工程学科,是一门边缘学科,涉及计算机科学、工程科学、管理科学、数学等多学科,研究的范围广,主要研究如何应用软件开发的科学理论和工程技术来指导大型软件系统的开发。
虽然对软件工程有着众多的定义,但是其基本思想都是强调在软件开发过程中应用工程化的重要性。
例如,1983年,IEEE(电气和电子工程师协会)所下的定义是:软件工程是开发、运行、维护和修复软件的系统方法。1990年,IEEE又将定义更改为:对软件开发、运行、维护的系统化的、有规范的、可定量的方法之应用,即是对软件的工程化应用。
2004年,IEEE/ACM联合发布的CCSE2004报告强调了对软件工程的新定义,即软件工程是“以系统的、科学的、定量的途径,把工程应用于软件的开发、运行和维护;同时,开展对上述过程中各种方法和途径的研究”。这也是目前一种比较广泛认可的定义。
从软件工程的定义可见,软件工程是一门指导软件系统开发的工程学科,它以计算机理论及其他相关学科的理论为指导,采用工程化的概念、原理、技术和方法进行软件的开发和维护,把实践证明的、科学的管理措施与最先进的技术方法结合起来。软件工程研究的目标是“以较少的投资获取高质量的软件”。它包括3个要素:方法、工具和过程。
(1)软件工程方法为软件开发提供了“如何做”的技术,是指导开发软件的某种标准规范。它包括多方面的任务,如项目计划与估算、软件系统需求分析、数据结构、系统总体结构的设计、算法的设计、编码、测试及维护等。软件工程方法常采用某种特殊的语言或图形的表达方法及一套质量保证标准。
(2)软件工具是指软件开发、维护和分析中使用的程序系统,为软件工程方法提供自动的或半自动的软件支撑环境。
(3)软件工程的过程则是将软件工程的方法和工具综合起来,以达到合理、及时地进行计算机软件开发的目的。过程定义了方法使用的顺序、要求交付的文档资料、为保证质量和协调变化所需的管理及软件开发各个阶段完成的“里程碑”。
软件工程的背景
为了克服软件危机,1968年10月,NATO召开的计算机科学会议上,Fritz Bauer首次提出“软件工程”的概念,企图将工程化方法应用于软件开发上。
许多计算机和软件科学家尝试把其他工程领域中行之有效的工程学知识运用到软件开发工作中来。经过不断实践和总结,最后得出一个结论:按工程化的原则和方法组织软件开发工作是有效的,是摆脱软件危机的一条主要道路。
虽然软件工程的概念提出已有40多年,但到目前为止,软件工程概念的定义并没有得到认可。在NATO会议上,Fritz Bauer对软件工程的定义是:“为了经济地获得可靠的和能在实际机器上高效运行的软件,而建立和使用的健全的工作原则。”除了这个定义,还有几种比较有代表性的定义。
B.W.Boehm给出的定义是:“运用现代科学技术知识来设计并构造计算机程序及为开发、运行和维护这些程序所必需的相关文件资料。”此处,“设计”一词广义上应理解为包括软件的需求分析和对软件进行修改时所进行的再设计活动。
1983年,IEEE给出的定义是:“软件工程是开发、运行、维护和修复软件的系统方法。”其中,“软件”的定义为计算机程序、方法、规则、相关的文档资料以及在计算机上运行时所必需的数据。
后来尽管又有一些人提出了许多更为完善的定义,但主要思想都是强调在软件开发过程中应用工程化原则的重要性。
我国2006年的国家标准GB/T 11457—2006《软件工程术语》中对软件工程的定义为:“应用计算机科学理论和技术以及工程管理原则和方法,按预算和进度,实现满足用户需求的软件产品的定义、开发、发布和维护的工程或进行研究的学科。”
概括地讲,软件工程是指导软件开发和维护的工程性学科,它以计算机科学理论和其他相关学科的理论为指导,采用工程化的概念、原理、技术和方法进行软件的开发和维护,把经过时间考验而证明是正确的管理技术和当前能够得到的最好的技术方法结合起来,以较少的代价获得高质量的软件并维护它。
软件工程的基本原理
著名软件工程专家B.W.Boehm于1983年综合了软件工程专家、学者们的意见,并总结了开发软件的经验,提出了软件工程的7条基本原理。这7条原理被认为是确保软件产品质量和开发效率的原理的最小集合,又是相互独立、缺一不可、相当完备的最小集合。
下面简要介绍软件工程的7条基本原理。
1)用分阶段的生命周期计划严格管理
在软件开发与维护的漫长的生命周期中,需要完成许多性质各异的工作。这条基本原理意味着,应该把软件生命周期划分为若干个阶段,并相应地提出切实可行的计划,然后严格按照计划对软件的开发和维护工作进行管理。Boehm认为,在软件的整个生命周期中,应该制订并严格地执行6类计划,它们是项目概要计划、里程碑计划、项目控制计划、产品控制计划、验证计划及运行维护计划。
不同层次的管理人员都必须严格按照计划各尽其责地管理软件开发与维护工作,绝不能受客户和上级人员的影响而擅自背离预定计划。
2)坚持进行阶段评审
软件的质量保证工作不能等到编码工作结束之后再进行。这样说至少有两个理由:第一,大部分错误是在编码之前造成的,有统计表明,设计错误占软件错误的63%,编码错误仅占37%;第二,错误发现与改正的时间越晚,所付出的代价就越高。因此,每个阶段都要对软件的质量进行严格的评审,以便尽早地发现在软件开发工作中所犯的错误,这是一条必须遵循的重要准则。
3)实行严格的产品控制
在软件开发过程中不应随意改变需求,因为改变一项需求往往需要付出较高的代价。但是,在软件开发过程中改变需求又是不可避免的,由于外部环境的变化,相应地改变用户需求是一种客观需要,显然不能硬性禁止客户提出改变需求的要求,而只能依靠科学的产品控制技术来顺应这种要求。
4)采用现代程序设计技术
从提出软件的概念开始,人们一直把主要精力用于研究各种新的程序设计技术。20世纪60年代末提出的结构程序设计技术,已经成为公认的、先进的程序设计技术,后来又进一步发展出各种结构分析(SA)与结构设计(SD)技术。实践表明,采用先进的技术既可以提高软件开发的效率,又可以提高软件维护的效率。
5)结果应能清楚地审查
软件产品不同于一般的物理产品,它是看不见摸不着的逻辑产品。软件开发人员(或开发小组)的工作进展情况可见性差,难以准确度量,从而使得软件产品的开发过程比一般产品的开发过程更难以评价和管理。为了提高软件产品开发过程的可见性,更好地进行管理,应该根据软件开发项目的总目标及完成期限,规定开发组织的责任和产品标准,从而使所得到的结果能够清楚地审查。
6)开发小组的人员应该少而精
这条基本原理的含义是,软件开发小组组成人员的素质要好,而人数不宜过多,开发小组素质和数量是影响软件产品质量和开发效率的重要因素。素质高的人员的开发效率比素质低的人员的开发效率可能高几倍至几十倍,而且素质高的人员所开发的软件中的错误数量明显少于素质低的人员所开发的软件中的错误数量。此外,随着开发小组人员数目的增加,交流情况、讨论问题而造成的通信开销也急剧增加。当开发小组人数为N时,可能的通信路径有N(N-1)/2条,可见随着人数N的增大,通信开销将急剧增加。因此,人员少而精的开发小组是软件工程的一项基本原则。
7)承认不断改进软件工程实践的必要性
遵循上述1)~6)条基本原理,就能够按照当代软件工程基本原理实现软件的工程化生产,但是仅有上述1)~6)条原理并不能保证软件开发与维护的过程能赶上时代前进的步伐,也不能保证能跟上技术的不断进步。因此,Boehm提出应把承认不断改进软件工程实践的必要性作为软件工程的第7条基本原理。按照这条原理,不仅要积极主动地采纳新的软件技术,而且要不断地总结经验,例如,收集进度和资源耗费数据,收集出错类型和问题报告数据,等等。这些数据不仅可以用于评价新的软件技术的效果,而且可以用于指明必须着重开发的软件工具和应该优先研究的技术。
软件工程工具
1.需求分析工具
需求分析工具的功能与所采用的系统开发方法密不可分。按所采用的系统开发方法,需求分析工具可分为结构化图形工具箱、面向对象模型化工具及分析工具。
1)结构化图形工具箱
这类工具需要通过数据流图(DFD)进行功能分析、包括DFD图形工具、实体-关系(ER)图形工具、Jackson图形工具、Warnier/Orr图形工具。
2)面向对象模型化工具及分析工具
这类工具需要通过对象建立构造系统的抽象模型,一般包括图形工具、对象浏览器及类库管理系统。
(1)图形工具。UML已经成为业界标准,支持面向对象的建模。因此,分析工具应该支持UML建模,如建立用例图、类图、顺序图、协作图、状态图、构件图及配置图等。
(2)对象浏览器。对象浏览器是一个允许开发者驾驭类继承的多窗口程序,它通常通过直接存取类的源代码来进行编辑。
(3)类库管理系统。类库管理系统的一个重要作用是增加可重用类的数量。随着类数量的增加,需要一些查找类的方法,类库管理系统就是一种允许选择和编辑类,并按照所需标准对类进行描述的工具。
有代表性的商品化工具如下。
①Rational Rose,由Rational Corporation开发。
②PowerDesigner,由Sybase设计。
③Visio,由Microsoft开发。
④ArgoUML,开源工具。
⑤Control Center,由TogetherSoft开发。
⑥Enterprise Architect,由Sparx Systems开发。
⑦Object Technology Workbench(OTW),由OTW Software开发。
⑧System Architect,由Popkin Software开发。
⑨UML Studio,由Pragsoft Corporation开发。
⑩Visual UML,由Visual Ob ject Modelers开发。
2.设计工具
设计阶段分为概要设计和详细设计。概要设计的主要任务是进行系统总体结构设计;详细设计的主要任务是设计软件算法和内部实现细节。
对于概要设计活动和详细设计活动,设计工具通常可分为概要设计工具和详细设计工具等两类。
1)概要设计工具
概要设计工具用于辅佐设计人员设计目标软件的体系结构、控制结构和数据结构。软件的体系结构通常用模块结构图来描述,它指明软件系统的模块组成及其调用关系、模块的接口定义等。模块的数据结构通常用实体-关系图来描述。
有代表性的商品化工具如下。
(1)Rational Rose,由Rational Corporation开发,是基于UML的设计工具,它支持体系结构设计中的所有方面。
(2)Adalon,由Synthis公司开发,是用于设计和构建专门基于Web构件体系结构的特定设计工具。
(3)Objectif,由Micro TOOL GmbH开发,是一个基于UML的设计工具,它用于设计符合基于构建的软件工程的各种体系结构(如Coldfusion、J2EE和Fusebox等)。
2)详细设计工具
详细设计工具用于辅佐设计人员设计模块的算法和内部实现细节。详细设计规范的图形描述方法通常有输入-处理-输出(Input-Process-Output,PO)图、问题分析图(Problem Analysis Diagram,PAD)、盒图(也称为N-S图)、流程图(Flow Chart,FC)等。详细设计规范的语言描述方法通常有程序设计语言(Program Design Language,PDL)、结构化语言等,其表格描述方法通常有判定表和判定树。
3.编码工具和排错工具
辅助程序员进行编码活动的工具有编码工具和排错工具。编码工具辅助程序员用某种程序设计语言编写源程序,并对源程序进行翻译,最终转换成可执行的代码。因此,编码工具通常与编码所使用的程序设计语言密切相关。排错工具用于辅助程序员寻找程序中错误的性质和原因,并确定其出错的位置。
由于源程序一般以正文的形式出现,因此必须用编辑器将它输入并进行浏览、编辑和修改。又由于源程序的编写往往不可能一次成功,需要不断寻找其中的错误,并加以纠正。因此,编码工具和排错工具是编程活动中的重要辅助工具,也是最早出现的软件工具。
4.测试工具
测试工具分为程序单元测试工具、组装测试工具和系统测试工具。
1)程序单元测试工具
早期的程序单元测试工具有静态分析工具、动态分析工具和自动测试支持工具三类。
目前最流行的单元测试工具是xUnit系列框架,根据语言不同而分为JUnit(Java)、CppUnit(C++)、DUnit(Delphi)、NUnit(.NET)、phpUnit(PHP)等。该测试框架的第一个和最杰出的应用就是有Erich Gamma(《设计模式》的作者)和Kent Beck(XP(极限编程)的创始人)提供的开放源代码的JUnit。
2)组装测试工具
组装测试也称为集成测试或联合测试。在单元测试的基础上,将所有模块按照设计要求组装成子系统或系统,再进行组装测试。实践表明,一些模块虽然能够单独工作,但并不能保证连接起来也能正常工作。程序在某些局部反映不出来的问题,很可能在全局上暴露出来,影响功能的实现。
有代表性的组装测试工具如下。
(1)WinRunner,由Mercury Interactive公司开发,是一种企业级的功能测试工具,用于检测应用程序是否能够达到预期的功能及正常运行。
(2)IBM Rational Robot,是业界最顶尖的功能测试工具。它集成在测试人员的桌面IBM Rational TestManager上,测试人员可以计划、组织、执行和报告所有测试活动。
(3)Borland SilkTest 2006,属于软件功能测试工具,是Borland公司提出的软件质量管理解决方案的套件之一。这个工具采用精灵设定与自动化执行测试,无论是程序设计新手还是资深的专家都能快速建立功能测试,并分析功能错误。
(4)TestDirector,是业界第一个基于Web的测试管理系统,它可以在公司内部或外部进行全球范围内的测试管理。通过在一个整体的应用系统中集成测试管理的各个部分,包括需求管理、测试计划、测试执行及错误跟踪等功能,极大地加速了测试过程。
3)系统测试工具
系统测试是对整个基于计算机的系统进行一系列不同的考验,它通常是耗费测试资源最多的测试。除了功能测试之外,负载测试、性能测试、可靠性测试和其他一些测试一般也都是在系统测试期间进行的。
有代表性的系统测试工具如下。
(1)LoadRunner,是一种预测系统行为和性能的负载测试工具。通过模拟上千万用户,实施并发布负载及实时性能监测的方式来确认和查找问题,LoadRunner能够对整个企业架构进行测试。
(2)OTF(Object Testing Framework),由MCG软件公司开发,为Smalltalk对象的测试提供管理框架。
(3)QADirector,由Compuware Corp.开发,为管理测试过程的各个阶段提供简单的控制。
(4)TestWorks,由Software Research Inc.开发,包含一个完整的测试工具集,包括测试管理与测试报告。
软件过程
软件生存周期
软件生存周期(SDLC,又称为软件生命周期)是指软件的产生直到报废的生命周期。目前划分软件生存周期的方法有许多种,软件规模、种类、开发方式、开发环境及开发时使用的方法论等都会影响软件生存周期。
在划分软件生存周期的阶段时应遵循一条基本原则:各阶段的任务彼此间相互独立,同一阶段的各项任务的性质尽可能相同,从而降低每个阶段任务的复杂程度,简化不同阶段之间的联系。
一般来说,软件生存周期由软件定义、软件开发和软件维护三个时期组成,每个时期又划分为若干个阶段。以时间分程可将软件生存周期划分为计划、需求分析、总体设计、详细设计、程序编码、软件测试及运行维护7个阶段。每个阶段有明确的任务,这样使规模大、结构复杂和管理复杂的软件开发变得容易控制和管理。
1.计划
此阶段由软件开发方与需求方共同讨论,软件计划包括问题定义和可行性研究,主要任务是确定要开发软件的总目标,给出它的功能、性能、可靠性及接口等方面的设想。此阶段主要研究完成该软件任务的可行性,探讨解决问题的方案,并对可供使用的资源、成本、可取得的效益和开发进度作出估计,制定完成开发任务的实施计划。
2.需求分析
需求分析的主要任务是确定目标系统必须具备哪些功能。软件设计员在该阶段必须与用户密切配合,充分交流信息,以得出经过用户确认的系统逻辑模型,并写出软件需求说明书或功能说明书及初步的系统用户手册,提交管理机构评审。
3.总体设计
在总体设计阶段,设计人员要把已确定了的各项需求转换成一个相应的体系结构,结构中每个组成部分都是意义明确的模块,每个模块都和某些需求相对应。另外,设计人员还应该使用系统流程图或其他工具描述实际系统的可能解决方案,并估算每种方案的成本和效益,还应该在充分权衡各种方案利弊的基础上,给用户推荐一个最佳方案。如果用户接受设计人员的推荐方案,则可以开始着手详细设计。
4.详细设计
在总体设计阶段,设计人员用抽象概括的方式提出系统的体系结构和功能模块。而详细设计阶段的任务就是将实现系统的步骤具体化。这种具体化还不是编写代码,而是对系统的每个模块要完成的工作进行具体的描述,并确定输入、输出,以便在编码之前可以评价软件质量,并为编码打下基础。
通常用HIPO图(层次图加输入/处理/输出图)或PDL语言(过程设计语言)描述详细设计的结果。
5.程序编码
这个阶段程序员的关键任务是根据目标系统的性质和实际环境,选取一种高级程序设计语言,将详细设计的结果翻译成用选定的语言书写的程序,并仔细地测试每个模块的功能。
6.软件测试
软件测试阶段的任务是通过各种类型的测试,使软件符合预定的要求。其主要方式是在设计测试用例的基础上检验软件的各个组成部分。首先进行单元测试以发现模块在功能和结构方面的问题,其次将已测试过的模块组装起来进行集成测试,再次进行验收测试,验收测试时按照需求规格说明的规定,由用户对目标系统进行验收。
必要时还可以通过现场测试或平行运行等方法对目标系统进行进一步的测试。通过对软件测试结果的分析可以预测软件的可靠性;反之,根据对软件可靠性的要求,也可以决定测试和调试过程的结束时间。
用证书的文档资料将测试计划、详细测试方案及实际测试结果保存下来,作为软件配置的一个组成部分。
7.运行维护
运行维护的主要任务是进行系统的日常运行管理,根据一定的规格对系统进行必要的修改,评价系统的运行效率、工作质量和经济效益,对运行费用和效果进行监理审计。软件交付用户后,便进入运行阶段。在运行阶段中,可能由于多方面的原因,需要对它进行修改。例如,为适应外部环境的变化和用户要求而添加新的功能;或是随着制作工艺的提高,将原来的工作流程做相应的改动;等等。运行维护时在软件生存周期的各个阶段去调整现有系统,而不是开发一个新的项目。
软件过程模型
所谓软件过程模型就是一种开发策略,这种策略针对软件工程的各个阶段提供了一套规范,使工程的进展能达到预期的目的。对一个软件的开发无论其大小,我们都需要选择一种合适的软件过程模型,这种选择基于项目和应用的性质、采用的方法、需要的控制,以及要交付的产品的特点。
目前,常见的软件开发模型大致可分为如下3类:
(1)以需求完全确定为前提的开发模型,如瀑布模型;
(2)在软件开发初始阶段只能提供基本需求时采用的渐进式开发模型,如原型模型、螺旋模型、协同模型等;
(3)以形式化开发方法为基础的专用过程模型。
瀑布模型
瀑布模型即生存模型,其核心思想是按工序将问题简化,将功能设计与设计分离。瀑布模型将软件生存周期划分为计划、需求分析、设计、编码、测试和运行维护等6个基本活动,并且规定了它们自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落,如下图所示。
按照传统的瀑布模型来开发软件,有如下几个特点。
1.阶段间具有顺序性和依赖性
(1)必须等前一个阶段工作完成后,才能开始后一阶段的工作;
(2)前一阶段的输出文档就是后一阶段的输入文档,因此只有前一阶段的输出文档正确,后一阶段的工作才能获得正确结果。
2.推迟实现的观点
瀑布模型在编码之前设置了计划、需求分析、设计3个阶段。需求分析与设计阶段的基本任务规定,在这两个阶段主要考虑目标系统的逻辑模型,不涉及软件的物理实现。清楚地区分逻辑设计与物理设计,尽可能推迟程序的物理实现,是瀑布模型的一条重要指导思想,可以避免项目中不必要的大量返工。
3.质量保证的观点
1)瀑布模型的每个阶段都应坚持两个重要做法
(1)每个阶段都必须完成规定的文档,没有完成合格的文档就是没有完成该阶段的任务。
(2)每个阶段结束前都要对所完成的文档进行评审,以便尽早的发现和改正问题。
2)瀑布模型的缺点
以上是隐含在软件生存周期各个阶段后面的指导思想,是比具体任务更重要的内容。但是,这种模型的线性过程太理想化,已不再适合现代的软件开发模式,几乎被业界抛弃,其主要问题在于以下几个方面:
(1)各个阶段的划分完全固定,阶段之间产生大量的文档,极大地增加了工作量;
(2)由于开发模型是线性的,用户只有等到整个过程的末期才能见到开发成果,从而增加了开发的风险;
(3)早期的错误可能要等到开发后期的测试阶段才能发现,进而带来严重的后果。
我们应该认识到,“线性”是人们最容易掌握并能熟练应用的思维方法。当人们碰到一个复杂的“非线性”问题时,总是千方百计地将其分解或转化为一系列简单的线性问题,然后逐个解决。一个软件系统的整体可能是复杂的,而单个子程序总是简单的,可以用线性的方式来实现。线性是一种简洁,简洁就是美。当我们领会了线性的精神,就不要再呆板地套用线性模型的外表,而应该灵活使用它。例如,增量模型实质上就是分段的线性模型,螺旋模型则是连接的弯曲了的线性模型,在其他模型中也能够找到线性模型的影子。
增量模型
增量模型融合了线性顺序模型的基本成分和原型模型的迭代特征。这种模型采用随着日程时间的进展而交错的线性序列。每一个线性序列产生软件的一个可发布的“增量”。当使用增量模型时,第一个增量往往是核心的产品,也就是说第一个增量实现了基本的需求,但很多补充的特征还没有发布。客户对每一个增量的使用和评估,都作为下一个增量发布的新特征和功能。在每一个增量发布后不断重复这个过程,直到产生了最终完善的产品为止。增量模型强调每一个增量均发布一个可操作的产品。采用增量模型的软件过程如下图所示。
增量模型像原型模型一样具有迭代的特征。但与原型模型不一样,增量模型强调每一个增量均发布一个可操作产品。早期的增量是最终产品的“可拆卸”版本,但它们确实给用户提供了服务的功能,并且给用户提供了评估的平台。
增量开发是很有用的,尤其是当配备的人员不能在为该项目设定的市场期限之前实现一个完全的版本时,早期的增量可以由较少的人员实现。如果核心产品很受欢迎,那么可以增加新的人手实现下一个增量。此外,增量能够有计划地管理技术风险,例如,系统的一个重要部分需要使用正在开发的并且发布时间尚未确定的新硬件,有可能计划在早期的增量中避免使用该硬件,这样就可以首先发布部分功能给用户,以免过分地拖延系统的问世时间。
演化过程模型
演化过程模型是一种全局的软件生存周期模型,属于迭代开发的模型。该模型的基本思想为:根据用户的基本需求,通过快速分析构造出该软件的原型,然后根据用户在使用原型过程中提出的意见和建议对原型进行改进,获得原型的新版本。重复这一过程,最终可以得到令用户满意的软件产品。
该模型可以表示为第一次迭代(需求→设计→实现→测试→集成)→反馈→第二次迭代→反馈→……
本小节主要介绍二种演化过程模型:原型模型和螺旋模型。
1.原型模型
原型就是可以逐步改进成运行系统的模型。开发者在初步了解用户需求的基础上,凭借自己对用户需求的理解,通过强有力的软件环境支持,利用软件快速开发工具,构成﹑设计和开发一个实在的软件初始模型(原型,一个可以实现的软件应用模型)。利用原型模型进行软件开发的流程如下图所示。相对瀑布模型,原型模型更符合人们开发软件的习惯,是目前较流行的一种实用软件生存模型。
1)原型模型的优点
(1)开发人员和用户在“原型”上达成一致。这样一来,可以减少设计中的错误和开发中的风险,也减少了对用户培训的时间,从而提高了系统的实用性﹑正确性及用户满意度。
(2)原型模型采用逐步求精的方法完善原型,使得原型能够快速开发,避免了像瀑布模型一样冗长的开发过程中难以对用户的反馈作出快速响应。
(3)原型模型通过“样品”不断改进,降低了成本。
(4)原型模型的应用使人们对需求有了渐进的认识,从而使软件开发更有针对性。另外,原型模型的应用充分利用了最新的软件工具,使软件开发效率大为提高。
2)原型模型的缺点
虽然用户和开发者都非常喜欢原型模型,因为它使用户能够感受到实际的软件系统,开发人员能很快建造出一些内容。但该模型仍然存在着一些问题,其原因如下。
(1)用户看到的是一个可运行的软件版本,但不知道这个原型是临时搭建起来的,也不知道软件开发者为了使原型尽快运行,并没有考虑软件的整体质量或以后的可维护性问题。当被告知该产品必须重建才能使其达到高质量时,用户往往叫苦连天。
(2)开发人员常常需要在实现上采取折中的办法,以使原型能够尽快工作。开发人员很可能采用一个不合适的操作系统或程序设计语言,仅仅因为它通用或有名,也可能使用一个效率低的算法,仅仅为了实现演示功能。经过一段时间之后,开发人员可能对这些选择已经习以为常了,忘记了它们不合适的原因。于是,这些不理想的选择就成了软件的组成部分。
虽然会出现问题,但原型模型仍是软件工程的一个有效典范。使用原型模型开发系统时,用户和开发者必须达成一致:原型被建造仅仅是用户用于定义需求,不宜利用它来作为最终产品,之后被部分或全部抛弃,最终的软件是要充分考虑了质量和可维护性等方面之后才被开发。
2.螺旋模型
对于复杂的大型软件,开发一个原型往往达不到要求。螺旋模型将瀑布模型和原型模型结合起来,这不仅体现了两个模型的优点,而且还增加了两个模型都忽略了的风险分析,弥补了两者的不足。
1)螺旋模型的结构
螺旋模型的结构如下图所示,它由4部分组成:制订计划、风险分析、实施开发和客户评估。在笛卡儿坐标的4个象限中分别表达了4个方面的活动。
沿螺旋线自内向外每旋转一圈便开发出一个更为完善的新的软件版本。例如,第一圈时,在制订计划阶段,确定了初步的目标、方案和限制条件以后,转入风险分析阶段,对项目的风险进行识别和分析。如果风险分析表明需求有不确定性,但是可以承受风险,那么在实施开发阶段,所建的原型会帮助开发人员和用户对需求做进一步的修改。软件开发完成后,客户会对工程成果做出评价,给出修正建议。在此基础上进入第二圈螺旋,再次进行制订计划、风险分析、实施开发和客户评估等工作。假如风险过大,开发者和用户无法承受,那么有可能终止项目。多数情况下,软件开发过程是沿螺旋线的路径连续进行的,自内向外,逐步延伸,最终总能得到一个用户满意的软件版本。
2)螺旋模型的优点
螺旋模型的优点在于:设计上的灵活性,可以在项目的各个阶段进行变更;以小的分段来构建大型系统,使成本计算变得简单容易;客户始终参与每个阶段的开发,保证了项目不偏离正确方向及项目的可控性;随着项目推进,客户始终掌握项目的最新信息,从而能够与管理层有效地交互;客户认可这种公司内部的开发方式带来的、良好的沟通和高质量的产品。
3)螺旋模型的缺点
螺旋模型的缺点在于:很难让用户确信这种演化方法的结果是可以控制的;建设周期长,而软件技术发展比较快,所以经常出现软件开发完毕后,与当前的技术水平有较大的差距,无法满足当前用户的需求。
螺旋模型不仅保留了瀑布模型中系统地、按阶段逐步地进行软件开发和“边开发、边评审”的风格,而且还引入了风险分析,并把制作原型作为风险分析的主要措施。用户始终关心、参与软件开发,并对阶段性的软件产品提出评审意见,这对保证软件产品的质量是十分有利的。但是,螺旋模型的使用需要具有相当丰富的风险评估经验和专门知识,而且开发费用昂贵,所以只适合大型软件的开发。
2、软件分析
可行性研究
可行性研究的任务
我们知道并不是所有问题都有简单明显的解决办法的,事实上,许多问题不可能在预定的系统规模之内解决。如果问题没有可行的解,那么花费在这项开发工程上的时间、资源、人力和费用都是无谓的浪费。
可行性研究的目的就是用最小的代价在尽可能短的时间内确定问题是否能够解决。必须记住,可行性研究的目的不是解决问题,而是确定问题是否值得去解。怎样达到这个目的呢?当然不能靠主观猜想,而只能靠客观分析。必须分析几种主要的可能解法的利弊,从而判断原定的系统目标和规模是否现实,系统完成后所能带来的效益是否大到值得投资开发这个系统的程度。因此,可行性研究实质上是要进行一次大大压缩简化了的系统分析和设计的过程,也就是在较高层次上以较抽象的方式进行系统分析和设计的过程。
首先需要进一步分析和澄清问题定义。在问题定义阶段要初步确定规模和目标,如果是正确的就进一步加以肯定,如果是错误的就应该及时改正;如果对目标系统有任何约束和限制,就必须清楚地把它们列举出来。
在澄清了问题定义之后,分析员应该导出系统的逻辑模型,然后从系统逻辑模型出发,探索若干种可供选择的主要解法(系统实现方案)。对每种解法都应该仔细研究它的可行性,一般说来,至少应该从下述三方面研究每种解法的可行性。
(1)技术可行性,使用现有的技术能实现这个系统吗?
(2)经济可行性,这个系统的经济效益能超过它的开发成本吗?
(3)操作可行性,系统的操作方式在这个用户组织内行得通吗?
分析员应该为每个可行的解法制定一个粗略的实现进度。
当然,可行性研究最根本的任务是对以后的行动方针提出建议。如果问题没有可行的解,分析员应该建议停止这项开发工程,以避免时间、资源、人力和费用的浪费;如果问题值得求解,分析员应该推荐一个较好的解决方案,并且为工程制订一个初步的计划。
可行性研究需要的时间长短取决于工程的规模,一般说来,可行性研究的成本只是预期工程总成本的5%~10%。
可行性研究的步骤
典型的可行性研究过程有下述一些步骤。
1.复查系统规模和目标
分析员访问关键人员,仔细阅读和分析有关的材料,以便对问题定义阶段书写的关于规模和目标的报告书进一步复查确认,改正含糊或不确切的叙述,清晰地描述对目标系统的一切限制和约束。这个步骤的工作,实质上是为了确保分析员正在解决的问题确实是要求解决的问题。
2.研究目前正在使用的系统
现有的系统是信息的重要来源。显然,如果目前有一个系统正被人使用,那么这个系统必定能完成某些有用的工作,因此,新的目标系统必须也能完成它的基本功能;另一方面,如果现有的系统是完美无缺的,用户自然不会提出开发新系统的要求,因此,现有的系统必然有某些缺点,新系统必须能解决旧系统中存在的问题。此外,运行使用旧系统所需的费用是一个重要的经济指标,如果新系统不能增加收入或减少使用费用,那么从经济角度来看新系统就不如旧系统。
应该仔细阅读分析现有系统的文档资料和使用手册,也要实地考察现有的系统。应该注意了解这个系统可以做什么,为什么这样做,还要了解使用这个系统的代价。在了解上述这些信息时必须访问有关的人员。在调查访问时分析员和用户之间的关系有点类似于医生和病人的关系,用户叙述的往往是“症状”而不是实际问题,分析员必须分析所得到的信息。
常见的错误做法是花费过多时间去分析现有的系统。这个步骤的目的是了解现有系统能做什么,而不是了解它怎样做这些工作。分析员应该画出现有系统的高层系统流程图,并请有关人员检验他对现有系统的认识是否正确。千万不要花费太多时间去了解和描绘现有系统的实现细节,除非是为了阐明一个特别关键的算法,否则不需要根据程序代码画出程序流程图。
没有一个系统是在“真空”中运行的,绝大多数系统都和其他系统有联系。应该注意了解并记录现有系统和其他系统之间的接口情况,这是设计新系统时的重要约束条件。
3.导出新系统的高层逻辑模型
优秀的设计过程通常总是从现有的物理系统出发,导出现有系统的逻辑模型,再参考现有系统的逻辑模型,设想目标系统的逻辑模型,最后根据目标系统的逻辑模型建造新的物理系统。
通过前一步的工作,分析员对目标系统应该具有的基本功能和所受的约束已有一定了解,能够使用数据流图,描绘数据在系统中流动和处理的情况,从而概括地表达出其对新系统的设想。通常为了把新系统描绘得更加清晰、准确,还应该有一个初步的数据字典来定义系统中使用的数据。数据流图和数据字典共同定义了新系统的逻辑模型,以后可以从这个逻辑模型出发设计新系统。
4.重新定义问题
新系统的逻辑模型实质上表达了分析员对新系统必须做什么的看法。用户是否也有同样的看法呢?分析员应该和用户一起再次复查问题定义、工程规模和目标,这次复查应该把数据流图和数据字典作为讨论的基础。如果分析员对问题有误解或用户曾经遗漏了某些要求,那么现在是发现和改正这些错误的时候了。
可行性研究的前四个步骤实质上构成一个循环。分析员定义问题,分析这个问题,导出一个试探性的解;在此基础上再次定义问题,再一次分析这个问题,修改这个解;继续这个循环过程,直到提出的逻辑模型完全符合系统目标为止。
5.导出和评价供选择的解法
分析员应该从其建议的系统逻辑模型出发,导出若干个较高层次的(较抽象的)物理解法进行比较和选择。导出供选择解法的最简单的途径,是从技术角度出发考虑解决问题的不同方案。分析员可以确定几组不同的自动化边界,然后针对每一组边界考虑如何实现要求的系统;还可以使用组合的方法导出若干种可能的物理系统,例如,在每一类计算机上可能有几种不同类型的系统,如微处理机上的批处理系统、微处理机上的交互式系统、小型机上的批处理系统等,此外还应该把现有系统和人工系统作为两种可能的方案一起考虑。
在从技术角度提出了一些可能的物理系统之后,应该根据技术可行性初步排除一些不现实的系统。例如,如果要求系统的响应时间不超过几秒钟,显然应该排除任何批处理方案。在把技术上行不通的解法去掉之后,就剩下一组技术上可行的方案。
其次可以考虑操作方面的可行性。分析员应该根据使用部门处理事务的原则和习惯检查技术上可行的方案,去掉其中从操作方式或操作过程的角度看用户不能接受的方案。
接下来应该考虑经济方面的可行性。分析员应该估计余下的每种可能的系统开发成本和运行费用,并且估计相对于现有的系统而言该系统可以节省的费用或可以增加的收入。在这些估计数字的基础上,对每个可能的系统进行成本、效益分析。
一般说来,只有投资预计能带来利润的系统才值得进一步考虑。
最后为每个在技术、操作和经济等方面都可行的系统制定实现进度表,这个进度表不需要(也不可能)制定得很详细,通常只需估计生存周期每个阶段的工作量。
6.推荐行动方针
根据可行性研究结果做出的一个关键性决策是:是否继续进行这项开发工程。分析员必须清楚地表明他对这个关键性决策的建议。如果分析员认为值得继续进行这项开发工程,那么就应该选择一种最好的解法,并且说明选择这个解决方案的理由。通常,使用部门的负责人主要根据经济上是否划算决定是否投资一项开发工程,因此对于所推荐的系统,分析员必须进行比较仔细的成本、效益分析。
7.草拟开发计划
分析员应该进一步为推荐的系统草拟一份开发计划,除了工程进度表之外还应该估计对各种开发人员(系统分析员、程序员、资料员等)和各种资源(计算机硬件、软件工具等)的需要情况,应该指明使用时间及使用时间的长短。此外,还应该估计系统生存周期中每个阶段的成本。最后,应该给出下一个阶段(需求分析)的详细进度表和成本估计。
8.书写文档,提交审查
应该把上述可行性研究中各个步骤的结果写成清晰的文档,请用户和使用部门的负责人仔细审查,以决定是否继续这项工程及是否接受分析员推荐的方案。
可行性研究报告
可行性分析的结果要用可行性分析报告的形式编写出来,内容包括引言、系统开发的必要性和意义、现行系统调查与分析、新系统的几种方案介绍、新旧系统方案比较、结论。
可行性分析结论应明确指出以下内容:系统具备立即开发的可行性,可进入软件开发的下一个阶段;若可行性分析结果完全不可行,则软件开发工作必
以上是关于软件工程基础知识的主要内容,如果未能解决你的问题,请参考以下文章