第1章 软件工程概述
现在是电子信息时代,大街上的年轻人头上戴着耳机听着什么匆匆走过;咖啡厅、地铁、医院、餐厅、学校、排队等候办事的人群中、甚至公交车上,不少人都在低着头用手机上网、看微信或玩游戏;当我们坐在家里玩电脑或上网查资料的时候,当我们到派出所办理户口或身份证的时候,当我们到医院检查身体或看病的时候,当我们到银行办理业务的时候,当我们去车站或机场购票的时候,等等这一切的一切,是依靠什么顺畅运行的呢?答案是软件!软件是什么,它是怎么发展起来的,没有它行不行,软件工程又是什么呢?本章内容将会回答你这些问题。
1.1 软件的分类和演化
软件工程是围绕软件的开发、维护、管理、质量保证等一系列活动而展开的,本节将介绍什么是软件,它是如何分类,又是如何发展的。
1.1.1 软件的起源和分类
1.软件起源
软件一词起源于程序,是20世纪60年代出现的概念,也是一个不断发展的概念,软件的形成和发展与计算学科的发展紧密相关,现在计算学科已经发展为计算机科学与技术以及软件工程两大学科。不同时期对软件的解释也有所不同,这是由于软件的功能、模块、开发方式以及使用方式在不断发生变化,因而对它的解释也在发展变化。
2.软件定义
软件是相对于硬件而言的,以解释性的定义为主。
美国软件工程专家罗杰·普雷斯曼(Roger S.Pressman)(如图1-1所示)将软件解释为当机器执行时能提供所要求功能和性能的程序,能使程序有效处理信息的数据结构以及描述操作和使用程序的文档,简单地说就是软件由程序、数据和文档组成。
电子与电气工程师协会(IEEE)将软件定义为计算机程序、方法、规则、相关文档及在计算机中运行时所需的数据。
英国软件工程专家兰·萨默维尔(Ian Sommerville)(如图1-2所示)认为软件是一个系统,通常由若干程序、用于建立这些程序的配置文件、描述系统结构的系统文档、解释如何使用系统的用户文档以及供用户下载最新产品信息的Web站点组成。
一些学者认为软件由程序及其文档组成,其中,程序是计算机任务的处理对象和处理规则的描述,文档是为了理解程序所需的阐述性资料。
图1-1 罗杰·普雷斯曼
图1-2 兰·萨默维尔
不难理解,软件其实是知识的载体,它包括的内容和范围很广,一般认为执行指令的计算机程序以及与之相关的文档、数据、影视资料、方法、规则、网页及其链接等都可算作软件。
3.软件分类
从软件的起源和定义可以看出,软件具有3层含义:一是个体含义,指计算机系统中的程序、文档和数据;二是整体含义,指在特定计算机系统中所有上述个体含义下的软件的总称;三是学科含义,指在研究、开发、维护以及使用前述含义下的软件所涉及的理论、方法、技术所构成的学科。
软件的种类很多,随着复杂程度的增加,软件的分类也在发展变化,界限越来越不明显,按软件的作用,可分为以下4类。
(1)系统软件
是指由生产厂家配置,服务于其他系统元素的软件。如操作系统、汇编程序、编译程序、数据库管理系统、计算机通信及网络软件等。如果没有这些软件,计算机、网络、设备等很难发挥功能,甚至无法工作。
(2)应用软件
是指在系统软件的基础上,为解决特定领域问题而开发的软件。这类软件很多,如用于电信、金融、电力、公安、交通管理、招生、考试、录取等领域的专用软件,企事业单位生产、工作、管理、服务的各种事务类软件,监视、分析和控制正在发生的现实世界事件的各种实时软件,各类科学和工程软件,用于工业、民用或军事上的各种功能的与设备融为一体的嵌入式软件,个人计算机软件,手机上的各种实用软件,基于Web的软件,儿童玩具中的软件,人工智能软件,等等。
(3)工具软件
用于辅助和支持开发及维护的应用软件,以提高软件开发质量和生产率的软件都可称为工具软件。如软件进度安排软件、软件成本估算工具、软件需求分析工具、软件设计工具、软件编码工具、测试工具、系统维护工具、管理工具等,这些软件工具不仅能完成指定的工作,还能进行完备性、一致性、正确性、安全性、追溯性等方面的检查,完成一些人工所不能完成的事情。
(4)可重用软件
是指通过修改、剪裁等手段应用于新软件的软件,可重用软件并不仅指代码,也可以是软件设计、规范、数据、测试用例,甚至概念等,可以把它们统称为可重用软件构件,目前,常见的各种图形用户界面一般是使用可重用软件构件创建的,这些构件涉及图形窗口、下拉菜单和各种交互机制。建造用户界面所需要的数据结构和处理细节包含在一个由界面构件所组成的可重用构件库中,开发人员通过可重用构件来开发新的软件。
若按功能对软件进行分类,则可划分为系统软件、支撑软件和应用软件三大类;若按规模进行划分,可将软件分为7类,如表1-1所示;若按软件工作方式进行划分,则可分为实时处理软件、分时软件、交互式软件和批处理软件4类;若按软件服务对象的范围进行划分,则可分为项目软件和产品软件2类;若按软件的应用领域进行划分也可将软件分为7类,如表1-2所示;还可按其他方式对软件进行划分,如按软件的使用频度进行划分、按软件失效的影响进行划分等。
表1-1 按规模对软件的分类
表1-2 按应用领域对软件的分类
软件产品包括两类,通用软件产品和定制软件产品。它们的区别在于,通用软件产品的描述由开发者自己完成,而定制软件产品的描述通常由客户给出,开发者必须按客户要求进行开发。因而,各类数据库软件、字处理软件、绘图软件、工程管理软件等属于通用软件产品,而特定的业务处理系统、电子设备的控制系统、空中交通管制系统等属于定制软件产品。
1.1.2 软件工程的产生和发展
1.软件工程的产生
20世纪40年代中期,美国宾夕法尼亚大学约翰·莫克莱(John Mauchly)和普雷斯帕·埃克特(J.Presper Eckert)(见图1-3)研制出世界上第一台电子数字计算机ENIAC。1947年,数学家冯·诺依曼(J.Von Neumann,如图1-4所示)针对ENIAC提出了EDVAC(Electronic Discrete Variable Automatic Computer)方案,在该方案中首次提出了“存储程序”的概念,图1-5所示是1951年实现的EDVAC。1949年,由英国皇家科学院院士莫里斯·威尔克斯制造的世界上第一台实现冯·诺依曼“存储程序”思想的计算机EDSAC(Electronic Delay Storage Automatic Calculator)问世。从冯·诺依曼提出存储程序概念至今的时间中,软件发生了很大变化,其发展可用表1-3概括。
图1-3 莫克莱和埃克特
图1-4 冯·诺依曼
图1-5 EDVAC(1951)
表1-3 软件的演化历程及特征
从表1-3可以看出,在20世纪60年代由于软件的发展不能满足需求出现了软件危机,所谓软件危机是指在计算机软件开发和维护过程中所遇到的一系列问题,这些问题几乎存在于所有的软件中。
软件危机主要表现为以下6个方面。
(1)软件开发成本和进度估计不准确
据统计,软件项目约有40%延期或超预算,20%不得不取消,真正成功的软件项目案例不足40%。实际成本比估计成本高出一个数量级,实际进度比预期进度拖延几个月,甚至几年的现象经常发生。例如,微软公司的Word 3.0原定于1986年7月推出,但是直到1987年2月才问世,但问世后很快就发现有很多错误,据说有700多处错误,有的错误甚至会破坏数据,摧毁程序,微软不得不花费100万美元在两个月内为用户免费升级。
(2)软件需求分析不充分,开发出的系统与实际需求有差距
软件开发人员和用户之间的信息交流往往很不充分,在没有确切了解问题的情况下,或对用户需求还很模糊的情况下就开始编写程序,导致开发出的软件产品与实际需求有差距,甚至不符合用户的实际需要。在进行软件需求分析时,不但要考虑功能需求,还要考虑质量需求和约束,既要有产品需求,还要有市场需求和组件需求,如果缺少必要的需求,或得到错误的需求,或不断变更的需求,都会最终导致系统失败。例如,哈维兰彗星1号客机,由于没有考虑到方形窗口的承压能力而经常坠毁;塔科马海峡大桥在需求和设计模型中没有考虑风力因素而被大风吹垮;Ariane 5型火箭不恰当地复用了需求,导致在第一次试航中坠毁。据克里斯托夫·埃伯特(Christof Ebert)(如图1-6所示)所著《需求工程:实践者之路》一书中给出的数据,87%的项目失败是由于需求工程做得不够而引起的。
(3)软件投入使用后经常出故障
一个著名的例子是美国IBM公司的OS/360,这是第一个功能较强的多道程序操作系统,参加这项开发工作的有IBM公司美国国内的11个单位,欧洲的6个单位,共计1000多人,耗费了5000人年的工作量,但结果不尽人意,它的每个版本都是在前一版本的基础上找出1000个程序错误而修正的结果,项目总负责人费雷德里克·布鲁克斯(FrederickP.Brooks Jr.,见图1-7)在他所著的《人月神话》(The Mythical Man-Month)一书中生动地描述了开发中遇到的困难和问题,提出了很多令人深思的观点。
图1-6 克里斯托夫·埃伯特
图1-7 费雷德里克·布鲁克斯
(4)软件难以维护
软件的维护不像硬件那样通过进行零部件的修复、更换或系统整体升级就能做到,修改了发现的错误后可能还会导致新的错误,更换后的软件也不一定比旧软件好。例如,美国第四大药品批发商福克斯迈尔医药公司在1994年决定用C/S系统和SAP软件代替老化的Unisys大型系统,该公司每天要填写成千上万份药房订单,每个药房又订购上千种药品,总量达50万种,与系统升级和改造相关的费用就花费了3800万美元。但在系统投入实际使用中却发现SAP软件每天只能处理几千条数据,在短短几个星期内,由于发出错误订单这一项,就使公司遭受了1550万美元的损失,最后迈基森公司为其支付了8000万美元现金,才使其子公司没被破产,总公司的股票也从26元跌到3元,使公司蒙受了巨大损失。
很多程序中的错误很难改正,让一个软件系统适应新的硬件环境,或在原有程序中增加一些新功能都非常困难,有时为了纠正软件的1个错误的工作量甚至可能要超出原来软件开发的总工作量。
(5)缺乏文档资料
在软件开发过程中应该有一套与之同步生成的文档资料,它们是软件开发过程的“里程碑”,若缺乏文档资料或事后再补都会给开发及维护带来困难。在计算机诞生的早期,软件规模比较小,应用领域狭窄,文档的作用并不十分突出,但是随着计算机应用领域的扩大及软件技术的发展,特别是软件工程的出现,软件文档的地位和作用也越来越重要,软件文档在软件产品开发过程中起到了重要的桥梁作用。例如,20世纪70年代初,汽车中只有几个控制器,需求规格说明书加在一起也不过上百页,而现代汽车中有50多个控制器,需求规格说明书达到了10万页。目前,软件文档已经成为项目管理的依据、软件人员进行技术交流的语言和依据、也是进行项目质量审查和评价的重要依据,它们为用户和技术人员提供培训和维护的资料、为维护软件提供技术支持,它们还是未来项目的一种资源,良好的系统文档有助于把程序移植和转移到各种新的系统环境中。
(6)软件在计算机总成本中所占比例逐年上升,维护费用增长迅速
在计算机系统诞生的早期,硬件的价格决定了系统的整体价格,但是随着硬件技术的快速发展及价格的不断下降,硬件与软件在整个计算机系统中的比重快速发生着变化,到20世纪60年代它们的成本比例就发生了颠倒,软件成本成为主体,例如,某发电厂花几百万元购买的数据采集与监控系统(简称SCADA系统),其中的90%都是软件费用。现在硬件已经成为软件的“包装”,软件的成本就决定了整个系统的价格。据美国军方给出的数据,在20世纪60年代的F-4战斗机中,由软件来完成的功能约为整体功能的8%,到90年代,在B-2轰炸机中,由软件来完成的功能就占到整体功能的65%,而在21世纪,在F-22战斗机中,由软件来完成的功能占到整体功能的80%,由此可看出软件已居主导。目前,软件费用已经成为计算机系统的主要费用,其中维护费用又占去了大部分,有些软件机构70%的工作量都花在维护已有的软件上。
随着计算技术的发展,软件危机的表现形式也在发生变化,旧的危机克服了,还会出现新的危机。为了摆脱日益严重的软件危机,1968年在德国小镇加米施(Garmisch)召开的北大西洋公约组织(简称NATO)学术会议上,与会学者们首次提出了软件工程的概念,图1-8所示是当时的会场,这次会议是软件开发走向工程化的标志,从此软件技术的发展及软件工程的研究有了长足的进步,并起着越来越大的作用。目前,软件工程已经成为一门大的学科,在它下面又出现了很多新的学科,需要研究的未知领域和课题还很多,但软件危机并未完全解决。
图1-8 1968年在NATO学术会议上首次提出了软件工程的概念
2.软件工程的定义
软件工程既是工程,又是一门学科,软件工程学科的内容很丰富,定义也是多种多样,最早的定义是弗里斯·鲍尔(Frith Bauer)在NATO学术会议上给出的,他指出软件工程是建立和使用一套合理的工程原则,以便经济地获得可靠的、可以在实际机器上高效运行的软件。
IEEE给出的软件工程定义是:软件工程首先是将系统化的、规范的、可量化的方法应用于软件的开发、运行和维护,即将工程化方法应用于软件;其次是与上述有关方法的研究。
美国国家工程院院士、著名的软件工程专家巴利·玻姆(Barry W.Boehm)(如图1-9所示)给出的定义:软件工程是现代科学技术知识在设计和构造计算机程序中的实际应用,其中包括管理在开发、运行和维护这些程序的过程中所必需的相关文档资料。
美国软件工程专家RogerS.Pressman把软件工程视作一种层次化技术,软件工程的任何活动都必须建立在高质量的基础之上,支持软件工程的根基就在于高质量,他的层次技术思想可以用图1-10来描述。
图1-9 巴利·玻姆
图1-10 软件工程层次图
从图1-10可以看出,软件工程层次结构的基础是过程层,过程层定义了一个框架,构建该框架是有效实施软件工程技术必不可少的。软件过程构成了软件项目管理控制的基础,在软件过程中要建立工作环境以便于应用技术方法、提交工作产品(如模型、文档、数据、报告、表格等)、建立里程碑、保证质量及正确管理变更。
软件工程方法为构建软件提供技术上的解决方法,主要包括沟通、需求分析、设计建模、编程、测试和技术支持。软件工程技术方法依赖于一组基本原则,这些原则涵盖了软件工程所有技术领域,包括建模和其他描述性技术等。
软件工程工具为过程和方法提供自动化或半自动化的支持。这些工具可以集成起来,使得一个工具产生的信息可被另外一个工具使用,这样就建立了软件开发的支撑系统,称为计算机辅助软件工程。
北京大学王立福教授等给出的软件工程定义:软件工程是一类求解软件的工程。它应用计算机科学、数学及管理科学等原理,借鉴传统工程的原则、方法,创建软件以达到提高质量、降低成本的目的。其中,计算机科学、数学用于构造模型与算法,工程科学用于制定规范、设计泛型、评估成本及确定权衡,管理科学用于计划、资源、质量、成本等管理。软件工程是一门指导计算机软件开发和维护的工程学科。
从以上软件工程的定义可以看出,软件工程包含的内容很丰富,它涉及软件开发、管理、维护、质量保证等各个方面,它既有一般工程的特点,也有其特殊性,它不但和软件相关,也和其他学科相关,软件工程是一门多学科交叉的学科。
1.2 软件的生命周期
软件和任何有生命或无生命的事务一样,有它的生命周期(或称为生存周期),一个人的生命周期是从孕育、出生,经过乳幼期、少年期、青年期、壮年期、老年期直到死亡,如图1-11所示,各个阶段的投入、目标、活动显然都是不一样的,在人的生命周期中对社会的贡献主要在成年期。软件与人的生命周期在某些方面很类似,一个软件的生命周期是指从制定软件计划开始,经过软件需求分析、软件设计、编码、软件测试、运行和维护直到软件被弃的全过程,如图1-12所示,软件的价值体现在运行和维护阶段,甚至价值曲线的形状也与人对社会的贡献曲线类似,呈“U”字形。
图1-11 人的生命周期
图1-12 软件的生命周期
软件的生命周期各阶段是从宏观上对软件的划分,当然也可以粗略地划分为计划、开发和维护3个阶段。与人的生命周期不同的是,软件的生命周期与开发模型有关,不同的开发模型可能对应着不同的生命周期。生命周期不同,则软件开发阶段的划分、评审次数及基线标准都有所不同。
1.2.1 计划阶段
软件计划阶段相当于婴儿在母腹中的孕育时期,这个阶段的主要工作有五项,一是确定待开发软件系统的工作范围,主要是给出软件的功能、性能、约束、接口和可靠性等方面的要求;二是预测开发该软件所需要的人力资源、可重用软件资源,以及软件和硬件工具;三是使用估算技术和估算模型对所开发软件的成本进行估算,也包括开发进度、开发工作量等的估算;四是对软件风险进行管理,包括风险的识别、预测、缓解和监测等,风险是对未来不确定性的预测,风险既可能是由人员引起的,也可能是技术、成本方面的原因,还可能是时间方面的原因,不同风险的影响程度也是不一样的,有些风险影响程度较小,甚至可以忽略,而有些风险可能很严重,甚至造成灾难性的后果,因而,风险也是分等级的,只有对风险进行了有效的评估,才有可能有效的管理和控制风险;五是对软件开发进度进行安排,它类似于铁路列车时刻表的编制,如果不按照规定的时间运行,造成的后果是不言而喻的,软件开发进度安排也是如此,关键时间点不能变,否则软件的交付就会延期。软件计划阶段工作结束后,要交付软件项目开发计划,该计划是一个里程碑性质的文件,上述五项是其中的核心内容,书写时应按有关标准和格式进行,经过审查通过后,才能开始进入到正式的软件开发。软件项目计划审查通过后相当于婴儿的诞生,把一个婴儿培养成对社会有用的人,还需要做很多工作。
1.2.2 分析和定义阶段
这一阶段即软件生命周期中的需求分析阶段,需求分析是软件生命周期的重要阶段,目标是深入描述软件的功能和性能,确定软件设计的约束、软件同其他系统元素的接口细节,定义软件的其他有效性需求。这一阶段的工作对软件产品的成功起到很大的作用,据统计,软件项目失败的原因87%是由于需求分析做得不够而引起的,由于需求分析工作的地位和作用十分重要,因而诞生了一门学科——需求工程,需求工程虽然是软件工程的一部分,但也是一门独立的学科。需求工程是为了系统性地、规范地进行需求获取、需求编写、需求分析、需求协商、需求审查以及需求管理,使顾客对软件的期望以及软件达到的目标在一个产品中实现。软件需求规格说明(Software Reqaiements Specification,SRS)是分析阶段的最终产物,是软件工程过程中的里程碑式的文档,因而是需求分析阶段最重要的文档。俗话说“磨刀不误砍柴工”,需求工程就是在“磨刀”,如果需求工作不充分,就像拿钝斧子砍树,并不能加快软件的交付,反而会更慢。
软件需求分析方法主要有结构化方法、原型化方法和面向对象方法。结构化分析是面向数据流进行需求分析的方法,它从宏观到具体采用自顶向下的方式描述现实问题,经过一系列的分解和抽象,得到的底层数据流图就是描述具体问题的解决方案,用结构化分析方法产生的SRS中主要包括数据流图、数据字典、E-R图以及状态图等。
原型化开发过程有抛弃式、演化式和增量式,主要是针对软件需求很模糊的情况下,通过不断地构造原型,以迭代的方式逐步搞清楚用户的需求。主要原型开发技术有三种:使用动态高级语言、数据库编程和组件复用,原型开发技术对用户界面的设计和实现是一种有效的方法。原型化开发软件是一个不断演化的过程,初始原型通常质量不高,因此,用这种方法开发软件时要废弃掉很多中间原型,而且一定要以质量为第一目标,SRS中的前述内容仍然需要,也可采用迭代方式在软件迭代的过程中同步产生SRS,并且要描述原型内容。
面向对象分析是利用面向对象的概念和方法构建软件需求模型,如用统一建模语言(Unified Modeling Language,UML)的用例图定义功能及交互活动的关键步骤、用活动图来说明场景、用泳道图来显示如何给不同的参与者或类分配处理流。面向对象的方法关注对象的内在性质,以及对象的关系与行为。在开始构建系统之前,必须定义出表示待解决问题的类(对象)、类之间的相互关联和交互的方式、对象的内部结构(即属性和操作)以及允许对象在一起工作的通信机制(消息)。所有这些事情均是在面向对象分析中完成的。在面向对象的方法中,UML是目前流行的建模工具,可以用它定义类的层次、关系、关联、聚合和依赖等,UML适用于系统开发的全过程,从需求规格描述直到系统建成后的测试和维护阶段。此外,还可以用CRC(Class-Responsibility-Collaborafor)索引卡的方式定义类之间的联系。上述建模过程及所建模型都应在SRS中体现出来。
1.2.3 设计阶段
软件设计阶段是软件开发中的关键阶段,它比编码工作重要得多。在设计过程中需要软件开发者付出创造性的劳动。软件生命周期中的上一阶段——需求分析阶段,主要解决的是需要让所开发的软件“做什么”的问题,并且已在SRS中详尽和充分地进行了描述。进入设计阶段后,应该解决“怎么做”的问题。简单地说,软件设计就是以SRS为基础,把确定的软件需求转换成相应的体系结构,对系统结构中的每个成分的具体工作进行描述,编写出设计说明书,提交有关部门评审。
软件设计可以分为两个阶段,概要设计和详细设计,概要设计主要是针对软件体系结构的设计,详细设计则把重点放在对软件过程的描述上,它为下一阶段实现系统奠定基础。
软件体系结构是构造系统的基本框架,就像楼房的架构一样,不同的楼房按用途其构造会完全不同,软件的构造也是如此,不同的软件应用适合于不同的体系结构,因而有不同的体系结构模型,常见的体系结构模型有以数据为中心的黑板模型、以变换数据的构件为主而构成的管道过滤器模型、以程序构件为主要构成成分的返回和调用体系结构模型、以信息隐蔽原理构造的面向对象体系结构模型、按每个层次各自完成不同操作形成的层次体系结构模型,等等,理想化的、所有软件系统皆适用的体系结构模型是没有的。
软件体系结构中各个元素之间都不是孤立的,因而要研究各个成分之间以及成分内部的联系,评价软件结构质量的度量标准是成分之间的耦合性和内聚性,这是一个问题的两个方面。以返回和调用体系结构为例,它的成分一般是程序模块,模块之间的耦合性从强到弱包括内容耦合、公共耦合、外部耦合、控制耦合、标记耦合、数据耦合和非直接耦合7种,内容耦合最差、非直接耦合最好,内聚性则是衡量一个成分内部能力的一种度量,还以返回和调用体系结构为例,模块的强度从弱到强包括偶发强度、逻辑强度、时间强度、过程强度、通信强度、顺序强度和功能强度7种,偶发强度的模块最差,功能强度的模块最好,软件设计追求的目标是强内聚、弱耦合。
软件设计方法也有多种,如面向数据流的设计方法、面向数据结构的设计方法、面向对象的设计方法、面向方面的设计方法、面向Agent的设计方法、面向构件的设计方法、敏捷方法等等,有些方法是成熟的,有些还在发展中。
面向数据流的设计方法也称为结构化设计方法,它是根据问题域的数据流(数据对象)定义一组不同的映射,把问题域的数据流(数据对象)转换为问题解的程序结构。结构化设计方法的要点是“自顶而下,逐步求精”。简单地说就是先构造高层的结构,然后再逐层分解和细化,从宏观到具体设计软件,避免一开始就陷入复杂的细节中,设计中模块可作为插件或积木使用,这样就降低了程序的复杂性,提高了可靠性。
面向数据结构的设计方法则是根据问题的数据结构定义一组映射,以问题的数据结构为基础转换为问题解的程序结构。在面向数据结构的设计方法中,Jackson(1975年,M.A.Jackson提出)方法和LCP(Logically Constracting Program)方法是最具代表性的方法,Jackson方法简单、易学易用,对于规模不大的数据处理系统非常适用,在了解了系统需处理的数据结构后,如果能找到输入和输出数据结构之间的对应性,其程序结构很容易导出。LCP方法本质上和Jackson方法是一样的,但它是更严格的一种软件设计方法,是建立在数据结构和程序过程结构关系上的方法。在软件生命周期中,数据结构往往会发生变化,一旦数据结构变化了,以数据结构为基础建立的整个程序结构也就需要改变。因而,对于复杂的、比较大的软件系统、数据结构易变化的系统都不适合用面向数据结构的设计方法。
面向对象的设计方法已经成为主流软件设计方法,它以对象为中心,软件中的任何元素都是对象,复杂的软件对象是由比较简单的对象组合而成。在面向对象的设计方法中,把所有对象都划分成各种对象类(简称为类,class),每个对象类都定义了一组数据和一组方法。数据用于表示对象的静态属性,是对象的状态信息。每当建立该对象类的一个新实例时,就按类中对数据的定义为这个新对象生成一组未用的数据,以便描述该对象独特的属性值。按照子类与父类的关系,把若干个对象类组成一个层次结构的系统。在这种层次结构中,下层的派生类具有和上层的基类相同的特性(包括数据和方法),这种现象称为继承。如果在派生类中对某些特性又做了重新描述,则低层的特性将屏蔽高层的同名特性。对象彼此之间仅能通过传递消息互相联系。对象与传统的数据有本质区别,它不是被动地等待外界对它施加操作,它是进行处理的主体,必须发消息请求它执行它的某个操作,处理它的私有数据,它的属性和操作对外界都是隐蔽的,所以不能从外界直接对它的私有数据进行操作,这种灵活的消息传递方式,便于体现并行和分布结构。
以上方法都有一定的局限性,因而人们还在研究新的方法,代表性的方法如面向方面的设计方法、面向Agent的设计方法、泛型程序设计、面向构件的设计方法、敏捷方法、Rational统一过程、FDD方法、XP方法等,这些方法目前还不成熟。
软件设计结束后,要交付里程碑式的文档,大中型以上规模的软件系统既要交出概要设计说明书又要交出详细设计说明书,甚大型软件系统还要交出数据库设计说明书,系统越大、越复杂要求交付的文档越多,小型软件系统只需交付一个文档,即交出软件设计说明书即可。软件设计说明书是重要文档,完成后要组织评审。
1.2.4 实现阶段
这一阶段是根据软件详细设计说明书,编程实现系统,并进行测试,所以也称为编码阶段,简单地说,就是将软件设计转换成计算机程序代码,并编写测试用例,对模块进行测试。
不同的程序设计语言适用于不同的应用领域,选择合适的语言可提高编程效率和提高程序的质量,但十全十美的语言是不存在的,一般应选择尽可能熟悉的、能较好满足应用领域要求的语言。对于成熟的软件企业由于积累了丰富的管理经验,过程管理到位,软件的构件库、类库以及各种资源丰富,软件的实现就相对容易。
计算机程序设计语言有成百上千种,分类方法也不太一样。从时间上看计算机语言的发展大致经历了四代,第一代是机器语言时代,第二代是汇编语言时代,第三代是高级语言时代,目前主要使用的是高级语言,高级语言是过程性语言,第四代语言是非过程性的,第四代语言的发展将逐步改变程序设计的方式。在实现软件时要重视编码风格,因为它直接影响到软件的可维护性和易理解性,编码风格就像作家的写作风格,好的作品不但给读者以享受,而且会影响到读者的思想和行为,程序虽然最终要转换成机器去执行的指令,但更重要的是给人看的,因此要重视编码风格。好的编码风格对软件企业的发展、对软件过程管理水平的提高以及对软件企业文化的形成都有很大的影响。
程序设计也是艺术,编程人员不但要遵守规范,而且要考虑它的效率、它的价值、以后是否能重用以及重用的方式,这样才能使软件企业的生产效率不断提高,编码质量不断提高,使企业不断地向高等级迈进。良好的编码风格要求使用合适的语句结构,源程序要文档化,数据说明要规范并易于理解,输入/输出要简单、格式尽可能一致。
1.2.5 测试阶段
简单地说软件测试阶段就是检验开发的软件是否完成了所要求的功能,整体性能、结构如何,是否满足用户的要求以及是否能与其他系统元素协同工作等。严格地说,软件测试从编码阶段就应该开始。
软件测试是保证软件质量的重要活动,也是软件开发过程中占有最大百分比的技术工作。软件测试的目的是为了发现错误,找出软件产品的缺陷,因而,没有发现错误的测试是不成功的,为了使测试工作有效且系统化,将测试阶段又划分成单元(或组件)测试、集成测试、确认测试和系统测试几个子阶段,目的是为了有针对性地发现错误。软件测试的步骤可以用图1-13形象地描述,单元测试是检查每个程序模块是否正确地实现了规定的功能。在面向对象的测试中,单元测试就是对组件的测试,组件可以是对象类或函数,或者是这些实体的一个相关集合;集成测试是将经过单元测试的模块组装起来进行测试;确认测试是检查软件是否满足SRS中确定的各种需求以及软件配置是否完整、正确;系统测试则是把软件纳入实际运行环境中,与其他系统元素一起进行测试。
图1-13 软件测试活动示意图
由于软件各个开发阶段的任务不同,因而所采用的测试方法和策略也不同。如集成测试可分为增殖测试、非增殖测试和混合增殖测试,增殖方式又可分为自顶向下以及自底向上增殖方式。确认测试包括功能测试、软件配置审查、验收测试以及α测试和β测试4种。
软件测试的种类大致可分为人工测试和基于计算机的测试,基于计算机的测试又可分为白盒测试和黑盒测试。白盒测试是结构测试,它以程序的逻辑为基础设计测试用例,基本思想是选择测试数据使其满足一定的逻辑覆盖,以此来尽可能地发现这一类中的错误。逻辑覆盖可分为语句覆盖、分支覆盖、条件覆盖、分支/条件覆盖、多重条件覆盖和路径覆盖6种。黑盒测试是功能测试,它不考虑程序的内部结构,根据程序的规格说明来设计测试用例,主要方法有等价类划分法、边界值分析法、错误推测法和因果图法,它的假设前提是,如果测试中发现了错误,那么满足某个条件的测试用例发现的就是这一类中的错误。
人工测试主要有桌面检查、代码会审和走查,代码会审和走查一般以会议的方式进行,3~5人开会,每次会议1.5小时左右。
测试工作结束后要进行软件调试。调试与测试不同,软件测试的目的是要尽可能多地发现软件中的错误,而调试是要进一步诊断和改正程序中潜在的错误,调试的方法主要有强力法排错、回溯法排错、归纳法排错和演绎法排错。
软件测试阶段主要交付的文档有软件测试计划和软件测试报告,软件测试计划起到一个框架结构的作用,它规划了测试的步骤和安排。一个测试计划的基本内容包括基本情况分析、测试需求说明、测试策略和记录、测试资源配置、问题跟踪报告、测试计划的评审等。软件测试报告是产品部门与技术部门沟通的主要技术手段,测试报告直接影响软件缺陷的修改速度。因此,软件测试报告必须是客观的。一个好的测试报告,应该使阅读报告的人获益。软件测试报告的主要内容包括测试内容、测试意义及目标、测试环境与测试标准、测试用例设计及测试结果、软件功能的结论、可靠性和有效性评价、软件缺陷及改进建议、测试消耗等。软件测试报告评审通过后,软件才能投入使用或投放市场。
1.2.6 运行和维护阶段
这一阶段相当于人的生命周期中的成年期,软件的价值也是在这个阶段才能体现出来,人在这一时期不但要给社会做贡献,同时也要维护自身的健康,得病了需要治疗,身体弱了要加强锻炼,要注意保健、提升自身素质等。软件也是如此,软件系统在投入运行后,还会逐步暴露出错误,另外,用户可能也会不断提出一些新的要求,或者软件要适应新的环境。因此,软件系统需要不断地排错、修改、扩充功能,这些工作都是维护。
软件维护是软件生命周期中消耗时间最长、最费精力、费用最高的一个阶段。如何提高可维护性、减少维护的工作量和费用是软件工程的一个重要任务。系统规模越大、越复杂则相应的维护工作也越多。按照不同的目标,维护活动可以分为4类:以纠正软件错误为目的的纠错性维护;为适应运行环境变化而进行的适应性维护;以增强软件功能为目标的完善性维护,以及为了改善未来软件的可靠性和可维护性所进行的预防性维护。这4种维护分别占总维护工作量的21%、25%、50%和4%,如图1-14所示。
软件可维护性是软件开发各个阶段的关键目标之一,为使软件具有较高的可维护性,在软件开发过程中,要使软件尽可能地具有较高的可理解性、可测试性、可修改性、可靠性、可移植性、可使用性和高的运行效率。
图1-14 软件维护工作量的分布
为提高软件的可维护性,在软件开发过程中要提供完整和一致的文档,进行严格的测试和阶段审查,建立明确的软件质量目标和优先级,使用现代化的开发技术和工具,并选用可维护性好的程序设计语言。
随着软件技术的飞速发展,软件维护技术也随之发展,对于新软件体系结构应采用新的软件维护方法。软件再工程是一种新的预防性维护方法,它通过逆向工程和软件重构等技术,来有效地提高现有软件的可理解性、可维护性和复用性。对现有应用系统实施再工程之前,应进行成本效益分析,有价值的系统才适宜进行软件再工程。对于多个欲将再工程的应用系统应按照成本效益分析的优先级进行排序,先对再工程整体效益高的应用系统实施软件再工程。
1.3 软件开发模型
软件开发模型也称为软件生存期模型,是软件开发过程的一个宏观框架,该框架反映了软件生命周期的主要活动以及它们之间的联系。
进行一场战役决策者们要制作沙盘,以便排兵布阵,讨论战役的进展,掌控全局。类似地,软件开发模型其实就是从宏观上描述软件的开发进程,讨论如何安排软件生命周期中的各项工作和任务,如何组织软件生命周期中的各种活动,各个阶段如何衔接。
1.3.1 瀑布模型
瀑布模型是提出最早的。目前使用最广泛的软件开发模型,图1-15是瀑布模型的基本形式。从图中可以看出,整个模型如同瀑布流水,开发活动互相衔接,逐级下落,每个阶段都必须在上一阶段的工作结束后才能开始。这种模型描述的是很规范的软件开发方式,每个阶段都有明确的工作目标和任务。
图1-15 瀑布模型的基本形式
瀑布模型的形式多种多样,如图1-16和图1-17所示,都是基本形式的变种。在图1-16中,将软件维护活动进行了展开,也和开发活动一样有序进行,由此就构成了软件生命周期的循环形式。
图1-16 循环形式的瀑布模型
图1-17 b型软件生存周期
图1-17其实是图1-15和图1-16合成后得到的,整体形状像英文字母“b”,由于软件在投入运行后要不断地维护,为把开发活动和维护活动区别开来,所以提出了b型软件生存期模型,并且把维护看作是软件的二次开发。
瀑布模型是其他模型的基础,是规范的开发模型,它支持结构化开发,为软件开发和维护提供了较为有效的管理模式,它对控制软件开发复杂度、制定开发计划、进行成本预算、组织阶段评审和文档控制等各项软件工程活动都较为有效,对保证软件质量具有较好的作用。但它的突出缺点是缺乏灵活性,无法应付软件需求不明确、不准确的问题,特别是,由于各阶段工作次序固定,使前期工作中造成的差错越到后期影响越大,带来的损失也越大,而要想纠正它们所花费的代价也越高,而这又是不可避免的。
1.3.2 演化模型
演化模型也叫原型开发模型,主要是针对事先不能完整定义需求的软件开发而提出的,它是瀑布模型的变种。开发人员根据用户的需求,先开发一个原型,让用户试用,用户提出改进、精化及增强系统能力的需求。开发人员根据用户的反馈意见,实施开发的迭代过程。这一过程反复进行,逐渐演化成最终的系统。每一迭代过程均由需求、设计、编码、测试、集成等阶段组成,图1-18所示是一种演化模型的表示。如果在一次迭代中,有的需求不能满足用户的要求,可在下一次迭代中进行修正。
图1-18 一种演化模型
演化模型也有多种形式,如丢弃型、样品型、渐增式演化型等,它的特点是突出一个“快”字,用户可以很快看到未来系统的“样品”,但它存在的问题也比较严重。一方面,为了尽快构造出原型,开发人员常常不得不使用不适当的开发环境、编程语言以及效率不高的算法,而这些有可能集成到系统中,成为实际系统的一部分。另一方面,构造原型时很难考虑到软件的整体质量和系统以后的可维护性问题,由此,可能造成开发出的软件质量不高。
1.3.3 螺旋模型
螺旋模型整体是螺旋形状,它也是反复迭代的过程,如图1-19所示,螺旋模型其实是把瀑布模型和演化模型相结合所建立的一种软件开发模型,它的显著特点是加入了二者所忽略的风险分析。软件风险是任何软件项目中都普遍存在的现象,也是多方面的。风险分析的目的是在造成危害之前,及时对风险进行识别,并采取对策,进而消除或减少风险造成的损害。
图1-19 一个典型的螺旋模型
一般按软件生命周期的工作任务将螺旋模型划分为若干框架活动,也称为任务区域,每一个区域均包含若干适应待开发项目的工作任务,称为任务集合。对于较小的项目,工作任务较少,形式化程度较低;对于较大的、关键的项目,每个任务区域都有较多的工作任务且形式化程度较高,典型的螺旋模型有3到6个任务区域,图1-19是6个任务区域的螺旋模型。
从中心开始,顺时针按螺旋线向外移动,就可一步一步地建立起完整的软件版本。在第1圈可能产生软件产品的归约,第2圈可能产生一个原型,第3圈用于软件产品的增强,第4圈可能是软件产品的维护。每次经过“制定计划”区域是为了对软件项目计划进行调整,根据用户的评价来调整费用和进度,根据每次的风险分析结果,都要做出继续还是停止的决策,如果项目风险太大就只能停止。
螺旋模型是当前大型软件系统开发的最现实方法,但它要求有风险评价的专门技术,这些专门技术决定了评价是否成功,若主要风险不能发现,则会造成重大损失。
1.3.4 喷泉模型
喷泉模型如图1-20所示,是描述面向对象软件开发过程的模型,喷泉的特点是连续无间隙。用面向对象技术开发软件时,软件生命周期中的各个阶段之间并无明确的边界,工作是连续的,就像喷泉一样,在分析阶段根据分析员的理解建立了相关概念,如建立用例图、类图、类的层次结构图、建立实例联系等,并确定了类的属性和操作。由于分析和设计是连续的过程,进入设计阶段后,可能还会派生出一些对象类,并要建立对象间的联系,在实现阶段,为适应问题描述及解法可能还会设计一些对象类,在测试阶段可能会根据测试需要又要派生出新的类,这个过程是迭代的。系统的某个部分常常会重复工作多次,相关功能在每次迭代中被加入演进的系统,因此,用“喷泉”一词来描述是很贴切的。
图1-20 喷泉模型
1.3.5 其他模型
软件生存期模型只是对软件生命周期各个阶段工作的一种图示化描述,它描述了软件开发都有哪些工作,各项工作如何衔接,同时也是为了指导软件开发过程。除了以上几种典型模型外,还有一些比较有影响的模型。
1.智能模型
智能模型是以专家系统或知识库为核心,所有的软件工程工作都与这个核心有关,因而该模型是基于知识的软件开发模型,如图1-21所示,知识库中存放模型、知识、规则,软件开发人员采用规约和推理机制,辅助进行相关开发工作。从图中可以看出,软件的维护不在程序一级上进行,而是在功能归约也就是需求分析一级进行,这就把问题的复杂性大大降低了,从而可把精力更加集中于具体描述的表达上。具体描述可以使用形式功能归约,也可以使用知识处理语言描述等。
图1-21 智能模型
2.增量模型
增量模型也是从瀑布模型演化而来,如图1-22所示,它融合了瀑布模型和原型开发模型的优点,也可以看作是演化模型的一种。宏观上看开发过程是迭代进行的,每次迭代都像是一个瀑布模型,它的每个增量都是可交付的软件。通常,每个增量的建造是基于那些已经交付的增量而进行的,任何增量均可以按原型开发模型来实现。例如,使用增量模型开发一个字处理软件,在第1个增量中发布基本的文件管理、编辑和文档生成功能,在第2个增量中发布更加完善的编辑和文档生成能力,第3个增量实现拼写和语法检查功能,第4个增量完成高级页面布局功能,等等。在不断地演化中,产品的功能、性能不断地提高。
图1-22 增量模型
3.并发过程模型
并发过程模型有时也称并发工程,它定义了一系列事件,这些事件将触发软件工程的主要技术活动、动作或者任务的状态转换。例如,设计的早期阶段(建模活动期间发生的主要软件工程动作),发现了需求模型中的不一致性,于是产生了分析模型修正事件,该事件将触发需求分析动作从“完成”状态到“等待改变”状态。图1-23是并发过程模型中一个活动的图形表示,该活动是分析,其他活动也用类似的方式表示。
图1-23 并发过程模型的一个元素
并发过程模型可用于所有类型的软件开发,它能够提供精确的项目当前状态图。它不是把软件工程活动、动作和任务局限在一个事件的序列,而是定义了一个过程网络。网络上每个活动、行为和任务与其他活动、行为和任务同时存在。过程网络中某一点产生的事件可以触发状态的转换。
4.基于构件的开发模型
基于构件的开发(Component-Based Development,CBD)模型是在面向对象技术的基础上发展起来的,如图1-24所示,它融合了螺旋模型的许多特征,利用预先包装好的软件构件(有时称为类)来构造应用系统。统一软件开发过程(Unified Software Development Process)是近年来产业界提出的一系列基于构件开发模型的代表。使用建模语言UML,统一过程定义了将被用于建造系统的构件和将用于连接构件的接口。使用迭代和增量开发的组合,统一过程通过应用基于场景的方法(从用户的视角)来定义系统的功能,然后将功能和体系结构框架耦合,体系结构框架标识了软件将呈现的形式。
图1-24 基于构件的开发模型
基于构件的软件工程在特定的应用领域内标识、构造、分类和传播一系列软件构件。这些构件经过合格性检验、适应性修改,并集成到新系统中。对于每个应用领域,应该在建立了标准数据结构、接口协议和程序体系结构的环境中设计可复用构件。
5.面向复用的软件开发模型
面向复用的软件开发模型也称为面向复用的软件工程,它与基于构件的开发模型的思想是一致的。
在大多数的软件项目中,都存在一定程度的软件复用。例如,当人们注意到某项目中的设计或代码是与当前项目中所需要的部分很相像的时候,一般不会再重做一次,因而复用就自然地发生了。人们搜寻这些可复用的东西,而后根据需要修改它们,再将其纳入到自己的系统中来。但是,这样随意性的复用并没有考虑到所采用的开发过程。
在21世纪的今天,注重复用现存软件的开发过程得到了广泛采用。面向复用的方法依赖于存在大量可复用的软件组件以及能组合这些组件的集成框架。有时,这些组件本身就是一个系统(例如COTS,即商业现货系统),它能提供专门的功能,例如字处理或制表软件。
用于面向复用过程的软件组件有三种类型:一种组件类型是通过标准服务开发的Web服务,可用于远程调用;另一种组件类型是对象的集合,如.NET或者J2EE等集成在一起作为一个包和组件框架来使用;还有一种组件类型是独立的软件系统,通过配置在特定的环境下使用。
面向复用开发的一般过程模型如图1-25所示,尽管初始需求描述阶段和有效性验证阶段与其他过程差不多,但是面向复用过程的中间阶段是不一样的,下面将这几个中间阶段的工作简单描述如下。
图1-25 面向复用的软件开发模型
(1)组件分析
在组件分析阶段先给出需求描述,然后搜寻能满足需求的组件。很多情况下没有正好合适的组件供选择,因而得到的组件往往只能提供所需要的部分功能。
(2)需求修改
在这个阶段,先根据得到的组件信息分析需求,然后修改需求以反映可得到的组件。当需求修改无法做到的时候,就需要重新进入组件分析活动以搜索其他可能的替代方案。
(3)使用复用的系统设计
在这个阶段,设计系统的框架或者重复使用一个已存在的框架。设计者分析那些将被重复使用的组件,并组织框架使之适应这些组件。当某些可复用的组件不能得到时,必须重新设计一些新的组件。
(4)开发和集成
当组件不能买到时,就需要自己开发,然后集成这些自己开发的组件和现货组件,使它们成为一个整体。在这个模型中,系统集成虽然是一项独立的活动,但它已经成为软件开发过程的一个部分。
从上述描述可以看出,面向复用模型的明显优势是它减少了开发软件的工作量,使用该模型不但可以降低软件开发成本,也可以降低开发中的风险,同时也可使软件快速地交付。该模型的缺点是需求妥协不可避免,而这可能会导致一个不符合用户真正需要的系统。此外,对系统进化的控制也将失效,因为可复用的组件新版本可能是不受机构控制的。
6.形式化方法模型
形式化方法模型是一种严格的软件工程方法,是一种强调正确性的数学验证和软件可控性认证的软件过程模型,其目标和结果是使软件的出错率非常低,这是其他方法所难以达到的。图1-26为形式化方法模型的一种,称为净室过程模型。由于形式化方法模型使用很费时且昂贵,因而应用较少。
图1-26 一种形式化方法模型——净室过程模型
7.第四代技术模型
第四代技术(4th Generation of Technology,4GT)包含了一种组件工具,它们都具有共同点,能使开发人员在较高的级别上规约软件的某些特征,并把这些特征自动生成源代码。
目前,支持4GT模型的软件开发环境包括以下各部分和全部工具:数据库查询的非过程性语言、报表生成、数据处理、屏幕交互和定义、代码生成、高层图形、电子表格、以及使用HTML和用于Web站点的工具等。这些工具都很适用,但都局限于一些专门的应用领域。现在,还没有一种4GT环境能够同时方便地使用上面所介绍的各类应用软件。软件工程的4GT模型如图1-27所示,目前,围绕该模型的应用还有很多争论。支持者认为,它可以极大地减少开发时间,提高软件开发效率;反对者认为,目前的4GT工具并不比编程语言容易,同时使用这样的工具生成的源代码效率不高,特别是用4GT开发大型软件系统可维护性很差。
4GT已经成为一种重要的软件工程方法,当它与CBD方法结合起来时,可能会成为软件开发的主流方法。
图1-27 4GT模型
8.混合模型
每种软件生存周期模型都不是十全十美的,要让它们适应各种项目的开发和各种情况的需要也是很难的。为此,可开发混合模型(Hybrid Model),如图1-28即为一个混合模型。开发混合模型的目的是为了发挥各自模型的优势,对于具体开发组织也可使用2~3种不同的模型组成一个较实用的混合模型,以便获得最大的效益。
图1-28 一个混合软件生存期模型的例子
1.4 实用案例
现实中的软件系统千千万万,软件开发方式也千差万别,同一个问题不同的开发组织可能会选择不同的开发模型去解决,开发出的软件系统也不会完全一样,但是基本目标都是一样的,那就是应该满足用户的基本功能要求,否则,再好的系统也是没有意义的。以下两个案例一个是读者都熟悉的业务活动的出卷系统,另一个是伴随互联网广泛应用后出现的家庭安全住宅系统。
1.4.1 出卷系统的开发模型选择
某学校要开发一个出卷系统,以整体提高考试出卷的客观性、规范性和科学性,提高试卷质量和管理水平,该系统可完全自动、也可以自动和手动结合、还可以完全手动出卷。
该系统其实是将以前人工工作计算机化,表面上看起来比较简单,但当认真考虑后却发现有很多约束,例如,一张卷子不能有重复的题目,连续几年(可根据需要设定年限)不能有重复试卷和试题,根据考试时间确定题量,确定各种类型考题的比例及分值,根据各类型总分及题量确定各小题的分值等等。为了建立实用的出卷系统,需要做很多非开发方面的工作,例如,一门课的题目数至少要满足某个最低限,如大于1000道题,一门课的试卷数不少于20份等等。如果试卷太少、题量太小,则开发出的系统不具有实用性。
系统的功能结构如图1-29所示。主模块应提供课程选择、联机帮助等功能,用户可根据需要选择调用“试卷管理”子系统、“题库管理”子系统、“在线考试”子系统或“系统维护”子系统。
图1-29 出卷系统的功能结构要求
“试卷管理”子系统主要包括试卷录入、试卷修改、试卷选择及试卷删除4项功能。
“题库管理”子系统主要包括试题追加、试题修改、试题组卷及试题删除4项功能。
“在线考试”子系统可包括“成绩管理”及“成绩分析”两个下级模块。“成绩管理”模块可为学籍管理系统提供规范的成绩,或直接将成绩写入学籍库中,也可打印成绩单,对成绩排名,转换成学分绩,对不及格的学生给出报警等等;“成绩分析”模块可自动生成考试成绩分析表,可根据需要给出定量的数据,如最高分、最低分、平均分、优秀人数及比例、良好人数及比例、中等人数及比例、及格人数及比例、不及格人数及比例,可给出饼图、柱图等,也可根据评价规则给出定性评语,如试卷的总体评价、学生掌握基本理论情况分析、学生灵活运用知识、分析、解决问题能力情况分析、存在问题分析、今后改进意见等。
“系统维护”子系统可包括课程维护及用户维护等,可根据需求分析的结果来确定其功能,在软件设计阶段确定软件结构。
系统可以统一建库,也可以按课程建库,系统应建立课程名称库、每门课程的试题库以及试卷库等。为便于组卷,可将试题按难度分为难、中、易3类;试题类型一般应有是非题、选择题、分析题、综合题、出题时间、使用时间,每个题目都应该有唯一的编号、覆盖的知识点、答案和难度,在试题录入时系统应能提供图形和文字编辑功能。
这是用户非常熟悉的业务活动,需求、目标、功能都很明确,建议采用规范的瀑布模型进行开发。
1.4.2 住宅安全系统SafeHome的开发模型选择
该案例从美国软件工程专家Roger S.Pressman所著《软件工程:实践者的研究方法》一书中整理而来。一家专门开发家用和商用消费产品的公司有一个拳头产品——通用的无线盒,只有火柴盒大小,可以把它放在各种传感器上,放在任何电子产品中,比如数码相机里,可以通过无线连接获得它的输出。利用这一拳头产品,他们计划开发一个住宅安全系统SafeHome,该产品采用新型无线接口,给家庭和小型商务使用者提供一个由计算机控制的系统——家庭安全、监视、应用和设备控制。例如,你可以在回家的路上关闭家里的空调,或者诸如此类的家电。该公司的工程部已经做了相关的技术可行性研究,该产品可行且制造成本不高,由于所需的大多数硬件可以在市场上购买到成品,因而SafeHome系统的主要工作是软件开发。在美国,70%的家庭拥有计算机。如果该产品开发成功且价格合理,那么将会有广阔的市场前景。到目前为止,只有该公司拥有这一无线控制盒技术,而且将在这个方面保持两年的领先地位。以下是在该公司软件工程部会议室开会讨论开发模型的选择过程。
1.第一次会议简况
会议主要成员:项目经理Lee Warrer,软件工程经理Doug Miller,软件团队成员Jamie Lazar、Vinod Raman和Ed Robbins。
Lee:正如我们现在所看到的,我已经花了很多时间讨论SafeHome产品的产品线。毫无疑问,我们做了很多工作定义这个东西,我想请各位谈谈你们打算如何做这个产品的软件部分。
Doug:看起来,我们过去在软件开发方面相当混乱。
Ed:Doug,我不明白,我们总是能成功开发出产品来。
Doug:你说的是事实,不过我们的开发工作并不是一帆风顺,并且我们这次要做的项目看起来比以前做的任何项目都要大而且更复杂。
Jamie:没有你说的那么严重,但是我同意你的看法。我们过去混乱的项目开发方法这次行不通了,特别是这次我们的时间很紧。
Doug:我希望我们的开发方法更专业一些,我们现在需要一个过程。
Jamie:我的工作是编程,不是文书。
Doug:在你反对我之前,请先尝试一下。我想说的是,似乎瀑布模型并不适合我们,……它假设我们此刻明确了所有的需求,而事实上并不是这样。
Vinod:同意你的观点,瀑布模型太IT化了……,也许适合于开发一套库存管理系统或者什么,但是不适合我们的SafeHome产品。
Doug:对。
Ed:从原型开发模型的特点来看,正适合我们现在的处境。
Vinod:有个问题,我担心用原型开发方法不够规范。
Doug:别怕,我们还有许多其他选择。我希望在座的各位选出最适合我们小组和我们这个项目的开发模型。
2.第二次会议简况
会议主要成员:项目经理Lee Warrer,软件工程经理Doug Miller,软件团队成员Jamie Lazar和Vinod Raman。
Doug首先介绍了一些可选的演化模型,比较了它们各自的特点。
Jamie:我现在有了一些想法,增量模型挺有意义的,我也很喜欢螺旋模型,听起来很实用。
Vinod:我赞成用增量模型。我们先交付一个增量产品,听取用户的反馈意见,再重新计划,然后交付另一个增量。这样做也符合产品的特性。我们能够迅速投入市场,然后在每个版本或者说在每个增量中添加功能。
Lee:等等,Doug,你的意思是说我们在螺旋的每一轮都重新生成计划?这样不好,我们需要一个计划,一个进度,然后严格遵守这个计划。
Doug:你的思想太陈旧了,Lee,就像他们说的,我们要现实。我认为,随着我们认识的深入和情况的变化来调整计划更好。这是一种更符合实际的方式。如果制定了不符合实际的计划,这个计划还有什么意义?
Lee:我同意这种看法,可是高管人员不喜欢这种方式,他们喜欢确定的计划。
第三次会议他们达成了共识,决定采用增量模型开发SafeHome产品软件。
1.5 小结
计算机软件是计算机系统的主要组成部分,它包括程序、数据、文档、方法、规则等,软件主要有系统软件、应用软件、工具软件和可重用软件4类。软件工程是集成计算机软件开发的过程、方法和工具的学科,是针对软件危机而发展起来的一门学科。软件的生命周期是一个重要的概念,是指从软件计划开始直到软件被弃为止的所有阶段,
软件开发模型也称为软件生存期模型,它是反映软件开发过程、开发活动和开发任务的结构框架,实际进展中允许进行改进或适当的变化,它是指导我们进行软件开发的一个宏观框架,不能被它完全束缚。
软件生存期模型目前虽有十余种,但常用的只有几种,使用最多的仍然是瀑布模型,它是其他模型的基础。
1.6 习题
1.如何理解软件概念,简述软件有哪些分类方法?
2.简述以下概念。
1)系统软件。
2)应用软件。
3)工具软件。
4)可重用软件。
3.解释下列软件的特点。
1)嵌入式软件。
2)产品线软件。
3)人工智能软件。
4.软件的发展经历了哪几个阶段?简述各阶段名称及特点。
5.什么是软件危机,主要有哪些表现?
6.美国IBM公司的OS/360项目总负责人费雷德里克·布鲁克斯(Frederick P.Brooks Jr.)写过一本计算机界人人皆知的名著,该名著的名称是什么?
7.简述软件工程的起源。
8.计算机系统的成本是由硬件决定还是由软件决定?
9.下列哪个概念是1968年在德国小镇加米施(Garmisch)召开的北大西洋公约组织(简称NATO)学术会议上与会学者们首次提出的。
软件工程、互联网、云计算、物联网、大数据
10.简述Roger S.Pressman的软件工程层次化定义。
11.为什么说软件工程是一门多学科交叉的学科?
12.简述北京大学王立福教授等给出的软件工程定义。
13.什么是软件的生命周期?
14.给出瀑布模型的基本形式,简述它的特点。
15.给出喷泉模型的图示表示,它是描述什么开发过程的模型,喷泉模型的特点是什么?16.螺旋模型的特点是什么?典型的螺旋模型有几个任务区域,试给出一种螺旋模型的图示表示。
17.说出面向复用的软件开发模型的主要步骤,简述该模型的主要特点。
18.演化模型又称作什么模型?说出几种演化模型的形式,说出演化模型的主要优点和缺点。19.常见的软件生存期模型主要有哪些?给出名称。
20.按照软件生命周期顺序,对下列任务进行排序。
1)交付软件项目开发计划。
2)制定软件测试计划。
3)获取需求。
4)编写需求。
5)估算软件开发成本、进度、工作量。
6)预测开发软件所需要的资源。
7)管理软件风险。
8)安排软件开发进度。
9)评审软件项目计划。
10)分析需求。
11)确定待开发软件系统的工作范围。
12)协商需求。
13)管理需求。
14)审查需求。
15)编写软件需求规格说明(SRS)。
16)评审SRS。
17)编写设计规格说明(即软件设计说明书)。
18)评审设计规格说明。
19)设计软件体系结构。
20)设计数据结构。
21)描述软件过程。
22)编写程序代码。
23)进行确认测试。
24)进行软件调试。
25)进行单元测试。
26)进行系统测试。
27)进行集成测试。
28)撰写软件测试报告。
29)评审软件测试计划。
30)评审软件测试报告。
21.常见的软件维护有哪几种类型,各占维护工作量的百分比是多少?
22.在案例2中,为什么SafeHome产品软件不采用瀑布模型?