1.1传统软件开发方法中存在的问题
20世纪60年代以前,软件开发者构造的软件系统的规模大多较小,且构造相对简单。那时所使用的编程语言和编程环境也相对简单,常见的编程语言有汇编语言以及随后出现的一些高级编程语言(如FORTRAN和COBOL等)。当时人们认为软件开发是一项强烈依赖个人技巧和技术能力的艺术性劳动,崇尚程序员的个人技能,没有认识到需要使用什么方法。那时产生的代码,按现在的人们所形容的,是意大利细面条式的,那是因为代码中含有较多的GOTO语句。
随着软件复杂性的增长,那种随心所欲的做法会带来问题,一个典型的问题是代码难以维护。一些高级编程语言试图解决所出现的问题,但这些语言并不能充分解决问题,因为软件开发也需要方法。
随后出现了多种软件开发方法,这些开发方法都能解决一些问题,但也都有一定的局限性。下面对三种典型的开发方法进行简要分析,以找出其中存在的主要问题。
1 功能分解法
早期的一种开发方法称为功能分解法,它是以系统需要提供的功能为中心来开发系统的。它的基本思想为:首先定义顶层功能,然后把功能分解为子功能,同时定义功能之间的接口。对较大的子功能进一步分解,直到可给出明确的定义,进而根据功能/子功能设计数据结构和算法。
在那时,人们都认为功能分解法非常自然,因为它以系统需要提供的功能为中心来组织系统。此外,功能分解法也较好地运用了过程抽象原则。当时,计算机的应用还不是很普及,只有特定的用户有着软件需求,而且要求规模并不是很大。功能分解法的发明,在很大程度上解决了以前存在的问题,开发效率也有了很大的提高。特别是提出了模块化思想,并与模块化编程相结合,使得软件维护更加有效。这些是功能分解法在当时大受欢迎的主要原因。
使用这种以功能为中心的方法开发软件系统,一个显著特点是开始容易深入难。因为一开始按照功能需求进行自顶向下的功能分解是很直接的,但功能和功能接口这些系统成分却不能直接地映射到问题域中的事物,这导致所建立的功能模型难以准确而深入地描述问题域,而且也难以检验所建立的模型的正确性。特别是,该方法对需求变化性的适应能力差:需求的变化必定导致功能模块发生变化,一个功能模块的变化往往引起其接口发生变化,这又致使其他模块发生变化,最终的结果经常是局部的变化导致全局性的影响。
2 结构化方法
结构化方法包括结构化需求分析、设计、编程和测试方法等。结构化需求分析使用数据流图、加工说明和数据字典来构造系统的需求分析模型。结构化需求分析方法比较严谨,使用它可避免很多错误和疏漏。此外,该方法也运用了逐步求精的原则,把加工逐步细化。结构化设计在需求分析的基础上,要针对给定的问题给出软件解决方案。结构化设计中的总体设计部分要给出被建系统的模块结构,详细设计部分要为各模块提供关于算法的详细描述。
结构化方法比功能分解法更强调对问题域的分析,但所使用的建模概念仍然不能直接地映射到问题域中的事物。需求的变化往往会引起相应的加工和数据流的变化,进而影响与之相关的其他加工和数据流的变化。系统复杂时也不能检验分析模型的正确性。此外,结构化需求分析与后续的结构化设计所采用的概念与表示法是不一致的(基于不同的概念体系),且转换规则不严格、具体,仅是指导性的,这致使从需求分析模型过渡到设计模型较为困难。
人们用功能分解法和结构化方法已经开发了很多软件系统,但是同时由于上述原因,对系统的开发与维护问题也日益显现出来。对于功能稳定的应用领域,如某些科学计算,上述方法是适用的。但对于众多的领域而言,它们的需求是易变的,如企业管理和商业管理领域就是如此。因为随着市场的变化,要对这些领域的管理模式不断地进行调整。对于较为复杂的系统,用上述方法进行软件开发,容易导致模块的低内聚和模块间的高耦合,从而使得系统缺乏良好的灵活性和可维护性。加上当时团队的开发与管理方法的不足,这些因素使得在20世纪70年代的软件危机情况更加严重。为了解决软件危机,人们对开发技术进行了一定的改进,对编程语言也进行了革新,如产生了用于软件开发的4GL、CASE工具、原型技术和代码生成器。这些努力取得了一定的成就,但没有从根本上解决问题。
3 信息建模方法
信息建模方法是在实体联系模型(entity relationship model)的基础上发展起来的。该方法以称为实体的数据集合作为系统的构造块,即以数据结构为中心来开发软件。因为有相当多的人认为实体是稳定的,并且实体联系模型有相当好的理论基础,所以当时该方法为很多开发团队所采用。
对于数据及其关系比较复杂的系统来说,信息建模方法很有用。但它也存在弱点,即它仅对问题域中事物的数据方面进行了建模,而对功能行为在模型中没有体现。这也是信息建模方法常常与其他开发方法相结合使用的一个原因。
包括上述方法在内的几乎所有的传统方法都只注重于系统的一个或少数几个方面,对系统的其他方面建模的能力都很弱。典型地,功能分解法集中于将功能作为系统的构造块,对数据组织的功能较弱,即使是在结构化方法中,对数据组织的支持也不是很强;在信息建模方法中的构造块是实体,强调对数据的组织,但在该方法中忽略了系统功能。此外,上述方法都没有较强的描述系统的动态行为的能力。
软件学术界和产业界尝试了数十年,一直在寻找有效的开发复杂软件系统的方法。经过坚持不懈的努力,形成了面向对象方法。
面向对象方法是在传统方法的基础上发展起来的,例如仍使用抽象和模块化等概念。然而,面向对象方法与传统方法相比发生了根本性的变化,主要在于面向对象方法具有从多维度把所建立的模型与问题域进行直接映射的能力,在整个开发过程中均采用一致的概念和表示法,采用诸如封装、继承和消息等机制使得问题域的复杂性在模型上得以控制。