1.1 软件和软件危机
1.1.1 软件的概念和特点
软件是计算机系统中与硬件相互依存的另一部分,它是包括程序、数据及其相关文档的完整集合。其中,程序是按事先设计的功能和性能要求执行的指令序列;数据是使程序能正常操纵信息的数据结构;文档是与程序开发、维护和使用有关的图文资料。
软件是逻辑部件,相对传统的工业产品,具有其独特性,主要表现在以下方面:
(1)软件是一种逻辑实体,而不是具体的物理实体。因而它具有抽象性。这个特点使它和计算机硬件或其他工程对象有明显的差别。人们可以把它记录在介质上,但却无法看到软件的形态,必须通过观察、分析、思考、判断,去了解它的功能、性能及其他特性。
(2)软件的生产与硬件不同,它没有明显的制造过程。也不象硬件那样,一旦研制成功,可以重复制造,并在制造过程中进行质量控制,以保证产品的质量。而软件是通过人们的智力活动,把知识与技术转化成信息的一种产品。一旦某一软件项目研制成功,就可以大量地复制同一内容的副本。所以控制软件的质量,必须着重在软件开发方面下功夫。
(3)在软件的运行和使用期间,没有硬件那样的机械磨损和老化问题。在软件研制成功后,为了改正软件中的错误和弥补缺陷、提升软件功能和性能、适应环境变化,需要持续对软件进行改进和完善,所以软件的维护比硬件的维护要复杂得多,与硬件的维修有着本质的差别。
(4)软件的开发和运行常常受计算机系统的限制,它对计算机系统有着不同程度的依赖。软件不能完全摆脱硬件单独活动,在软件的开发和运行中必须以硬件提供的条件为依据。有的软件依赖于某个操作系统,为了消除这种依赖性,软件开发人员在软件开发中提出了软件移植的问题,并且把软件的可移植性作为衡量软件质量的因素之一。
(5)软件的开发至今尚未完全摆脱手工艺的开发方式。由于传统的手工艺开发方式仍然占据统治地位,开发的效率自然受到很大的限制。为此,人们在软件技术方面做了许多卓有成效的工作,提出了许多新的开发方法,如充分利用现成软件的复用技术、自动生成技术,也研制了一些有效的软件开发工具或软件开发环境。
(6)软件本身是复杂的。软件的复杂性可能来自它所反映的实际问题的复杂性,也可能来自程序逻辑结构的复杂性。软件开发,特别是应用软件的开发常常涉及其他领域的专业知识,这对软件开发人员提出了很高的要求。
(7)软件成本昂贵。软件的研制工作需要投入大量的、复杂的、高强度的脑力劳动,它的成本比较高。而且,也并非在所有的软件开发都能成功。
(8)许多软件工作涉及社会因素。许多软件的开发和运行涉及机构、体制及管理方式等问题,甚至涉及人们的传统观念和心理问题,这些问题直接影响项目的成败。
1.1.2 软件的发展历程
20世纪40年代中期世界上出现了第一台计算机,自此就有了程序的概念。其后软件经过几十年的发展,经历了3个发展阶段:
(1)程序设计阶段,20世纪40年代至60年代。
(2)程序系统阶段,20世纪60年代至70年代。
(3)软件工程阶段,20世纪70年代以后。
表1.1对3个软件发展阶段的特点进行了比较。
表1.1 软件发展阶段的特点比较
续表
从表 1.1 中可以看到,几十年来软件的根本变化主要体现在以下几个方面:
(1)人们改变了对软件的看法。20世纪50年代到60年代时,程序设计曾经被看成一种任意发挥、创造才能的技术领域。当时人们认为,写出的程序只要能在计算机上得出正确的结果,程序的写法可以不受任何约束。随着计算机的广泛使用,人们要求这些程序容易看懂、容易使用,并且容易修改和扩充。于是,程序便从按个人意图创造的“艺术品”转变为能被广大用户接受的工程化产品。
(2)软件的需求是软件发展的动力。早期的程序开发者只是为了满足自己的需要,这种自给自足的生产方式仍然是其低级阶段的表现。进入软件工程阶段以后,软件开发的成果具有社会属性,它要在市场中流通以满足广大用户的需要。
(3)软件工作的范围发生变化。软件开发从只考虑程序的编写扩展到涉及整个软件生存周期,包括软件的需求分析、设计编码、测试验证、维护等技术工作,以及人员、规模、进度、质量、风险等项目管理内容。
1.1.3 软件危机
在软件技术发展的第二阶段,随着计算机硬件技术的进步,要求软件能与之相适应。然而,软件技术的进步一直未能满足形势发展提出的要求,软件质量得不到保证,软件成本不断上升,软件开发的生产率无法提高。这些问题积累起来,形成了日益尖锐的矛盾,这就导致了软件危机。
早在20世纪60年代末,美国国防部和软件界有关人士首先提出了“软件危机”的警告。软件危机主要体现在以下几个方面:
(1)难以正确估计软件开发的成本和进度,软件研制成为武器装备研制进度延误、研制经费超支和物资浪费的主要因素。
(2)软件质量不高、不可靠,用户经常不满意“已完成”的软件系统。
(3)没有适当的文档来记录软件开发过程中的信息及变化,软件常常不可维护。
(4)软件生产率越来越低等。
长期以来软件危机一直存在,几乎每个重大项目的失败,问题往往都可以归结到风险最高的部件——软件,软件问题已成为引起武器系统交付延迟、系统故障失效的主要原因。美国国防部软件研究计划的负责人回顾 82 个大型军事采办计划时,发现大多数软件研制项目比计划进度推迟约 20 个月完成,推迟项目的数量是非软件密集项目计划的 3 倍,该负责人还说:“国防部由于未能解决软件问题受到了巨大的惩罚,惩罚不仅是软件推出的时间推迟,而且这使作战能力大打折扣。”
软件危机产生的原因,有客观上的,也有主观上的,主要包括以下几个方面:
(1)软件不同于硬件,它是计算机系统的逻辑部件而不是物理部件。在写出程序代码并在计算机上试运行之前,软件开发过程的进展情况较难衡量。很难检验软件开发的正确性,且软件开发的质量也较难评价。因此,控制软件开发过程相当困难。此外,软件维护常常意味着修改原来的设计。这样,维护的费用十分惊人,客观上使得软件较难维护。
(2)软件开发的过程是多人分工合作,分阶段完成的过程,参与人员之间的沟通和配合十分重要。但是,相当多的软件开发人员对软件的开发和维护存在不少错误的观念,在实践过程中没有采用工程化的方法,或多或少采用了一些错误的方法和技术,这是造成软件危机的主要原因。
(3)开发和管理人员只重视开发而轻视问题的定义,使软件产品无法满足用户的要求。对用户的要求没有完整、准确的认识就急于编写程序,这是许多软件开发失败的另一主要原因。事实上,许多用户在开始时并不能准确具体地叙述他们的需要,软件人员需要做大量深入细致的调查研究工作,反复与用户交流信息,才能真正全面、准确地了解用户的要求。
(4)软件管理技术不能满足现代软件开发的需要,没有统一的软件质量管理规范。首先,文档缺乏一致性和完整性,从而失去了管理的依据。因为程序只是完整软件产品的一个组成部分,一个软件产品必须由一系列配置项组成,不能只重视程序还应当特别重视软件配置。其次,由于成本估计不准确、资金分配混乱、人员组织不合理、进度安排无序,导致软件技术无法实施。
(5)在软件的开发和维护关系问题上存在错误的观念。软件维护工作通常是在软件完成之后进行的,任务艰巨复杂,需要花费很大的精力。所以做好软件的定义工作,是降低软件成本,提高软件质量的关键。如果软件开发人员在定义阶段没有正确、全面地理解用户要求,直到测试阶段才发现软件产品不完全符合用户的需要,这时再修改就为时已晚了。另外,在软件生存周期的不同节点进行修改需要花费的精力差异很大。在开发早期引入变更,涉及面较小,付出的代价较低;在开发中期,软件配置的许多成分已经完成,引入一个变更可能需要对所有已完成的配置成分都做相应的修改,不仅工作量大,而且逻辑上更复杂,因而付出的代价剧增。在软件“已完成”后再引入变更,则需要付出更高的代价。因此,必须把软件维护的观念引入软件开发的各个阶段,建立起软件开发与维护的正确关系。
产生软件危机的根源,归结起来主要有4点:
(1)缺乏软件开发的经验和有关软件开发数据的积累,使得开发工作的计划很难制订。主观盲目地制订计划,执行起来和实际情况有很大差距,致使经费预算常常突破。对于工作量估计不准确,进度计划无法遵循,开发工作完成的期限一拖再拖。
(2)软件需求在开发的初期阶段提得不够明确,或是未能得到确切的表达。开发工作开始后,软件开发人员和用户又未能及时交换意见,使得一些问题不能及时解决而隐藏了下来,造成开发后期矛盾集中暴露。
(3)开发过程没有统一的、公认的方法论和规范指导,参加的人员各行其是。加之设计和实现过程的资料很不完整;或忽视软件开发人员的工作接口,发现问题修修补补,使得软件很难维护。
(4)未能在测试阶段充分做好验证确认工作,提交用户的软件质量差,在运行过程中暴露出大量的问题。在应用领域工作的不可靠软件,轻者影响系统的正常工作,重者发生事故,甚至造成生命财产的重大损失。