软件工程(SoftwareEngineering)是在处理20世纪60年代末所出现的“软件危机”的过程中逐渐形成与发展的。它是一门指导计算机软件系统开发和维护的工程学科,是一门新兴的边缘学科,主要研究如何应用软件开发的科学理论和工程技术来指导大型软件系统的开发,是涉及计算机科学、工程科学、管理科学、数学等领域的一门综合性的交叉学科。它借鉴传统工程的原则、方法,以提高质量、降低成本为目的。本章主要围绕现代软件工程这一概念展开,包括软件、软件危机、软件工程、软件的生命周期和软件工程的目标和原则。
软件的概念
在计算机系统发展的早期时代(20世纪60年代中期以前),通用硬件相当普遍,软件却是为每个具体应用而专门编写的。这时的软件通常是规模较小的程序,编写者和使用者往往是同一个(或同一组)人。这种个体化的软件环境,使得软件设计通常是在人们头脑中进行的一个隐含的过程,除了程序清单之外,没有其他文档资料保存下来。
随着软件的不断发展和完善,才形成了软件的定义。软件是计算机系统中与硬件相互依存的另一部分,它是包括程序、数据及其相关文档的完整集合。其中,程序是按事先设计的功能和性能要求执行的指令序列;数据是使程序能正常操纵信息的数据结构;文档是与程序开发、维护和使用有关的图文材料。
如今,软件已成为信息化的核心,国民经济、国防建设、社会发展及人民生活都已离不开软件。软件产业是增长最快的产业,是高投入、高产出、无污染、低能耗的绿色产业。计算机软件已经成为一种驱动力,是进行商业决策的引擎,是现代科学研究和工程问题寻求解答的基础,也是鉴别现代产品和服务的关键因素。它被嵌入在各种类型的系统中,如交通、医疗、电信、军事、工业生产过程、娱乐、办公等。软件在现代社会中是必不可少的。进入2l世纪以后,软件已成为从基础教育到基因工程的所有领域取得新进展的驱动器。
软件的特点
软件具有以下8个特点。
(1)软件是一种逻辑实体,而不是具体的物理实体,它具有抽象性。软件与计算机硬件,或是其他工程对象有着明显的区别。人们可以把它记录在介质上,但却无法看到软件的形态,必须通过观察、分析、思考、判断,去了解它的功能、性能及其他特性。
(2)软件的生产与硬件不同,在它的开发过程中没有明显的制造过程。秘奥服装店管理软件等是通过人们的智力活动,把知识与技术转化而形成的一种产品。
(3)在软件的运行和使用期问,没有像硬件那样的机械磨损、老化问题。但是软件的维护比硬件的维护要复杂得多,与硬件的维修有着本质的差别。任何机械、电子设备在运行和使用中,其失效率大都遵循如图1.1(a)所示的u形曲线(即浴盆曲线)。而软件的情况与此不同,因为它不存在磨损和老化问题。然而它存在退化问题,必须要经过多次修改(维护),如图1.1(b)所示。
(4)软件的开发和运行常受到计算机系统的限制,对计算机系统有着不同程度的依赖性。
(5)软件的开发至今尚未完全摆脱手工艺的开发方式。
(6)软件本身是复杂的。包括实际问题的复杂性和程序逻辑结构的复杂性。
(7)软件成本是昂贵的。
(8)相当多的软件工作涉及社会因素。
软件的分类
对不同类型的工程对象进行开发和维护有着不同的要求和处理方法,因此需要对软件的类型进行必要的划分。但是,目前还找不到一个统一的严格分类标准,下面从不同的方面对软件进行分类。
1.按照软件功能划分
(1)系统软件。系统软件属于计算机系统中最靠近硬件的一层,其他软件一般都通过系统软件发挥作用,它与具体的应用领域无关,如操作系统、编译程序、设备驱动程序等。
(2)支撑软件。支撑软件是协助用户开发软件的工具性软件,其中包括帮助程序人员开发软件产品的工具,也包括帮助管理人员控制开发进程的工具,如数据库管理系统、网络软件、软件开发环境等。
(3)应用软件。应用软件是在特定领域内开发,为特定目的服务的一类软件,如工程与科学计算软件、服装店管理软件/库存管理软件、、、CAD/CAM软件、CAI软件、信息管理系统等。
2.按照软件工作方式划分
(1)实时处理软件。指在事件或数据产生时,立即予以处理,并及时反馈信号,控制需要监测和控制的过程的软件。
(2)分时软件。它允许多个联机用户同时使用计算机。系统把处理机时问轮流分配给各联机用户,使各用户都感到只有自己在使用计算机的软件。
(3)交互式软件。它是能实现人机通信的软件。这类软件接收用户给出的信息,但在时间上没有严格的限定。这种工作方式给予用户很大的灵活性。
(4)批处理软件。批处理软件是把一组输入作业或一批数据以成批处理的方式一次运行,按顺序逐个处理完的软件。
3.按照软件服务对象的范围划分
(1)项目软件。由用户委托开发的软件。
(2)产品软件。由软件开发机构开发,提供给市场的软件。
4.按使用的频度进行划分
(1)一次使用软件。
(2)频繁使用软件。
5.按软件失效的影响进行划分
(1)高可靠性软件。
(2)一般可靠性软件。
软件危机
软件危机的出现
从20世纪60年代中期以后,随着计算机应用的日益广泛,软件数量急剧膨胀。但是,在程序运行时发现的错误需要设法改正;用户(或用户)有了新的需求时必须相应地修改程序;硬件或操作系统更新时,通常也需要修改程序以适应新的环境。这样就导致了越来越多的软件项目不能满足用户的要求,越来越多的软件项目超出预算和时间安排,以令人吃惊的比例耗费资源。更严重的是,许多程序的个体化特性使得它们最终成为不可维护的。这样就开始出现了软件危机。
软件危机是指在计算机软件的开发和维护过程中所遇到的一系列严重问题。这些问题绝不仅仅是不能正常运行的软件才具有的,实际上,几乎所有软件都不同程度地存在这些问题。软件危机主要包含下述两方面的问题:如何开发软件,以满足人们对软件H益增长的需求;如何维护数量不断膨胀的已有软件。
具体地说,软件危机主要有以下一些典型表现。
(1)对软件开发成本和进度的估计常常很不准确。实际成本比估计成本有可能高出一个数量级,实际进度比预期进度拖延几个月甚至几年的现象并不罕见。这种现象降低了软件开发组织的信誉;为了赶进度和节约成本又往往损害了软件产品的质量,从而不可避免地会引起用户的不满。
(2)用户对“已完成的”软件系统不满意的现象经常发生。软件开发人员常常在对用户要求只有模糊的了解,甚至对所要解决的问题还没有确切认识的情况下,就匆忙着手编写程序。软件开发人员和用户之间的信息交流往往很不充分,“闭门造车”必然导致最终的产品不符合用户的实际需要。
(3)软件产品的质量往往没有保证。软件质量保证技术(审查、复审和测试)还没有坚持不懈地应用到软件开发的全过程中,这些都导致软件产品发生质量问题。
(4)软件常常是不可维护的。很多程序中的错误是非常难以改正的,实际上不可能使这些程序适应新的硬件环境,也不能根据用户的需要在原有程序中增加一些新的功能。“可重用的软件”还是一个没有完全做到的、正在努力追求的目标,人们仍然在重复开发类似的或基本类似的软件。
(5)软件通常没有适当的文档资料。计算机软件不仅仅是程序,还应该有一整套文档资料。缺乏必要的文档资料或者文档资料不合格,必然给软件开发和维护带来许多严重的困难和问题。
(6)软件成本在计算机系统总成本中所占的比例逐年上升。由于生产自动化程度不断提高,硬件成本逐年下降,然而软件开发需要大量人力,软件成本随着软件规模和数量的不断扩大而持续上升。
(7)软件开发生产率提高的速度,远远跟不上计算机应用迅速普及深入的趋势。软件产品“供不应求”的现象使人类不能充分利用现代计算机硬件提供的巨大潜力。
以上列举的仅仅是服装店管理软件等软件危机的一些明显的表现,与软件开发的维护有关的问题远远不止这些。
产生软件危机的原因
软件危机的出现,使得人们去寻找产生危机的内在原因,其原因可归纳为两方面:一方面与软件本身的特点有关;另一方面和软件开发与维护的方法不正确有关。
具体地说,软件危机的产生主要有以下一些原因。
(1)软件不同于硬件,它是计算机系统中的逻辑部件而不是物理部件。管理和控制软件开发过程相当困难。在运行过程中发现的错误,很可能是一个在开发时期引入的,在测试阶段没能检测出来的故障。因此,软件维护通常意味着改正或修改原来的设计,这就在客观上使得软件较难维护。
(2)软件规模大,程序的复杂性将随着程序规模的增加而呈指数上升。如何保证每个人完成的工作合在一起确实能构成一个高质量的大型软件系统,更是一个极端复杂困难的问题,其中不仅涉及许多技术问题,诸如分析方法、设计方法、形式说明方法、版本控制等,更重要的是必须有严格且科学的管理。
(3)与软件开发和维护有关的许多错误认识和做法的形成,可以归因于在计算机系统发展的早期软件开发的个体化特点。这些错误认识和做法主要表现为忽视软件需求分析的重要性,认为软件开发就是写程序并设法使之运行,轻视软件维护等。事实上,对用户要求没有完整准确的认识就匆忙着手编写程序是许多软件开发工程失败的主要原因之一。
(4)软件的生命周期:一个软件从定义、开发、使用和维护,直到最终被废弃,要经历一个漫长的周期。通常把软件经历的这个漫长的时期称为生命周期,主要包括问题定义、可行性研究、需求分析、软件设计(总体设计和详细设计)、编写程序(软件开发全部工作量的10%~20%)和测试(软件开发全部工作量的40%~50%)等阶段。在生命周期的每个阶段都要得出最终产品的一个或几个组成部分。在软件开发的不同阶段进行修改需要付出的代价是有很大差异的,在早期出现需求变动,涉及的面较少,因而代价也比较低;而在开发的中期软件配置的许多成分已经完成,引入一个变动要对所有已完成的配置成分都做相应的修改,不仅工作量大,而且逻辑上也更复杂,因此付出的代价剧增;在软件“已经完成”时再引入变动,则需要付出更高的代价。
(5)软件维护。在软件开发的不同阶段进行修改需要付出的代价是有很大差异的,根据美国一些软件公司的统计资料,在后期引人一个变动比在早期引入相同变动所需付出的代价高2~3个数量级。因此,轻视维护是一个最大的错误。许多软件产品的使用寿命长达10年甚至20年,在这样漫长的时期中不仅必须改正使用过程中发现的每一个潜在的错误,而且当环境变化时(例如硬件或系统软件更新换代)还必须相应地修改软件以适应新的环境,特别是必须经常改进或扩充原来的软件以满足用户不断变化的需要。所有这些改动都属于维护工作,而且是在软件已经完成之后进行的,因此维护是艰巨复杂的工作,需要花费很大代价。统计数据表明,实际上用于软件维护的费用占软件总费用的55%~70%。软件工程学的一个重要目标就是提高软件的可维护性,减少软件维护的代价。
消除软件危机的途径
消除软件危机有以下三个途径。
(1)组织管理:软件开发不是某种个体劳动的神秘技巧,而应该是一种组织良好、管理严密、各类人员协同配合、共同完成的工程项目。必须充分吸取和借鉴人类长期以来从事各种工程项目所积累的行之有效的原理、概念、技术和方法,特别要吸取几十年来人类从事计算机硬件研究和开发的经验教训。
(2)方法:应该推广使用在实践中总结出来的开发软件的成功的技术和方法,并且研究探索更好更有效的技术和方法,尽快消除在计算机系统早期发展阶段形成的一些错误概念和做法。
(3)工具:应该开发和使用更好的软件工具。在软件开发的每个阶段都有许多烦琐的工作需要做,在适当的软件工具辅助下,开发人员可以把这类工作做得既快又好。如果把各个阶段使用的软件工具有机地集合成一个整体,支持软件开发的全过程,则可构成一个良好的软件工程支撑环境。
为了解决软件危机,组织管理措施、方法和工具三者缺一不可。软件工程正是从管理和技术两方面研究如何更好地开发和维护计算机软件的一门新兴学科。
软件工程
软件工程的定义
软件工程(SoftwareEngineering)是在为处理20世纪60年代末所出现的“软件危机”的过程中逐渐形成与发展的。从1968年北大西洋公约的软件可靠性会议(NATO)上,首次提出“软件工程”的概念,提出了在软件生产中采用T程化的方法,以及一系列科学的、现代化的方法技术来开发软件。
软件工程是一门指导计算机软件系统开发和维护的工程学科,是一门新兴的边缘学科,主要研究如何应用软件开发的科学理论和工程技术来指导大型软件系统的开发,涉及计算机科学、工程科学、管理科学、数学等领域。它借鉴传统工程的原则、方法,以提高质量、降低成本为目的。
软件工程一直以来都缺乏一个统一的定义,很多学者、组织机构都分别给出了自己的定义。Boehm指出软件工程就是运用现代科学技术知识来设计并构造计算机程序及为开发、运行和维护这些程序所必需的相关文件资料。IEEE在软件工程术语汇编中将软件工程定义为:将系统化的、严格约束的、可量化的方法应用于软件的开发、运行和维护,即将工程化应用于软件。FritzBauer在NATo会议上给出的定义是建立并使用完善的工程化原则,以经济的手段获得能在实际机器上有效运行的可靠软件的一系列方法。《计算机科学技术百科全书》中对软件工程的定义为:软件_r程是应用计算机科学、数学及管理科学等原理,开发软件的工程。软件工程借鉴传统丁程的原则、方法,以提高质量、降低成本。其中,计算机科学、数学用于构建模型与算法,工程科学用于制定规范、设计范型(Paradigm)、评估成本及确定权衡,管理科学用于计划、资源、质量、成本等的管理。
目前比较认可的一种定义认为:软件工程是研究和应用如何以系统性的、规范化的、可定量的过程化方法去开发和维护软件,以及如何把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来。
虽然人们对软件工程的定义不尽相同,但是,人们普遍认为软件工程具有下述的本质特性。
(1)软件工程关注于大型程序的构造。通常把一个人在较短时问内写出的程序称为小型程序,而把多人合作用时半年以上才写出的程序称为大型程序。现在的软件开发项目通常构造出包含若干个相关程序的“系统”。
(2)软件工程的中心课题是控制复杂性。软件所解决的问题十分复杂,所以通常把问题分解成若干个可以理解的小部分,而且各部分之间保持简单的通信关系。用这种方法虽然不能降低问题的整体复杂性,但是却可使它变成可以管理的。
(3)软件经常变化。为了使软件不被很快淘汰,必须让其随着所模拟的现实世界一起变化。因此,在软件系统交付使用后仍然需要耗费成本,而且在开发过程中必须考虑软件将来可能的变化。
(4)开发软件的效率非常重要。随着社会的进步,社会对新应用系统的需求越来越大,超过了人力资源所能提供的限度,软件供不应求的现象日益严重。因此,提高软件开发的效率非常重要。
(5)开发团队和谐地合作是软件开发的关键。软件处理的问题十分庞大,必须多人协同工作才能解决这类问题。因此,只有开发团队同心协力、和谐地合作才能开发出优质的软件。
(6)软件必须有效地支持它的用户。开发软件的目的是支持用户的工作,所以一个软件是否能够满足用户的要求是检验软件合格与否的标准。
(7)在软件工程领域中是由一种文化背景的人替另一文化背景的人创造产品。创造产品这个特性与前两个特性紧密相关。缺乏应用领域的相关知识,是软件开发项目出现问题的常见原因,软件工程师往往缺乏应用领域的实际知识以及该领域的文化知识。
软件工程的基本原理
自从1968年提出“软件工程”这一术语以来,研究软件工程的专家学者们陆续提出了一百多条关于软件工程的准则或信条。美国著名的软件工程专家Boehm综合这些专家的意见,并总结了TRw公司多年开发软件的经验,于1983年提出了软件工程的7条基本原理。
Boehm认为,这7条原理是确保软件产品质量和开发效率的原理的最小集合。它们是相互独立的,是缺一不可的最小集合;同时,它们又是相当完备的。人们当然不能用数学方法严格证明它们是一个完备的集合,但是可以证明,在此之前已经提出的一百多条软件工程准则都可以由这7条原理的任意组合蕴涵或派生。
下面简要介绍软件工程的7条原理:
原理l用分阶段的生命周期计划严格管理
这一条是吸取前人的教训而提出来的。统计表明,50%以上的失败项目是由于计划不周而造成的。在软件开发与维护的漫长生命周期中,需要完成许多性质各异的工作。这条原理意味着,应该把软件生命周期分成若干阶段,并相应制定出切实可行的计划,然后严格按照计划对软件的开发和维护进行管理。Boehm认为,在整个软件生命周期中应指定并严格执行6类计划:项目概要计划、里程碑计划、项目控制计划、产品控铷计划、验证计划、运行维护计划。
原理2坚持进行阶段评审
统计结果显示:大部分错误是在编码之前造成的,大约占63%,错误发现得越晚,改正它要付出的代价就越大,要差2~3个数量级。因此,软件的质量保证_I作不能等到编码结束之后再进行,应坚持进行严格的阶段评审,以便尽早发现错误。
原理3实行严格的产品控制
开发人员最难处理的事情之一就是需求变更。但是在实际项目开发过程中,需求的改动往往是不可避免的。这就要求人们要采用科学的产品控制技术来满足这种要求。通常要采用变动控制,又叫基准配置管理。当需求变动时,其他各个阶段的文档或代码随之做相应变动,以保证软件的一致性。
原理4采纳现代程序设计技术
从20世纪六七十年代的结构化软件开发技术,到最近的面向对象技术,从第一、第二代语言,到第四代语言,人们已经充分认识到:采用先进的技术既可以提高软件开发的效率,又可以减少软件维护的成本。
原理5结果应该能清楚地审查
软件是一种看不见、摸不着的逻辑产品。软件开发小组的工作进展情况可见性差,难以评价和管理。为了有效管理,应根据软件开发的总目标及完成期限,尽量明确地规定开发小组的责任和产品标准,从而使所得到的标准能够清楚地审查。
原理6开发小组的人员应少而精
开发人员的素质和数量是影响软件质量和开发效率的重要因素,应该少而精。这一条基于两点原因:高素质开发人员的效率比低素质开发人员的效率要高几倍到几十倍,开发工作中犯的错误也要少得多;当开发小组为N人时,可能的通信信道为N(N一1)/z,可见随着人数N的增大,通信开销将急剧增大。
原理7承认不断改进软件工程实践的必要性
遵从前面6条基本原理,就能够较好地实现软件的工程化生产。但是,它们只是对现有经验的总结和归纳,并不能保证赶上技术不断发展的步伐。因此,Boehm提出应把承认不断改进软件工程实践的必要性作为软件工程的第7条原理。根据这条原理,不仅要积极采纳新的软件开发技术,还要注意不断总结经验,收集进度和消耗等数据,进行出错类型和问题报告统计。这些数据既可以用来评估新的软件技术的效果,也可以用来指明必须着重注意的问题和应该优先进行研究的工具和技术。
软件工程的框架
软件工程的框架可概括为软件工程目标、软件工程过程和软件工程原则。
(1)软件工程目标指生产具有正确性、可用性以及代价合宜的产品。正确性指软件产品达到预期功能的程度。可用性指软件基本结构、实现及文档为用户可用的程度。代价合宜是指软件开发、运行的整个代价开销满足用户要求的程度。这些目标的实现不论在理论上还是在实践中均存在很多待解决的问题,它们形成了对过程、过程模型及工程方法选取的约束。
(2)软件工程过程指生产一个最终能满足需求且达到工程目标的软件产品所需要的步骤。软件工程过程主要包括开发过程、运作过程、维护过程。它们覆盖了需求、设计、实现、确认以及维护等活动。需求活动包括问题分析和需求分析。问题分析获取需求定义,又称软件需求规约。需求分析生成功能规约。设计活动一般包括概要设计和详细设计。概要设计建立整个软件系统结构,包括子系统、模块以及相关层次的说明、每一模块的接口定义。
详细设计产生程序员可用的模块说明,包括每一模块中数据结构说明及加工描述。实现活动把设计结果转换为可执行的程序代码。确认活动贯穿于整个开发过程,实现完成后的确认,保证最终产品满足用户的要求。维护活动包括使用过程中的扩充、修改与完善。伴随以上过程,还有管理过程、支持过程、培训过程等。
(3)软件工程的原则指围绕工程设计、工程支持以及工程管理在软件开发过程中必须遵循的原则。
软件工程方法学
通常把在软件生命周期全过程中使用的一整套技术方法的集合称为方法学,也称为范型(Paradigm)。在软件工程领域中,这两个术语的含义基本相同。
软件工程方法学包含三个要素:方法、工具和过程。其中,方法是完成软件开发的各项任务的技术方法;工具是为运用方法而提供的自动的或半自动的软件工程支撑环境;过程是为了获得高质量的软件所需要完成的一系列任务的框架,它规定了完成各项任务的工作步骤。
大的软件公司和研究机构一直在研究软件工程方法学,而且也提出了很多实际的软件开发方法。下面简单介绍几种使用得最广泛的软件工程方法学。
1.结构化方法学
结构化方法学也称为传统方法学,它采用结构化技术(结构化分析、结构化设计和结构化实现)来完成软件开发的各项任务,并使用适当的软件工具或软件工程环境来支持结构化技术的运用。这种方法学把软件生命周期的全过程依次划分为若干个阶段,然后顺序地完成每个阶段的任务。采用这种方法学开发软件的时候,从对问题的抽象逻辑分析开始,一个阶段一个阶段地进行开发。前一个阶段任务的完成是开始进行后一个阶段_T作的前提和基础,而后一阶段任务的完成通常是使前一阶段提出的解法更进一步具体化,加进了更多的实现细节。每一个阶段的开始和结束都有严格标准,对于任何两个相邻的阶段而言,前一阶段的结束标准就是后一阶段的开始标准。在每一个阶段结束之前都必须进行正式严格的技术审查和管理复审,从技术和管理两方面对这个阶段的开发成果进行检查,通过之后这个阶段才算结束;如果没通过检查,则必须进行必要的返工,而且返工后还要再经过审查。审查的一条主要标准就是每个阶段都应该交出“最新式的”(即和所开发的软件完全一致的)高质量的文档资料,从而保证在软件开发工程结束时有一个完整准确的软件配置交付使用。文档是通信的工具,它们清楚准确地说明了到这个时候为止,关于该项工程已经知道了什么,同时奠定了下一步工作的基础。此外,文档也起到备忘录的作用,如果文档不完整,那么一定是某些工作忘记做了,在进人生命周期的下一个阶段之前,必须补足这些遗漏的细节。
结构化方法学中的程序设计采用的是结构化程序设计(StructureProgramming,SP),是20世纪80年代主要的程序设计方法,其核心是模块化。SP方法主张使用顺序、选择、循环三种基本结构来嵌套连接成具有复杂层次的“结构化程序”。SP的要点是“自顶而下,逐步求精”的设计思想,“独立功能,单出、入口”的模块仅用三种(顺序、分支、循环)基本控制结构的编码原则。自顶向下的出发点是从问题的总体目标开始,抽象底层的细节,先专心构造高层的结构,然后再一层一层地分解和细化。这种方法使复杂的设计过程变得简单明了,过程的结果也容易做到正确可靠。
目前,结构化方法学仍然是人们在开发软件时使用得十分广泛的软件T程方法学。这种方法学历史悠久,为广大软件工程师所熟悉,而且在开发某些类型的软件时也比较有效,因此,在相当长一段时期内这种方法学还会有生命力。
2.面向对象方法学
面向对象方法学的出发点和基本原则,是尽量模拟人类习惯的思维方式,使开发软件的方法与过程尽可能接近人类认识世界解决问题的方法与过程,从而使描述问题的问题空间(也称为问题域)与实现解法的解空间(也称为求解域)在结构上尽可能一致。
面向对象的基本思想与结构化设计思想完全不同,面向对象的方法学认为世界由各种对象组成,任何事物都是对象,是某个对象的实例,复杂的对象可由较简单的对象以某种方式组成。对象是数据及对这些数据施加的操作组合在一起所构成的独立实体的总称;类是一组具有相同数据结构和相同操作的对象的描述。面向对象的基本机制是方法和消息。方法是对象所能执行的操作,它是类中所定义的函数,描述对象执行某个操作的算法,每一个对象类都定义了一组方法;消息是要求某个对象执行类中某个操作的规格说明。
面向对象方法学具有下述4个要点:
①把对象(Object)作为融合了数据及在数据上的操作行为的统一的软件构件;
②把所有对象都划分成类(Class);
③按照父类(或称为基类)与子类(或称为派生类)的关系,把若干个相关类组成一个层次结构的系统(也称为类等级);
④对象彼此间仅能通过发送消息互相联系。
随着00P(面向对象编程)向OOD(面向对象设计)和OoA(面向对象分析)的发展,最终形成了面向对象的软件开发方法0MT(ObjectModelingTechnique)。这是一种自底向上和自顶向下相结合的方法,而且它以对象建模为基础,从而不仅考虑了输入输出数据结构,实际上也包含所有对象的数据结构。不仅如此,面向对象技术在需求分析、可维护性和可靠性这三个软件开发的关键环节和质量指标上有了实质性的突破,基本解决了在这些方面存在的严重问题。当前软件行业关于面向对象建模的标准是统一建模语言UML(UnifiedModelingLanguage)。
3.后面向对象方法学
经过多年的实践摸索,人们逐渐发现面向对象方法也有其不足,如许多软件系统不完全都能按系统的功能来划分构建,仍然有许多重要的需求和设计决策,无论是采用面向对象语言还是过程型语言,都难以用清晰的、模块化的代码实现。因此,人们在面向对象的基础上发展了更多的新技术,以使面向对象技术能够更好地解决软件开发中的问题。这些建立在面向对象的基础上,并对面向对象做出扩展的新技术被广泛应用的时期,被称为“后面向对象时代”。在后面向对象时代,有许多新型的程序设计思想值得关注。
1)敏捷开发方法
敏捷方法(AgileMethodology)也称做轻量级开发方法。该方法在无过程和过于烦琐的过程中达到了一种平衡,使得能以不多的步骤过程获取较满意的结果。敏捷型方法是“面向人”的而非“面向过程”的,敏捷型方法认为没有任何过程能代替开发组的技能,过程起的作用是对开发组的工作提供支持。
2)面向方面程序设计
面向方面程序设计(Aspect—OrientedProgramming,AOP)方法最早是由施乐(Xerox)公司在美国加州硅谷PaloAlto研究中心(PARC)的首席科学家、加拿大大不列颠哥伦比亚大学教授GregorKicgales等在1997年的欧洲面向对象编程大会(ECOOP97)上提出的。
所谓的Aspect,就是AOP提供的一种程序设计单元,它可以将上面提到的那些在传统程序设计方法学中难以清晰地封装并模块化实现的设计决策,封装实现为独立的模块。Aspect是AOP的核心,它超越了子程序和继承,是AOP将贯穿特性局部化和模块化的实现机制。
通过将贯穿特性集中到Aspect中,AOP就取得一种单一的结构化行为,该行为在传统程序中分布于整个代码中,这样就使Aspect代码和系统目标都易于理解。
3)面向Agent程序设计
随着软件系统服务能力要求的不断提高,在系统中引入智能因素已经成为必然。Agent作为人工智能研究重要的分支,引起了科学、工程、技术界的高度重视。在计算机科学主流中,Agent的概念作为一个自包含、并行执行的软件过程能够封装一些状态并通过传递消息与其他Agent进行通信,被看做是面向对象程序设计的一个自然发展。
4)其他后面向对象程序设计
除了上述两种主流的后面向对象程序设计方法外,还出现了许多值得关注的新的程序设计方法,如泛型程序设计、面向构件的程序设计等。
泛型程序设计(GenericProgramming,GP)是一种范型(Paradigm),它致力于将各种类型按照一小组功能性的需求加以抽象,然后以这些需求为条件实现算法。由于算法在其操作的数据类型上定义了一个严格的窄接口,同一个算法便可以应用于各种类型之上。
在面向构件程序设计中构件就是一组业务功能的规格,面向构件针对的是业务规格,不需要源代码,可执行代码或者中间层的编译代码,在这个层面上可以做到代码的集成、封装、多态,做到AOP,这才是面向构件的精髓。面向构件技术还包括另外一个重要思想,就是程序在动态运行时构件的自动装载。
软件的生命周期
软件生命周期及其各个阶段
软件工程强调使用生存周期方法学和各种结构分析及结构设计技术。它们是在20世纪70年代为了应对应用软件日益增长的复杂程度、漫长的开发周期以及用户对软件产品经常不满意的状况而发展起来的。
一般说来,软件生存周期由软件定义、软件开发和软件维护三个时期组成,每个时期又进一步划分成若干个阶段。
软件定义时期的任务是确定软件开发工程必须完成的总目标;确定工程的可行性,导出实现工程目标应该采用的策略及系统必须完成的功能;估计完成该项工程需要的资源和成本,并且制定工程进度表。这个时期的工作通常又称为系统分析,由系统分析员负责完成。软件定义时期通常进一步划分成三个阶段,即问题定义、可行性研究和需求分析。
开发时期具体设计和实现在软件定义时期定义的软件,它通常由下述4个阶段组成:总体设计、详细设计、编码和单元测试、综合测试。
维护时期的主要任务是使软件持久地满足用户的需要。具体地说,当软件在使用过程中发现错误时应该加以改正;当环境改变时应该修改软件以适应新的环境;当用户有新要求时应该及时改进软件满足用户的新需要。通常对维护时期不再进一步划分阶段,但是每一次维护活动本质上都是一次压缩和简化了的定义和开发过程。
下面简要介绍软件生存周期每个阶段的基本任务和结束标准。
1.问题定义
问题定义阶段必须回答的关键问题是“要解决的问题是什么?”如果不知道问题是什么就试图解决这个问题,显然是盲目的,只会白白浪费时间和金钱,最终得出的结果很可能是毫无意义的。尽管确切地定义问题的必要性是十分明显的,但是在实践中它却可能是最容易被忽视的一个步骤。
通过问题定义阶段的工作,系统分析员应该提出关于问题性质、工程目标和规模的书面报告。通过对系统的实际用户和使用部门负责人的访问调查,分析员扼要地写出他对问题的理解,并在用户和使用部门负责人的会议上认真讨论这份书面报告,澄清含糊不清的地方,改正理解不正确的地方,最后得出一份双方都满意的文档。
2.可行性研究
这个阶段要回答的关键问题是“对于上一个阶段所确定的问题有行得通的解决办法吗?”为了回答这个问题,系统分析员需要进行一次大的压缩和简化过的系统分析和设计的过程,即在较抽象的高层次上进行的分析和设计的过程。
可行性研究的时间应该比较短,这个阶段的任务不是具体解决问题,而是研究问题的范围,探索这个问题是否值得去解,是否有可行的解决办法。
在问题定义阶段提出的对工程目标和规模的报告通常比较含糊。可行性研究阶段应该导出系统的高层逻辑模型(通常用数据流图表示),并且在此基础上更准确、更具体地确定工程规模和目标。然后分析员更准确地估计系统的成本和效益,对建议的系统进行仔细的成本/效益分析是这个阶段的主要任务之一。
可行性研究的结果是使用部门负责人做出是否继续进行这项工程的决定的重要依据。可行性研究以后的那些阶段将需要投入更多的人力物力。及时中止不值得投资的工程项目,可以避免更大的浪费。
3.需求分析
这个阶段的任务仍然不是具体地解决问题,而是准确地确定“为了解决这个问题,目标系统必须做什么”,主要是确定目标系统必须具备哪些功能。
用户了解他们所面对的问题,知道必须做什么,但是通常不能完整准确地表达出他们的要求,更不知道怎样利用计算机解决他们的问题;软件开发人员知道怎样使用软件实现人们的要求,但是对特定用户的具体要求并不完全清楚。因此,系统分析员在需求分析阶段必须和用户密切配合,充分交流,以得出经过用户确认的系统逻辑模型。通常用数据流图、数据字典和简要的算法描述表示系统的逻辑模型。
在需求分析阶段确定的系统逻辑模型是以后设计和实现目标系统的基础,因此必须准确完整地体现用户的要求。系统分析员通常都是计算机软件专家,技术专家一般都喜欢很快着手进行具体设计,然而,一旦分析员开始谈论程序设计的细节,就会脱离用户,使他们不能继续提出他们的要求和建议。软件工程在使用的结构分析设计的方法时为每个阶段都规定了特定的结束标准,需求分析阶段必须提供完整准确的系统逻辑模型,经过用户确认之后才能进入下一个阶段,这就可以有效地防止和克服急于着手进行具体设计的倾向。
4.总体设计
这个阶段必须回答的关键问题是“概括地说,应该如何解决这个问题?”
首先,应该考虑几种可能的解决方案。例如,目标系统的一些主要功能是用计算机自动完成还是用人工完成;如果使用计算机,那么是使用批处理方式还是人机交互方式;信息存储是用传统的文件系统还是数据库等。通常至少应该考虑下述几类可能的方案:低成本的解决方案、中等成本的解决方案和高成本的解决方案。
系统分析员应该使用系统流程图或其他工具描述每种可能的系统,估计每种方案的成本和效益,还应该在充分权衡各种方案的利弊的基础上,推荐一个较好的系统(最佳方案),并且制定实现所推荐的系统的详细计划。如果用户接受分析员推荐的系统,则可以着手完成本阶段的另一项主要工作。
上面的工作确定了解决问题的策略以及目标系统需要哪些程序,但是,怎样设计这些程序呢?结构设计的一条基本原理就是程序应该模块化,也就是一个大程序应该由许多规模适中的模块按合理的层次结构组织而成。总体设计阶段的第二项主要任务就是设计软件的结构,也就是确定程序由哪些模块组成以及模块间的关系。通常用层次图或结构图描绘软件的结构。
5,详细设计
总体设计阶段以比较抽象概括的方式提出了解决问题的办法。详细设计阶段的任务就是把解法具体化,也就是回答下面这个关键问题:“应该怎样具体地实现这个系统呢?”这个阶段的任务还不是编写程序,而是设计出程序的详细规格说明。这种规格说明的作用非常类似于其他工程领域中工程师经常使用的工程蓝图,它们应该包含必要的细节,程序员可以根据它们写出实际的程序代码。
通常用HIPO图(层次图加输入/处理/输出图)或PDL(过程描述语言)描述详细设计的结果。
6.编码和单元测试
这个阶段的关键任务是写出正确的、容易理解、容易维护的程序模块。程序员应该根据目标系统的性质和实际环境,选取一种适当的高级程序设计语言(必要时用汇编语言),把详细设计的结果翻译成用选定的语言书写的程序,并且仔细测试编写出的每一个模块。
7.综合测试
这个阶段的关键任务是通过各种类型的测试(及相应的调试)使软件达到预定的要求。
最基本的测试是集成测试和验收测试。所谓集成测试是根据设计的软件结构,把经过单元测试检验的模块按某种选定的策略装配起来,在装配过程中对程序进行必要的测试。
所谓验收测试则是按照规格说明书的规定(通常在需求分析阶段确定),由用户(或在用户积极参加下)对目标系统进行验收。
必要时还可以再通过现场测试或平行运行等方法对目标系统进一步测试检验。为了使用户能够积极参加验收测试,并且在系统投入生产性运行以后能够正确有效地使用这个系统,通常需要以正式的或非正式的方式对用户进行培训。
通过对软件测试结果的分析可以预测软件的可靠性;反之,根据对软件可靠性的要求也可以决定测试和调试过程什么时候可以结束。
测试计划、详细测试方案以及实际测试结果应该以文档形式保存下来,作为软件配置的一个组成部分。
8.软件维护
维护阶段的关键任务是通过各种必要的维护活动使系统持久地满足用户的需要。通常有4类维护活动:改正性维护,也就是诊断和改正在使用过程中发现的软件错误;适应性维护,即修改软件以适应环境的变化;完善性维护,即根据用户的要求改进或扩充软件使它更完善;预防性维护,即修改软件为将来的维护活动预先做准备。
虽然没有把维护阶段进一步划分成更小的阶段,但是实际上每一项维护活动都应该经过提出维护要求(或报告问题),分析维护要求,提出维护方案,审批维护方案,确定维护计划,修改软件设计,修改程序,测试程序,复查验收等一系列步骤,因此实质上是经历了一次压缩和简化了的软件定义和开发的全过程。
软件生命周期的各阶段有不同的划分。软件规模、种类、开发模式、开发环境和开发方法都影响软件生存期的划分。在划分软件生存期的阶段时,应遵循以下规则:各阶段的任务应尽可能相对独立,同一阶段各项任务的性质应尽可能相同,从而降低每个阶段任务的复杂程度,简化不同阶段之间的联系,有利于软件项目开发的组织和管理。
软件生命周期模型
通常使用生命周期模型简洁地描述软件过程。生命周期模型规定了把生命周期划分成哪些阶段及各个阶段的执行顺序,因此,也称为过程模型。
软件生命周期模型是从软件项目需求定义直至软件经使用后废弃为止,跨越整个生命期的系统开发、运作和维护所实施的全部过程、活动和任务的结构框架。
下面介绍几种常见的服装店管理软件等软件生命周期模型。
1.瀑布模型
在20世纪80年代之前,瀑布模型一直是唯一被广泛采用的生命周期模型,现在它仍然是软件工程中应用得最广泛的过程模型。传统软件工程方法学的软件过程,基本上可以用瀑布模型来描述。
如图1.2所示为传统的瀑布模型。按照传统的瀑布模型开发软件,有下述几个特点。
1)阶段间具有顺序性和依赖性
这个特点有两重含义:
①必须等前一阶段的工作完成之后,才能开始后一阶段的工作;
②前一阶段的输出文档就是后一阶段的输入文档。
2)推迟实现的观点
对于规模较大的软件项目来说,往往编码开始得越早最终完成开发工作所需要的时间反而越长。这是因为,前面阶段的工作没做或做得不扎实,过早地考虑进行程序实现,往往导致大量返工,有时甚至发生无法弥补的问题,带来灾难性后果。
3)质量保证的观点
软件工程的基本目标是优质、高产。为了保证所开发的软件的质量,在瀑布模型的每个阶段都应坚持两个重要做法:
①每个阶段都必须完成规定的文档,没有交出合格的文档就是没有完成该阶段的任务。完整、准确、合格的文档不仅是软件开发时期各类人员之间相互通信的媒介,也是运行时期对软件进行维护的重要依据;
②每个阶段结束前都要对所完成的文档进行评审,以便尽早发现问题,改正错误。事实上,越是早期阶段犯下的错误,暴露出来的时间就越晚,排除故障改正错误所需付出的代价也越高。因此,及时审查,是保证软件质量、降低软件成本的重要措施。
传统的瀑布模型过于理想化了,事实上,人们在工作过程中不可能不犯错误。在设计阶段可能发现规格说明文档中的错误,而设计上的缺陷或错误可能在实现过程中显现出来,在综合测试阶段也会发现需求分析、设计或编码阶段的错误。因此,实际的瀑布模型是带“反馈环”的,如图1.3所示(图中实线箭头表示开发过程,虚线箭头表示维护过程)。当在后面阶段发现前面阶段的错误时,需要沿图中左侧的反馈线返回前面的阶段,修正前面阶段的产品之后再回来继续完成后面阶段的任务。
但是,“瀑布模型是由文档驱动的”这个事实也是它的一个主要缺点。由于瀑布模型几乎完全依赖于书面的规格说明,很可能导致最终开发出的软件产品不能真正满足用户的需要。
2.渐增模型
渐增模型也称为增量模型或演化模型,如图1.4所示。软件在该模型中是“逐渐”开发出来的,开发出一部分,向用户展示一部分,可让用户及早看到部分软件,及早发现问题。或者先开发一个“原型”软件,完成部分主要功能,展示给用户并征求意见,然后逐步完善,最终获得满意的软件产品。这个过程是一个迭代的过程。该模型具有较大的灵活性,适合于软件需求不明确,设计方案有一定风险的软件项目。
使用渐增模型开发软件时,把软件产品作为一系列的增量构件来设计、编码、集成和测试。每个构件由多个相互作用的模块构成,并且能够完成特定的功能。把软件产品分解成增量构件时,应该使构件的规模适中,规模过大或过小都不好。最佳分解方法因软件产品特点和开发人员的习惯而异。分解时唯一必须遵守的约束条件是,当把新构件集成到现有软件中时,所形成的产品必须是可测试的。
采用瀑布模型开发软件时,目标都是一次就把一个满足所有需求的产品提交给用户。渐增模型则与之相反,它分批地逐步向用户提交产品,整个软件产品被分解成许多个增量构件,开发人员一个构件接一个构件地向用户提交产品。从第一个构件交付之日起,用户就能做一些有用的工作。显然,能在较短时间内向用户提交可完成部分工作的产品,是渐增模型的一个优点。
渐增模型的另一个优点是,逐步增加产品功能可以使用户有较充裕的时问学习和适应新产晶,从而减少一个全新的软件可能给用户组织带来的冲击。
使用渐增模型的困难是,在把每个新的增量构件集成到现有软件体系结构中时,必须不破坏原来已经开发出的产品。此外,必须把软件的体系结构设计得便于按这种方式进行扩充,向现有产品中加入新构件的过程必须简单、方便,也就是说,软件体系结构必须是开放的。但是,从长远观点看,具有开放结构的软件拥有真正的优势,这样的软件的可维护性明显好于封闭结构的软件。因此,尽管采用渐增模型比采用瀑布模型需要更精心的设计,但在设计阶段多付出的劳动将在维护阶段获得回报。如果一个设计非常灵活而且足够开放,足以支持渐增模型,那么,这样的设计将允许在不破坏产品的情况下进行维护。事实上,使用渐增模型时开发软件和扩充软件功能(完善性维护)并没有本质区别,都是向现有产品中加人新构件的过程。
从某种意义上说,渐增模型本身是自相矛盾的。它一方面要求开发人员把软件看做一个整体,另一方面又要求开发人员把软件看做构件序列,每个构件本质上都独立于另一个构件。除非开发人员有足够的技术能力协调好这一明显的矛盾,否则用渐增模型开发出的产品可能并不令人满意。
3.快速原型模型
所谓快速原型是快速建立起来的可以在计算机上运行的程序,它所能完成的功能往往是最终产品能完成的功能的一个子集。如图1-5所示(图中实线箭头表示开发过程,虚线箭头表示维护过程),快速原型模型的第一步是快速建立一个能反映用户主要需求的原型系统,让用户在计算机上试用它,通过实践来了解目标系统的概貌。通常,用户试用原型系统之后会提出许多修改意见,开发人员按照用户的意见快速地修改原型系统,然后再次请用户试用。一旦用户认为这个原型系统确实能做他们所需要的工作,开发人员便可据此编写规格说明文档,根据这份文档开发出的软件可以满足用户的真实需求。
从图1.5可以看出,快速原型模型是不带反馈环的,这正是这种过程模型的主要优点:软件产品的开发基本上是线性顺序进行的。能做到基本上线性顺序开发的主要原因如下:
(1)原型系统已经通过与用户交互而得到验证,据此产生的规格说明文档正确地描述了用户需求,因此,在开发过程的后续阶段不会因为发现了规格说明文档的错误而进行较大的返工。
(2)开发人员通过建立原型系统已经学到了许多东西(至少知道了“系统不应该做什么,以及怎样不去做不该做的事情”),因此,在设计和编码阶段发生错误的可能性也比较小,这自然减少了在后续阶段需要改正前面阶段所犯错误的可能性。
软件产品一旦交付给用户使用之后,维护便开始了。根据所需完成的维护工作种类的不同,可能需要返回到需求分析、规格说明、设计或编码等不同阶段,如图1.5中虚线箭头所示。
快速原型的本质是“快速”。开发人员应该尽可能快地建造出原型系统,以加速软件开发过程,节约软件开发成本。原型的用途是获知用户的真正需求,一旦需求确定了,原型将被抛弃。因此,原型系统的内部结构并不重要,重要的是,必须迅速地构建原型然后根据用户意见迅速地修改原型。UNIXShell和超文本都是广泛使用的快速原型语言,最近的趋势是,广泛地使用第四代语言(4thGenenationLanguage,4GL)构建快速原型。
4.螺旋模型
对于复杂的大型软件,开发一个原型往往达不到要求。螺旋模型将瀑布模型与渐增模型结合起来,并且加入两种模型均忽略了的风险分析。
所谓“软件风险”,是普遍存在于任何软件开发项目中的实际问题。对于不同的项目,其差别只是风险有大有小而已。在制定软件开发计划时,系统分析员必须回答:项目的需求是什么,需要投入多少资源以及如何安排开发进度等一系列问题。然而,若要他们当即给出准确无误的回答是不容易的,甚至几乎是不可能的。但系统分析员又不可能完全回避这一问题。凭借经验的估计并给出初步的设想便难免带来一定风险。实践表明,项目规模越大,问题越复杂,资源、成本、进度等因素的不确定性越大,承担项目所冒的风险也越大。因此,风险是软件开发不可忽视的潜在不利因素,它可能在不同程度上损害到软件开发过程或软件产品的质量。软件风险控制的目标是在造成危害之前,及时对风险进行识别、分析,采取对策,进而消除或减少风险的损害。
螺旋模型沿着螺线旋转,如图1.6所示,在笛卡儿坐标的4个象限上分别表达了4个方面的活动,即:
(1)制定计划——确定软件目标,选定实施方案,弄清项目开发的限制条件。
(2)风险分析——分析所选方案,考虑如何识别和消除风险。
(3)实施工程——实施软件开发。
(4)用户评估——评价开发工作,提出修正建议。
沿螺线自内向外,每旋转一圈便开发出更为完善的一个新的软件版本。例如,在第一圈,确定了初步的目标、方案和限制条件以后,转入右上象限,对风险进行识别和分析。如果风险分析表明,需求有不确定性,那么在右下的工程象限内,所建的原型会帮助开发人员和用户,考虑其他开发模型,并对需求做进一步修正。用户对工程成果做出评价之后,给出修正建议。在此基础上需再次计划,并进行风险分析。在每一圈螺线上,风险分析的终点做出是否继续下去的判断。假如风险过大,开发者和用户无法承受,项目有可能终止。多数情况下沿螺线的活动会继续下去,自内向外,逐步延伸,最终得到所期望的系统。
螺旋模型有许多优点:对可选方案和约束条件的强调有利于已有软件的重用,也有助于把软件质量作为软件开发的一个重要目标;减少了过多测试(浪费资金)或测试不足(产品故障多)所带来的风险;更重要的是,在螺旋模型中维护只是模型的另一个周期,在维护和开发之间并没有本质区别。
螺旋模型主要适用于内部开发的大规模软件项目。如果进行风险分析的费用接近整个项目的经费预算,则风险分析是不可行的。事实上,项目越大,风险也越大,因此,进行风险分析的必要性也越大。此外,只有内部开发的项目,才能在风险过大时方便地中止项目。
螺旋模型的主要优势在于,它是风险驱动的,但是,这也可能是它的一个弱点。除非软件开发人员具有丰富的风险评估经验和这方面的专门知识,否则将出现真正的风险:当项目实际上正在走向灾难时,开发人员可能还认为一切正常。
5.喷泉模型
喷泉模型对软件复用和生存期中多项开发活动的集成提供了支持,主要支持面向对象的开发方法。“喷泉”一词本身体现了迭代和无间隙特性。系统某个部分常常重复工作多次,相关功能在每次迭代中随之加入演进的系统。所谓无间隙是指在开发活动,即分析、设计和编码之间不存在明显的边界。喷泉模型如图1.7所示。
喷泉模型的特点如下:
(1)喷泉模型各阶段相互重叠,反映了软件过程并行性的特点。
(2)喷泉模型以分析为基础,资源消耗呈塔形,在分析阶段消耗的资源最多。
(3)喷泉模型反映了软件过程迭代的自然特性,从高层返回低层没有资源消耗。
(4)喷泉模型强调增量式开发,它依据分析一部分就设计一部分的原则,不要求一个阶段的彻底完成。整个过程是一个迭代的逐步细化的过程。
(5)喷泉模型是对象驱动的过程,对象是所有活动作用的实体,也是项目管理的基本内容。
(6)喷泉模型在实现时,由于活动不同,可分为对象实现和系统实现,不但反映了系统的开发全过程,而且也反映了对象的开发和复用的过程。
6.变换模型
变换模型是一种基于形式化规格说明语言及程序变换的软件开发模型。它采用形式化的软件开发方法,对形式化的软件规格说明进行一系列自动的或半自动的程序变换,最终映射成为计算机系统能够接受的程序系统。
软件需求确定以后,可用某种形式化的需求规格说明语言(如VDM的META—IV,CSP和Z)描述软件需求规格说明,生成形式化的设计说明。为了确认形式化规格说明与软件需求的一致性,往往以形式化设计说明为基础开发一个软件原型。用户可以从人机界面、系统主要功能、性能等几个方面对原型进行评审,必要时,可以对软件需求、形式化设计说明和原型进行修改,直到原型被确认为止。这时软件开发人员就可以对形式化的规格说明进行一系列的程序变换,直到生成计算机可以接受的目标代码。
多步程序变换过程的一个重要性质是每一步变换对相关的模型描述是“封闭的”。即每一步程序变换的正确性仅与该步变换所依据的规范M,以及对变换后的假设M汁。有关,在此意义上,变换步骤独立于其他变换步骤。这称为变换的独立性。若没有这种独立性,就不能控制错误的蔓延。
变换模型的特点如下:
(1)该模型只适合于软件的形式化开发方法。
(2)需要严格的数学理论(如逻辑、代数等)和形式化技术支持。
(3)需要一整套开发环境(如程序变换工具、定理证明工具等)的支持。
(4)该模型目前还缺乏相应的支持工具,仍处于手工处理方式。
(5)对软件开发人员的知识和方法要求较高。
理论上,一个正确的、满足用户要求的形式化规格说明,经过一系列正确的程序变换后,应当能够生成正确的:计算机系统能够接受的程序代码。但是,目前形式化开发方法在理论、实践和人员培训方面与工程应用还有一定的距离。
7.智能模型
智能模型是基于知识的软件开发模型,它把瀑布模型和专家系统综合在一起。该模型在开发的各个阶段都利用了相应的专家系统来帮助软件人员完成开发工作,使维护能在系统需求说明一级上进行。为此,建立了各个阶段的知识库,将模型、相应领域知识和软件工程知识分别存人数据库,以软件工程知识为基础的生成规则构成的专家系统与包含应用领域知识规则的其他专家系统相结合,构成该应用领域的开发系统。
基于知识的智能模型如图1.9所示。该模型基于瀑布模型,在各阶段都有相应的专家系统支持。
(1)支持需求活动的专家系统用于支持帮助减少需求活动中的二义性的、不精确的、冲突或易变的需求。这需要使用应用领域的知识和应用系统的规则,从而建立应用领域的专家系统以支持需求活动。
(2)支持设计活动的专家系统用于选择支持设计功能的CASE工具和文档。它要用到软件开发的知识。
(3)支持测试活动的专家系统用来支持测试自动化。利用基于知识的系统来选择测试
工具。生成测试用例,跟踪测试过程,分析测试结果。
(4)支持维护活动的专家系统将维护变成新的应用开发过程的重复,运行可利用的基
于知识的系统来进行维护。
基于知识的模型将软件工程知识从特定领域中分离出来,随过程范例存人知识库,在接受软件工程技术的基础上编成专家系统,用来辅助软件的开发。在使用过程中,将软件工程专家系统与其他领域的应用知识的专家系统连接起来,形成特定软件系统,用于开发一个软件产品。
智能模型的优点是:
(1)通过领域的专家系统,可使需求说明更完整、准确和无二义性。
(2)通过软件工程专家系统,在开发过程中成为设计人员的助手。
(3)通过软件工程知识和特定应用领域知识和规则的应用可帮助系统的开发。
智能模型的缺点是:
(1)建立适合于软件设计的专家系统是非常困难的。
(2)建立一个既适合软件工程又适合应用领域的知识库也是非常困难的。
(3)目前的状况是正在软件开发中应用人工智能技术,在CASE工具系统中使用专家系统,用专家系统实现测试自动化,在软件开发的局部阶段已有进展。
软件工程的基本目标
组织实施软件工程项目,从技术和管理上采取了多项措施以后,最终希望项目能够取得成功。所谓软件成功指的是达到以下几个主要的目标:
(1)达到要求的软件功能。
(2)取得较好的软件性能。
(3)开发的软件易于移植。
(4)能按时交付使用。
(5)付出较低的开发成本。
(6)较低的维护费用。
在具体项目的实际开发中,企图让以上几个目标都达到理想的程度往往是非常困难的。况且上述目标很可能是互相冲突的。例如,若降低开发成本,很可能同时也降低了软件的可靠性。另一方面,如果过于追求提高软件的性能,可能造成开发出的软件对硬件有较大的依赖,从而直接影响到软件的可移植性。
图1.10表明了软件工程目标之间存在的相互关系。其中有些目标之间是互补关系,例如,易于维护和高可靠性之间,低开发成本与按时交付之间。还有一些目标是彼此互斥的,例如,低开发成本与软件可靠性之间,提高软件性能与软件可移植性之间,就存在冲突。
这里提到的几个目标很自然地成为判断软件开发方法或管理方法优劣的衡量尺度。如果提出一种新的开发方法,人们关心的是它对满足哪些目标比现有的方法更为有利。实际上,实施软件开发项目就是力图在以上目标的冲突中取得一定程度的平衡。
软件工程的原则
为达到以上软件工程的目标,不仅仅是秘奥服装店管理软件,其它管理软件也一样,在软件开发过程中必须遵循下列软件工程原则。
(1)抽象:抽取事物最基本的特性和行为,忽略非基本的细节。采用分层次抽象,自顶向下、逐层分解的办法控制软件开发过程的复杂性。例如,软件瀑布模型、结构化分析方法、结构化设计方法,以及面向对象建模技术等都体现了抽象的原则。
(2)信息隐蔽:将模块设计成“黑箱”,实现的细节隐藏在模块内部,不让模块的使用者直接访问。这就是信息封装,使用与实现分离的原则。使用者只能通过模块接口访问模块中封装的数据。
(3)模块化:模块是程序中逻辑上相对独立的成分,是独立的编程单位,应有良好的接口定义。如C语言程序中的函数过程,C++语言程序中的类。模块化有助于信息隐蔽和抽象,有助于表示复杂的系统。
(