1.1 软件
1.1.1 软件的概念及特点
人们通常把具有各种功能的程序,包括系统程序、应用程序、用户自己编写的程序等称为软件。然而,随着计算机应用的日益普及,软件日益复杂,规模日益增大,人们意识到软件并不仅仅包含程序。
程序是人们为了完成特定的功能而编制的一组指令集,它由计算机的语言描述,并且能在计算机系统上执行。而软件不仅包括程序,还包括程序的处理对象——数据,以及与程序开发、维护和使用有关的图文资料(文档)。例如,用户购买的Windows 11操作系统软件,不仅包含可执行的程序,还包含一些支持数据(一般放在计算机的硬盘或网络的服务器中),并且还包含纸质的用户手册等文档。根据电气电子工程师协会(Institute of Electrical and ElectronicsEngineers,IEEE)610.12-1990标准,软件被定义为“计算机程序、过程、规则和相关文档的集合,以及与计算机系统的运行和维护相关的数据”。软件工程专家罗杰·S.普莱斯曼(Roger S.Pressman)对软件给出了这样的定义:计算机软件是由专业人员开发并长期维护的软件产品。完整的软件产品包括在各种不同容量和体系结构的计算机上的可执行的程序、运行过程中产生的各种结果,以及以硬复制或电子表格等多种方式存在的软件文档。
软件具有以下几个特点:
(1)软件是一种逻辑实体 而不是具体的物理实体,因而它具有抽象性。
(2)软件的生产与硬件的生产不同,它没有明显的制造过程。要提高软件的质量,必须在软件开发方面下功夫。
(3)软件在运行和使用期间,不会出现硬件中所出现的机械磨损、老化问题。然而它存在退化问题,必须要对其进行多次修改与维护,直至其退役,如早期的DOS(Disk OperatingSystem,磁盘操作系统),就进行了多次修改与维护,仍难以匹敌Windows操作系统而没落的。
图1-1和图1-2分别展示了硬件的失效率和使用时间的关系。以及软件的失效率和使用时间的关系。
(4)计算机应用的开发与运行常常受到计算机系统的制约,不同应用对计算机系统有着不同程度的依赖性,如有专门针对个人计算机(Personal Computer,PC)的游戏,也有针对平板电脑的游戏。为了降低这种依赖性,人们在软件开发中提出了软件移植的概念。
(5)
(6)软件本身是复杂的。软件的复杂性可能来自它所反映的实际问题的复杂性,也可能来自程序逻辑结构的复杂性。
(7)软件研制成本相当高。软件的研制工作需要投入大量的、复杂的、高强度的脑力劳动,它的成本是比较高的。
(8)相当多的软件工作涉及社会因素。许多软件的开发和运行涉及机构、体制、管理方式等方面的问题,它们直接决定了软件项目的成败。
1.1.2 软件的分类
随着计算机软件复杂性的增加,在某种程度上人们很难针对软件给出一个通用的分类标准,但是人们可以从不同的角度对软件进行分类。
(1)按照软件功能的不同,软件可以分为系统软件、支撑软件和应用软件3类。 系统软件是计算机系统中最靠近硬件的一层,为其他程序提供底层的系统服务,它与具体的应用领域无关,系统软件有编译程序和操作系统等支撑软件以系统软件为基础,以提高系统性能为主要目标,支撑应用软件的开发与运行,主要包括环境数据库)各种接口软件利工具组3应用软件是提供特定应用服务的软件,如字处理程序等。系统软件、支撑软件和应用软件之间既有分工又有合作,是不可以截然分开的。
(2)根据软件服务对象的不同,软件可以分为通用软件和定制软件通用软件是由特定的软件开发机构开发、面向市场公开发行的独立运行的软件系统,例如操作系统、文档处理系统和图片处理系统等。定制软件通常是面向特定的用户需求,由软件开发机构在合同的约束下开发的软件,如为企业定制的办公系统、交通管理系统和飞机导航系统等。
(3)按照软件产品规模的不同,软件可以分为微型 小型中型 大型 和超大型软件。一般情况下,微型软件只需要一名开发人员,在4周以内完成开发,并且代码量不超过500行,这类软件一般仅供个人专用,没有严格的分析、设计和测试资料,例如某个学生为完成“软件工程”课程的作业而编制的程序,就属于微型软件。小型软件开发周期在半年内,代码量一般控制在5000行以内,这类软件通常没有预留与其他软件的接口,但是需要遵循一定的标准,附有正规的文档资料。例如某个学生团队为完成“软件工程”课程的大作业(学期项目)而编制的程序,就属于小型软件 。中型软件的开发人员控制在10人以内,要求在2年以内开发5000~50000行代码,这种软件的开发不仅需要完整的计划、文档及审查,还需要开发人员之间,开发人员和用户之间的交流与合作,例如某个软件公司为某个客户开发的办公自动化(Office Automation, OA)系统而编制的程序,就属于中型软件 。大型软件是10~100名开发人员在1~3年的时间内开发的,具有50000~100000行(甚至上百万行)代码的软件产品,在这种规模的软件开发中,统一的标准、严格的审查制度及有效的项目管理都是必需的,例如某个软件公司开发的某款多人在线的网络游戏,就属于大型软件。超大型软件往往涉及上百名甚至上千名成员的开发团队,开发周期可以为3年以上,甚至5年,这种大规模的软件项目通常被划分为若干个小的子项目,由不同的团队开发,例如微软公司开发的Windows 11操作系统,就属于超大型软件
(4)按照工作方式的不同,计算机软件可以分为实时软件、分时软件、交互式软件和批处理软件。实时软件能够在严格的时间限制下进行实时处理和响应,通常用于需要及时响应和处理事件的系统,如航空航天、工业自动化、交通控制、医疗设备等领域的系统。分时软件指的是一种操作系统或程序设计技术,将处理器时间片分配给不同的用户或任务,以实现多用户共享计算资源的目的。交互式软件是一种能够与用户进行实时交互的软件。与传统的批处理软件不同,交互源的目的。交互式软件是一种能够与用户进行实时交互式软件允许用户通过输入指令或在操作界面与软件进行实时的交互和反馈。常见的交互式软件句括文字处理软件、电子表格软件、图像编辑软件、游戏软件等。批处理软件是一种能够自动执行一系列预定义任务的软件。与交互式软件不同,批处理软件通常不需要用户的实时交互,而是按照预先设定的顺序和规则自动执行任务。
(5)按照源代码是否公开,软件可以分为开源软件和闭源软件。开源软件是指可以免费获取、使用、修改和分发的软件,它的源代码是公开的,任何人都可以查看、修改和重新分发。开源软件通常遵循开放的许可证,这些许可证确保了用户对软件的自由使用和修改的权利。闭源软件是指其源代码不公开的软件,闭源软件的源代码只有软件的开发者或授权人可以查看和修改,普通用户无法访问或修改源代码。
此外,还有很多软件的归类是交叉的,如关键基础软件、大型工业软件、新型平台软件、安全可靠软件、嵌入式软件、群体软件、智能软件等。
软件的分类示意如图1-3所示。
1.2 软件危机
1.2.1 软件危机的表项与产生原因
软件危机是指人们在开发软件和维护软件过程中所遇到的一系列的问题。在20世纪60年代中期,随着软件规模的扩大、复杂性的增加、功能的增强,开发高质量的软件越来越困难。在软件开发的过程中,经常会出现不能按时完成任务、产品质量得不到保证、工作效率低下和开发经费严重超支等现象。这些现象逐渐使人们意识到软件危机的存在。计算机软件的开发、应用和维护过程中普遍出现的一些严重的问题,主要表现如下:
(1)开发出来的软件产品不能满足用户的需求,即产品的功能或特性与需求不符。这主要是由千开发人员与用户之间不能充分、有效地交流,开发人员对用户需求的理解存在差异。相比越来越廉价的硬件,软件代价过高。
(2)软件质量难以得到保证,且难以发挥硬件潜能。开发团队缺少完善的软件质量评审体系以及科学的软件测试规程,使得最终的软件产品存在诸多缺陷。
(3)难以准确估计软件开发、维护的费用以及开发周期。软件产品往往不能在预算范围之内按照计划完成开发。在很多情况下,软件产品的开发周期或经费会大大超出预算。
(4)难以控制开发风险,开发速度赶不上市场变化。
(5)软件产品修改和维护困难,集成遗留系统更困难。
(6)软件文档不完备,并且存在文档内容与软件产品不符的情况。
软件危机的出现及其日益严重的趋势充分暴露了软件产业在早期的发展过程中存在的各种各样的问题。可以说,人们对软件产品认识的不足以及对软件开发的内在规律理解的偏差是软件危机出现的根本原因。
具体来说,软件危机出现的原因可以概括为以下几点。
①忽视软件开发前期的需求分析
②开发过程缺乏统一的、规范化的方法论的指导。软件开发是一项复杂的工程,人们需要用科学的、工程化的思想来组织和指导软件开发的各个阶段。而这种工程学的视角正是很多软件开发人员所没有的,他们往往简单地认为软件开发就是程序设计。
③文档资料不齐全或不准确。软件文档没有得到软件开发人员和用户的足够重视。软件文档是软件开发团队成员之间交流和沟通的重要平台,还是软件开发项目管理的重要工具。如果人们不重视软件文档,势必会给软件开发带来很多不便。
④忽视与用户之间、开发团队成员之间的交流。
⑤忽视测试的重要性。
⑥不重视维护或由于上述原因造成维护工作困难由于软件的抽象性和复杂性,软件在运行之前,软件开发人员很难对开发过程的进展情况进行估计,再加上软件错误的隐蔽性和改正软件错误的复杂性,软件开发和维护在客观上存在一定的难度。
⑦从事软件开发的专业人员对软件产业认识不充分,缺乏经验。软件产业相较于其他工业产业而言,是一个比较年轻、发展不成熟的产业,人们在对它的认识上缺乏深刻性。
⑧没有完善的质量保证体系。完善的质量保证体系的建立需要有严格的评审制度,同时还需要有科学的软件测试技术及质量维护技术。如果软件的质量得不到保证,开发出来的软件产品往往不能满足人们的需求,同时人们还可能需要耗费大量的时间、资金和精力去修复软件的缺陷,从而导致软件质量的下降和开发预算超支等后果。
1.2.2 软件危机的启示
软件危机给我们的最大启示,是我们应更加深刻地认识到软件的特性以及软件产品开发的内在规律。
①软件产品是复杂的人造系统,具有复杂性、不可见性和易变性,难以处理。
②个人或小组在开发小型软件时使用到的非常有效的编程技术和过程,在开发大型、复杂系统时难以发挥同样的作用。
③从本质上讲,软件开发的创造性成分很大、发挥的余地也很大,很接近于艺术创作。它介于艺术创作与工程制造之间,并逐步向工程制造的一端发展,但很难发展到完全的工程制造。·计算机和软件技术的快速发展,提高了用户对软件的期望水平,促进了软件产品的演化,对软件产品提出了新的、更多的需求,所以软件开发人员难以在可接受的开发进度内保证软件的质量。
④几乎所有的软件项目都是新的,而且是不断变化的。项目需求在开发过程中会发生变化,而且很多原来预想不到的问题会出现,对设计和实现手段进行适当的调整是不可避免的。“人月神化”现象——生产力与人数并不成正比。
为了解决软件危机,人们开始试着用工程化的思想去指导软件开发,于是软件工程诞生了。
1.3软件工程
1.3.1软件工程的概念
1968年,在北大西洋公约组织举行的一次学术会议上,该组织的科学委员们在开会讨论软件的可靠性与软件危机的问题时,首次提出了“软件工程”的概念,并将其定义为“为了经济地获得可靠的和能在实际机器上高效运行的软件,而建立和使用的健全的工程规则”。这一定义肯定了工程化的思想在软件工程中的重要性,但是并没有提到软件产品的特殊性。
经过50多年的发展,软件工程已经成为一门独立的学科,人们对软件工程也逐渐有了更全面、更科学的认识。
IEEE对软件工程的定义为:①将系统化的、严格约束的、可量化的方法应用于软件的开发、运行和维护,即将工程化应用于软件;②对1中所述方法的研究。
软件工程层次如图1-4所示。
从图1-4可知,软件工程的根基就在于对质量的关注;软件工程的基础是过程层,它定义了一组关键过程区域的框架,使得软件能够被合理和及时地开发:软件工程的方法提供了构造软件在技术上需要“做什么”的指导,它覆盖了一系列的任务,包括需求分析、设计、编程、测试和维护等;软件工程的工具对过程和方法提供了自动或半自动的支持。软件工程本身是一个交叉学科等领域,涉及多种学科领域的相关知识,包括工程学、数学、计算机科学、经济学、管理学、心理学
软件工程以天注质量为目标,其中过程、方法和工具是软件工程的三要素。
1.3.2软件工程研究的内容
软件工程研究的内容主要包括以下两个部分。
(1)软件开发技术:主要研究软件开发、运行和维护方法、软件开发过程、软件开发工具和环境。
(2)软件开发过程管理:主要研究软件工程经济学和软件管理学。
必须要强调的是,随着人们对软件系统研究的逐渐深入,软件工程所研究的内容也在不断更新和发展。
1.3.3 软件工程的目标和原则
软件工程要达到的基本目标如下。
①实现达到要求的软件功能。
②取得较好的软件性能。
③开发出高质量的软件。
④付出较低的开发成本。
⑤仅需较低的维护费用。
⑥能按时完成开发工作,及时交付使用。
为了达到上述目标,软件工程设计、工程支持以及工程管理在软件开发过程中必须遵循一些基本原则。软件工程专家B.勃姆(B.Boehm)综合了有关专家和学者的意见,并总结了多年来开发软件的经验,提出了软件工程的7条基本原则。
(1)采用分阶段的生命周期计划实行严格的项目管理
将软件的生命周期划分为多个阶段,对各个阶段实施严格的项目管理。软件开发是一个漫长的过程,人们可以根据软件的特点或目标,把整个软件的开发周期划分为多个阶段,并为每个阶段制定分阶段的计划及验收标准,这样有益于对整个软件开发过程进行管理。在传统的软件工程中,软件开发的生命周期可以划分为可行性研究 需求分析 软件设计软件实现。软件测试、产品验收和交付等阶段。
(2)坚持进行阶段评审
严格地贯彻与实施阶段评审制度可以帮助软件开发人员及时地发现错误并将其改正。在软件开发的过程中,错误发现得越晚,修复错误所要付出的代价就会越大。实施阶段评审要求只有在本阶段的工作通过评审后,才能进入下一阶段的工作。
(3)实施严格的版本控制
在软件开发的过程中,用户需求很可能在不断地发生变化。有些时候,即使用户需求没有改变,软件开发人员受到经验的限制以及与客户交流不充分的影响,也很难做到一次性获取全部正确的需求。可见,需求分析的工作应该贯穿到整个软件开发的生命周期内。在软件开发的整个过程中,需求的改变是不可避免的。当需求更新时,为了保证软件各个配置项的一致性,实施严格的版本控制是非常必要的。
(4)采用现代程序设计技术
采用现代的程序设计技术,例如面向对象程序设计技术,可以使开发出来的软件产品更易维护和修改,同时还能缩短开发的时间,并且更符合人们的思维逻辑。
(5)软件产品应能被清楚地审查
虽然软件产品的可见性比较差,但是它的功能和质量应该能够被清楚地审查和度量,这样才能进行有效的项目管理。一般软件产品包括可以执行的源代码、一系列相应的文档和资源数据等。
(6)开发小组的人员应该少而精
开发小组成员的人数少有利于组内成员充分地交流,这是高效团队管理的重要因素。而高素质的开发小组成员是提高软件产品质量和开发效率的重要因素。
(7)持续不断地总结经验、学习新的软件技术
随着计算机科学技术的发展,软件从业人员应该不断地总结经验并主动学习新的软件开发术,只有这样才能不落后于时代。
B.Boehm指出,遵循前6条基本原则,能够实现软件的工程化生产;要遵循第7条原则,我们要积极主动地学习新的软件开发技术,而且要注意不断总结经验。