1.3 软件工程的基本概念
1.3.1 什么是软件工程
所谓的“工程”,就是创造性地运用科学原理设计和实现建筑、机器、装置或生产过程,或者是在实践中使用一个或多个这些实体,或者是实现这些实体的过程。
远古时期,人们互相协作建造了不少工程奇迹,比如希腊雅典的帕特农神庙、古罗马帝国的罗马水道、中国的长城等。我们可以想象这些工程在设计和建造的过程中一定涉及了大量的计算、计划、各类角色的协作,以及成百上千的人、动物、机械经年累月的劳作。这些因素在后来出现的诸如化学工程、土木工程等各类“工程”中依然存在。
顾名思义,软件工程就是把工程化的方法应用到软件之中,是一门研究如何用系统化、规范化、数量化等工程原则和方法去进行软件的开发和维护的学科。人们曾经对“软件工程”给过许多定义,下面是两个比较典型的。
1968年NATO会议上首次提出:“软件工程是为了经济地获得可靠的和能在实际机器上高效运行的软件,而建立和使用完善的工程原理。”这个定义不仅指出了软件工程的目标是经济地开发出高质量的软件,而且强调了软件工程是一门工程学科,它应该建立并使用完善的工程原理。
1993年IEEE进一步给出了一个更全面更具体的定义:“软件工程是①将系统化的、规范的、可度量的方法应用于软件的开发、运行和维护的过程,即将工程化应用于软件中;②对①中所述方法的研究。”
美国南加州大学的巴里·贝姆(Barry Boehm)教授总结了国际上软件工程的发展历程: 20世纪50年代的类似硬件工程(Hardware Engineering)、60年代的软件手工生产(Software Crafting)、70年代的形式化方法和瀑布模型(Formality and Waterfall Processes)、80年代的软件生产率和可扩展性(Productivity and Scalability)、90年代的软件并发和顺序进程(Concurrent vs.Sequential Processes)以及21世纪初的软件敏捷性和价值(Agility and Value)。我国北京大学杨芙清院士也系统地回顾了起步于1980年的中国软件工程的研究与实践,代表性工作包括软件自动化系统、XYZ系统4、MLIRF系统和青鸟工程等,都在国内外有广泛的影响。
总的来说,软件工程包括软件开发技术和软件项目管理两方面内容。其中,软件开发技术包括软件开发方法学、软件工具和软件工程环境,软件项目管理包括软件度量、项目估算、进度控制、人员组织、配置管理、项目计划等。
1.3.2 软件工程的基本要素
软件工程是相当复杂的。涉及的因素很多,不同软件项目使用的开发方法和技术也是不同的,而且有些项目的开发无现成的技术,带有不同程度的试探性。一般说来,软件工程包含方法(methodologies)、工具(tools)和过程(procedures)三个关键元素。
软件方法提供如何构造软件的技术,包括与项目有关的计算和各种估算、系统和软件需求分析、数据结构设计、程序体系结构、算法过程、编码、测试以及维护等内容。软件工程的方法通常引入各种专用的图形符号以及一套软件质量的准则。概括地说,软件工程方法规定了明确的工作步骤与技术、具体的文档格式、明确的评价标准。
软件开发方法(见图1-2)的发展经历了面向过程、面向对象、面向构件和面向服务4个阶段。
图1-2 软件开发方法
(1)面向过程。以算法作为基本构造单元,强调自顶向下的功能分解,将功能和数据进行一定程度的分离。
(2)面向对象。以类为基本程序单位,对象是类的实例化,对象之间以消息传递为基本手段。
(3)面向构件。寻求比类的粒度更大且易于复用的构件,期望实现软件的再工程。
(4)面向服务。在应用表现层次上将软件构件化,即应用业务过程由服务组成,而服务由构建组装而成。
代码封装的力度从函数到类,再到粒度更大的构件以及在应用表现层次上的服务,软件的复用程度逐步提升,开发效率也越来越高。
软件工具是人类在开发软件的活动中智力和体力的扩展和延伸,为方法和语言提供自动或半自动化的支持。软件工具最初是零散的,后来根据不同类型软件项目的要求建立了各种软件工具箱,支持软件开发的全过程。更进一步,人们将用于开发软件的软、硬件工具和软件工程数据库(包括分析、设计、编码和测试等重要信息的数据结构)集成在一起,建立集成化的计算机辅助软件工程(Computer-Aided Software Engineering)系统,简称CASE。
现在开源的工具非常多,贯穿于整个开发过程。具体来说,软件建模工具可以支持建立系统的需求和设计模型;软件构造工具包括程序编辑器、编译器、解释器和调试器;软件测试工具可以帮助人们分析代码质量,执行软件测试和评价产品的质量;在软件维护阶段,一些代码分析工具和重构工具,可以帮助人们理解和维护代码。除此之外,还有一些软件工程管理工具,帮助人们有效管理开发过程,控制代码的更改,支持团队进行协作开发。
软件过程贯穿于软件开发的各个环节,它定义了方法使用的顺序、可交付产品(文档、报告以及格式)的要求、为保证质量和协调变化所需要的管理以及软件开发过程各个阶段完成的标志。
软件开发过程一般包括一系列基本的开发活动,这些活动将用户的需求转化为用户满意的产品。通过对开发过程中各个活动环节质量的有效控制,来保证最终产品的质量。首先要研究和定义用户的问题;确定和分析用户的实际需求;设计整个系统的总体结构;编程实现系统的各个部分;最后,将各个部分集成起来进行测试,最终交付出用户满意的产品。除此之外,还应该包括一些开发过程管理等支持性的活动。
从内容上说,软件工程包括软件开发理论和结构、软件开发技术以及软件工程管理和规范。其中,软件开发理论和结构包括程序正确性证明理论、软件可靠性理论、软件成本估算模型、软件开发模型以及模块划分原理,软件开发技术包括软件开发方法学、软件工具以及软件环境,软件工程管理和规范包括软件管理(人员、计划、标准、配置)以及软件经济(成本估算、质量评价)。即软件工程可分为理论、结构、方法、工具、环境、管理、何规范等。理论和结构是软件开发的基础;方法、工具、环境构成软件开发技术,好的工具促进方法的研制,好的方法能改进工具;工具的集合构成软件开发环境;管理是技术实现与开发质量的保证;规范是开发遵循的技术标准。
软件工程几十年的发展,已经积累了许多开发方法。但是仅有好的战术是不够的,还需要在实践中运用良好的开发策略。软件复用、分而治之、逐步演进和优化折中,是软件开发的四个基本策略。
(1)软件复用。构造一个新的系统,不必都从零开始。可以将已有的软件制品,直接组装或者合理修改形成新的软件系统,从而提高开发效率和产品质量,降低维护成本。软件复用也不仅仅是代码的复用,还包括对系统类库、模板、设计模式、组件和框架等的复用。
(2)分而治之。是人们处理复杂性的一个基本策略。通过对问题进行研究分析,将一个复杂的问题分解成若干个可以理解并能够处理的小问题,然后逐个予以解决。
(3)逐步演进。软件更像是一个活着的植物,其生长是一个逐步有序的过程。软件开发应该遵循软件的客观规律,不断进行迭代式增量开发,最终交付符合客户价值的产品。
(4)优化折中。软件工程师应当把优化当成一种责任,不断改进和提升软件质量。但是优化是一个多目标的最优决策,在不可能使所有目标都达到最优时,需要进行折中来实现整体的最优。
Wasserman 规范给出了对软件工程发展有重大影响的若干技术,这些技术分别是抽象、软件建模方法、用户界面原型化、软件体系结构、软件过程、软件复用、度量、工具和集成环境。其中,抽象是一种降低复杂性的处理方法;软件建模方法可以帮助工程师理解和刻画系统的分析和设计结果,便于开发人员进行沟通和交流;用户界面原型化可以克服需求难以确定的困难;软件体系结构对产品质量是至关重要的;软件过程、软件复用和度量都是工程方法的组成部分;工具和集成环境对于提高软件开发效率是必不可少的。
Wasserman 指出,上述八个技术变化中的任何一个都对软件开发过程有着重大的影响,它们合在一起,改变了我们的工作方式。
在软件工程中,软件的可靠性是软件在所给条件下和规定时间内,能完成所要求的功能的性质。软件工程的软件可靠性理论及其评价方法,是贯穿整个软件工程各个阶段所必须考虑的问题。
软件工程的目标在于研究一套科学的工程化方法,并与之相适应,发展一套方便的工具与环境,供软件开发者使用。
1.3.3 软件工程的基本原理
自从1968年提出“软件工程”这一术语以来,研究软件工程的专家学者们陆续提出了许多关于软件工程的准则或信条。美国著名的软件工程专家 Boehm 综合这些专家的意见,并总结了TRW公司多年的开发软件的经验,于1983年提出了软件工程的七条基本原理。
Boehm认为,这七条基本原理是确保软件产品质量和开发效率的原理的最小集合。它们是相互独立的,是缺一不可的最小集合;同时,它们又是相当完备的。下面简要介绍软件工程的七条基本原理。
1.用分阶段的生命周期计划严格管理
这一条是吸取前人的教训而提出来的。统计表明,50%以上的失败项目是由于计划不周而造成的。在软件开发与维护的漫长生命周期中,需要完成许多性质各异的工作。这条原理意味着,应该把软件生命周期分成若干阶段,并相应制定出切实可行的计划,然后严格按照计划对软件的开发和维护进行管理。Boehm 认为,在整个软件生命周期中应指定并严格执行项目概要计划、里程碑计划、项目控制计划、产品控制计划、验证计划、运行维护计划六类计划。
2.坚持进行阶段评审
统计结果显示,大部分错误是设计错误,大约占63%;错误发现得越晚,改正它要付出的代价就越大,相差大约2到3个数量级。因此,软件的质量保证工作不能等到编码结束之后再进行,应坚持进行严格的阶段评审,以便尽早发现错误。
3.实行严格的产品控制
开发人员最痛恨的事情之一就是改动需求。但是实践告诉我们,需求的改动往往是不可避免的。这就要求我们要采用科学的产品控制技术来顺应这种要求,也就是要采用变动控制,又叫基准配置管理。当需求变动时,其他各个阶段的文档或代码随之相应变动,以保证软件的一致性。
4.采纳现代程序设计技术
从20世纪六七十年代的结构化软件开发技术到最近的面向对象技术,从第一、第二代语言到第四代语言,人们已经充分认识到:方法比气力更有效。采用先进的技术既可以提高软件开发的效率,又可以减少软件维护的成本。
5.结果应能清楚地审查
软件是一种看不见、摸不着的逻辑产品。软件开发小组的工作进展情况可见性差,难以评价和管理。为更好地进行管理,应根据软件开发的总目标及完成期限,尽量明确地规定开发小组的责任和产品标准,以使所得到的标准能清楚地审查。
6.开发小组的人员应少而精
开发人员的素质和数量是影响软件质量和开发效率的重要因素,开发人员应该少而精。这一条基本原理基于两点原因:高素质开发人员的效率比低素质开发人员的效率要高几倍到几十倍,开发工作中犯的错误也要少得多;当开发小组为N人时,可能的通信信道为N(N-1)/2,可见随着人数N的增大,通信开销将急剧增大。
7.承认不断改进软件工程实践的必要性
遵从上述七条基本原理,就能够较好地实现软件的工程化生产。但是,它们只是对既有经验的总结和归纳,并不能保证赶上技术不断前进发展的步伐。因此,Boehm提出应把承认不断改进软件工程实践的必要性作为软件工程的第七条基本原理。根据这条原理,不仅要积极采纳新的软件开发技术,还要注意不断总结经验,收集进度和消耗等数据,进行出错类型和问题报告统计。这些数据既可以用来评估新的软件技术的效果,也可以用来指明必须着重注意的问题及应该优先进行研究的工具和技术。