第1章 面向对象技术概述.docx

上传人:b****4 文档编号:4902512 上传时间:2022-12-11 格式:DOCX 页数:10 大小:62.42KB
下载 相关 举报
第1章 面向对象技术概述.docx_第1页
第1页 / 共10页
第1章 面向对象技术概述.docx_第2页
第2页 / 共10页
第1章 面向对象技术概述.docx_第3页
第3页 / 共10页
第1章 面向对象技术概述.docx_第4页
第4页 / 共10页
第1章 面向对象技术概述.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

第1章 面向对象技术概述.docx

《第1章 面向对象技术概述.docx》由会员分享,可在线阅读,更多相关《第1章 面向对象技术概述.docx(10页珍藏版)》请在冰豆网上搜索。

第1章 面向对象技术概述.docx

第1章面向对象技术概述

第1章面向对象技术概述

1.1软件危机及软件工程

20世纪60年代中期开始爆发的软件危机,使人们认识到大中型软件系统与小型软件有本质的不同:

大型软件系统的开发周期长、开发费用昂贵、开发出来的软件质量难以保证、开发生产率低,它们的复杂性已远远超出了人脑所能直接控制的程度。

就像用制造小木船的方法不能生产航空母舰一样,大型软件系统的开发不能再延续手工作坊式的开发方式,而必须立足于科学的理论基础上,实行大兵团式的工程化作业,这一认识导致了软件工程学的诞生。

1968年,北大西洋公约组织(NATO)科技委员会在当时的联邦德国Garmisch召开了有近50名一流的计算机科学家、编程人员和工业界人士参加的研讨会,商讨摆脱软件危机的办法,在这次会议上第一次提出了软件工程的概念,这是软件开发史上重要的里程碑,它标志着软件开发进入了划时代的新阶段。

 

1.2对软件开发的基本认识

如图2.2所示是UML发展历史的简图。

图2.2UML的发展历史

UML是由世界著名的棉线对象技术专家G.Booch、J.Rumbaugh和L.Jacobson发起,在Booch方法、OMT方法和OOSE方法的基础上,汲取其他面向对象方法的优点,广泛征求意见,几经修改而完成的。

目前UML得到了诸多大公司的支持,如IBM、HP、Oracle、Microsoft等,已经成为面向对象技术领域内占主导地位的标准建模语言,Booch、Rumbaugh和Jacobson在一些文献中经常被称作“三个好朋友”(threeamigos)。

 

1.3软件的固有复杂性

软件的特点说明了软件开发的复杂性和困难性。

著名的计算机专家,被称之为IBM360系列计算机之父的F.Brooks认为软件的复杂性是固有的,软件可能是人类所能制造出来的最复杂的实体[Bro87]。

导致软件复杂性的原因很多,下面列出一些主要的原因:

(1)首先,软件的复杂性和计算机的体系结构有关。

计算机的体系结构从计算机诞生以来,尽管有了很大的进步,如采用了流水线、超高速缓冲存储器等,但主要仍然是冯·诺依曼式的,虽然在计算机的发展过程中,也出现过一些新型的体系结构,但这些体系结构并没有获得主导地位。

冯·诺依曼所提出的存储程序方式的计算机体系结构的主要特点是硬件简单(存储器、运算器和控制器),而软件却很复杂,所需全部功能由软件来完成。

在一些很单纯的应用中(如数值计算),这种体系结构尚且可行,但在目前需要庞大而复杂的软件系统的情况下,这种体系结构存在难以克服的缺点。

如果计算机继续采用冯·诺依曼式的体系结构,则软件的复杂性将很难消除。

(2)其次,软件开发是人的一种智力活动,软件系统从本质上是由许多相互联系的概念所组成的结构。

这种概念结构很难用一组数学公式或物理定律来描述,也就是说,很难找到一种好的方法或工具来刻画软件系统的内在本质特征或规律。

(3)第三,造成软件系统复杂性的另一个原因是,软件系统中各元素之间的相互作用关系具有不确定性。

从理论上讲,任何两个元素之间都可以存在交互关系,几乎不受任何外界因素的限制,而且随着元素数目的增加,元素之间的交互关系呈非线性递增的趋势。

(4)第四,由于软件没有固定的形式与坚硬的外壳,人们普遍认为软件系统是“软”的,似乎可以随意扩充和修改。

因此软件系统还面临不断变化的压力,不同的软件系统需要满足不同用户的工作方式和习惯。

用户总是尝试用更合理和更方便的方式使用软件,并且希望系统为他们完成更多种类和更大数量的工作。

新的功能或变化的功能不断地向软件系统提出新的要求,这种持续的变化又增加了软件系统的复杂性。

(5)第五,规模较大的软件系统的生命周期一般都超过相应硬件系统的生命周期。

在此期间,硬件系统可能在不断变化,原有的软件系统将不得不根据实际应用环境的要求随时做出调整与变化,以适应不同的硬件系统,这又给软件系统本身带来许多新的复杂性。

由于软件的固有复杂性,使得开发成员之间的沟通变得困难,开发费用超支,开发时间延期,等等;复杂性也导致产品有缺陷、不易理解、不可靠、难以使用、功能难以扩充,等等。

在一些传统的工程领域,设计人员往往有好的理论帮助其进行设计。

如桥梁专家在设计桥梁时有完整的力学理论帮助其进行设计,硬件设计师在设计新片时有微电子学理论的指导。

但对于软件设计人员,几乎没有任何类似的数学或物理理论帮助或制约设计人员对软件系统进行设计,即使存在这种约束,那也是设计人员为了达到控制软件复杂性的目的,人为地强加给软件系统的。

软件开发过程中这种巨大的自由性使得软件系统可以具有极大的无序度,使得软件系统难以理解、认识、掌握和控制。

软件系统复杂到一定程序,人的智力将很难考虑到其中包含的所有问题。

尽管可以人为地给软件强加某些约束关系,但毕竟是人为的。

软件设计人员所面临问题的复杂性远远超过了设计一座桥梁,设计一个芯片等所面临问题的复杂性,软件设计人员既要为自己建立设计与实现的准则,又要利用这些准则构造符合要求的软件系统,因此所面临的困难比其他设计领域更多。

1.4控制软件复杂性的基本方法

软件的复杂性不是因为某个软件系统要解决一个特定的复杂问题而偶然产生的,它是大型软件系统的一个固有的本质特征,软件的开发过程必然会受到软件复杂性的影响。

软件的固有复杂性是导致软件开发与维护过程中众多问题的根源,它使得软件开发过程难以控制,造成软件项目的延期及预算超支,达不到预定的设计要求。

但由于软件复杂性是固有的,人们无法彻底消除这些复杂性,因此只能采用控制复杂性的方法,尽量减少软件复杂性对软件开发过程的影响,而分解、抽象、模块化、信息隐蔽等是控制软件复杂性的有效方法。

1.分解

人类解决复杂问题时普遍采用的一个策略就是“各个击破”,也就是对问题进行分解,然后再分别解决各个子问题。

著名的计算机科学家Parnas认为,巧妙地分解系统可以有效地划分系统的状态空间,降低软件系统的复杂性所带来的影响[Par72]。

对于复杂的软件系统,可以逐步将它分解为越来越小的组成部分,直至不能分解为止。

这样就可以使系统的复杂性,在特定的层次与范围内不会超过人的理解能力。

UNIX中的shell和管道即是采用分解思想的例子。

2.抽象

抽象指的是抽取系统中的基本特征而忽略非基本的特征,以便更充分地注意与当前目标有关的方面。

现实世界中的大多数系统都有其内在的复杂性,远远超出人当时所处理的程度。

当时用抽象这个概念时,我们承认这个内在考虑的问题是复杂的,但我们并不打算理解问题的全部,而只是选择其中的主要部分,我们指导这个问题还应包括附加的细节,只是此时不去注意那些细节而已。

Miller在一篇经典的文献“神奇的数字7”中提到,人在同一时间里,一般只能集中于7项左右的信息,而不受信息的内容、大小等因素的影响[Mil56]。

大型软件系统所包含的元素数目远远超过了这一数字。

虽然我们仍然受Miller规则的限制,但可以利用抽象来克服这一困难。

通过忽略系统内许多非本质的细节,仍然有可能理解和控制各种复杂性的系统。

一般说来,抽象又可分为过程抽象和数据抽象。

过程抽象是广泛使用的一种抽象形式。

任何一个有明确功能的操作都可被使用者作为单个的实体看待,尽管这个操作实际上可能有一系列更低级的操作来完成。

在实际应用中,将处理分解成子步骤是对付复杂性的一个基本方法。

数据抽象定义了数据类型和施加于该类型上的操作,并限定了数据类型的值只能通过这些操作来修改和读取。

数据抽象是一个强有力的抽象机制,是控制复杂性的一个重要方法。

3.模块化

Parnas对模块化的原则有精辟的论述[Par76]。

一般地,对模块的要求是高内聚(cohesion)、低耦合(coupling)。

高内聚指在一个模块中应尽量多地汇集逻辑上相关的计算资源,低耦合指的是模块之间的相互作用应尽量少。

4.信息隐蔽

也称封装。

信息隐蔽的原则是把模块内的实现细节与外界隔离,用户只需知道模块的功能,而不需了解模块的内部细节。

即将每个程序的成分隐蔽或封装在一个单一的模块中,定义每一个模块时尽可能少地暴露其内部的处理。

信息隐蔽的基本思想是,无论喜欢或不喜欢,我们是生活在一个瞬息万变的环境中,如果将系统中极不稳定的部分封装起来,那么系统不可避免的变化对整体结构的威胁就较少了。

信息隐蔽能帮助人们在开发新系统时减少不必要的工作,将来如果需要对模块进行修改,则只需修改模块的内部结构,其外部接口可以不做变动。

信息隐蔽原则提高了软件的可维护性,且模块内的错误不易蔓延到其他模块,极大地降低了模块间的耦合度,是控制软件复杂性的有效手段,现在信息隐蔽原则已成为软件工程学中的一条重要原则。

1.5面向对象技术

面向对象(object-oriented,OO)技术充分体现了分解、抽象、模块化、信息隐蔽等思想,可以有效地提高软件生产率、缩短软件开发时间、提高软件质量,是控制软件复杂性的有效途径。

传统的结构化方法的着眼点在于一个信息系统需要什么样的方法和处理过程。

以过程抽象来对待系统的需求,其主要思想就是对问题进行功能分解,如果分解后得到的功能过大,那么再对这些功能进行分解,直到最后分解得到的功能比较方便地处理和理解为止。

所以结构化方法也称为功能分解法(functionaldecomposition)。

与传统的结构化软件开发方法相比,面向对象软件开发方法在描述和理解问题域时采用截然不同的方法。

其基本思想是,对问题域进行自然分割,以更接近于人类思维的方式建立问题域模型,从而使设计出的软件尽可能直接地描述现实世界,具有更好的可维护性,能适应用户需求的变化。

面向对象技术的优点是非常明显的。

首先,用OO技术开发的系统比较稳定,较小的需求变化不会导致大的系统结构的改变。

其次,用OO技术开发的系统易于理解。

结构化方法和面向对象方法对现实世界采用了不同的映射方法。

在结构化方法中,现实世界被映射为功能的集合;在面向对象方法中,现实世界中的实体及其相互关系被影射为对象及对象间的关系,实体之间的相互作用被映射为对象间的消息发送,以及其他类似的各种映射关系。

也就是说,面向对象的模型对现实世界的映射更直观、更有对应关系。

第三,采用OO技术开发的系统具有更好的适应性,能更好地适应用户需求的变化,有助于构造大型软件系统。

第四,用OO技术开发的系统具有更高的可靠性。

在面向对象方法中,分析和设计阶段采用一致的概念和表示法,面向对象的分析和面向对象的设计之间不存在鸿沟,这是与结构化分析和设计方法的一个很大区别。

图1.1表示了这两种方法之间的区别。

图1.1结构化方法和面向对象方法的比较

一般认为,面向对象分析和设计是以对象的观点看待问题域,其解决问题的思维过程和结构化分析及设计方法在本质上是有区别的,但早期提出的适用于结构化分析和设计的一些基本概念,如高内聚、低耦合、有意识地推迟设计决策等,同样可适用于面向对象分析和设计。

也就是说,面向对象方法和结构化方法还是存在一定的联系。

目前学术界关于面向对象方法对结构化方法来说究竟是“革命性”的还是“演化性”的,不同的人有不同的观点。

一般来说,认为是“演化性”的人多一些。

1.6面向对象领域中的基本概念

面向对象软件开发方法中有很多传统软件开发方法所没有的概念和术语。

在本节中,将对OO领域中常见的几个概念和术语做一些简单的解释,对可能存在的错误认识做一些澄清。

这些概念和术语包括:

对象、实例、类、属性、方法、封装、继承、多态、消息等。

与UML有关的概念和术语将在后面的相关章节中讨论。

1.6.1对象和实例

对象(object)是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。

一个对象是由一组属性和对这组属性进行操作的一组方法组成。

对象只描述客观事物本质的、与系统目标有关的特征,而不考虑那些非本质的、与系统目标无关的特征。

对象之间通过消息通信。

一个对象通过向另一个对象发送消息激活某一个功能。

实例(instance)这个概念和对象很类似。

在UML中,会经常遇到实例这个术语。

一般来说,实例这个概念的含义更广泛一些,它不仅仅是对类而言,其他建模元素也有实例。

如类的实例就是对象,而关联的实例就是链(在第五章讲UML类图时将解释具体什么是关联)。

1.6.2类

类(class)是具有相同属性和方法的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述。

同类对象具有相同的属性和方法,是指它们的定义形式相同,而不是说每个对象的属性值都相同。

类是静态的,类的语义和类之间的关系在程序执行前就已经定义好了,而对象是动态的,对象是在程序执行时被创建和删除的。

如图1.2所示是类的例子,其中类的名字是Employee,该类有5个属性和5个方法。

图1.2类Employee

1.6.3封装

封装(encapsulation)就是把对象的属性和方法结合成一个独立的系统单位,并尽可能地隐藏对象的内部细节。

封装使一个对象形成两个部分:

接口部分和实现部分。

对于用户来说,接口部分是可见的,而实现部分是不可见的。

对象包括:

①接口部分②实现部分。

封装提供了两种保护。

首先封装可以保护对象,防止用户直接存取对象的内部细节;其次封装也保护了客户端,防止对象实现部分的变化可能产生的副作用,即实现部分的改变不会影响到相应客户端的改变。

两种保护:

①保护对象②保护客户端。

1.6.4继承

利用继承(inheritance),子类可以继承父类的属性或方法。

在一些文献中,往往把子类/父类称作特殊类/一般类、子类/超类、派生类/基类等。

继承增加了软件重用的机会,可以降低软件开发和维护的费用,而继承是OO技术和非OO技术的一个很明显的区别。

所以很多人认为OO技术的目的就是为了重用,这是一个很流行的关于面向对象技术和软件重用的误解。

确实,采用OO技术可以增加软件重用的机会,但OO技术并不等于软件重用技术,软件重用技术也不等于OO技术,两者之间的关系如图1.3所示。

图1.3OO技术和软件重用技术的关系

也就是说,两者之间并不存在相互包含的关系,OO技术既不是重用技术的充分条件,也不是重用技术的必要条件。

利用继承可以开发更贴近现实的模型,使得模型更简洁。

继承的另一个好处是可以保证类之间的一致性,父类可以为所有子类定制规则,子类必须遵守这些规则。

许多面向对象程序设计语言提供了这种实现机制,如C++中的虚函数,Java中的接口等。

在子类中可以增加或重新定义所继承的属性或方法,如果是重新定义,则称为覆盖(override)。

与覆盖很类似的一个概念是重载(overload),重载指的是一个类中有多个同名的方法,但这些方法在操作数或/和操作数的类型上有区别。

覆盖和重载是OO技术中很常见的两个术语,也很容易混淆。

下面举两个例子说明这两个概念之间的区别。

覆盖的例子如下所示:

publicclassA{

Stringname;

publicStringgetValues(){

return“Valueis:

”+name;

}

}

publicclassBextendsA{

Stringaddress;

publicStringgetValues(){

Return“Valueis:

”+address;

}

}

其中类B是类A的子类,类B中定义的getValues()方法是对类A的getValues()的覆盖。

重载的例子如下所示:

publicclassA{

intage;

Stringname;

publicvoidsetValue(intx){

age=i;

}

publicvoidsetValue(Strings){

name=s;

}

}

类A定义了两个setValue方法,但这两个方法的参数不同。

当一个对象使用类A的一个对象的setValue方法时,根据传进来的参数类型可以确定具体要调用的是哪个方法。

继承可分为单继承和多继承。

单继承指的是子类只从一个父类继承,而多继承指的是子类从多于一个的父类继承。

如图1.4所示的是单继承的例子。

其中,交通工具(Vehicle)是父类,地面交通工具(GroundVehicle)和水上交通工具(WaterVehicle)是子类。

图1.4单继承

如图1.5所示是多继承的例子。

其中两栖交通工具(AmphibiousVehicle)同时继承地面交通工具和水上交通工具。

图1.5多继承

多继承虽然比较灵活,但多继承可能会带来“命名冲突”的问题。

如果是在实现阶段,不同的程序设计语言可能有不同的解决方法。

如C++是采用成员名限定方法解决,Eiffel是采用方法再命名机制解决,而Java干脆不支持多继承,如果要实现类似于多继承的功能,则采用接口来实现。

1.6.5多态

从字面上理解,多态(polymorphism)就是具有多种形态的意思。

在面向对象技术中,多态指的是使一个实体在不同上下文条件下具有不同意义或用法的能力。

多态往往和覆盖、动态绑定(dynamicbinding)等概念结合在一起。

多态属于运行时的问题,而重载(overload)是编译时的问题。

图1.6多态

如图1.6所示是多态的例子。

在图1.6的继承结构中,可以声明一个Graph类型对象的变量,但在运行时,可以把Circle类型或Rectangle类型的对象赋给该变量。

也就是说,该变量所引用的对象在运行时会有不同的形态。

如果调用draw()方法,则根据运行时该变量是引用Circle还是Rectangle,来决定调用Circle中的draw()方法还是Rectangle中的draw()方法。

多态是保证系统具有较好适应性的一个重要手段,也是使用OO技术所表现出来的一个重要特征。

1.6.6消息

消息(message)就是向对象发出的服务请求。

它包含了提供服务的对象标识、服务(方法)标识、输入信息和回答信息等。

面向对象方法的一个原则就是通过消息进行对象之间的通信。

初学面向对象方法的人往往把消息等同于函数调用,事实上两者之间存在区别。

消息可以包括同步消息和异步消息,如果消息是异步的,则一个对象发送消息后,就继续自己的活动,不等待消息接收者返回控制,而函数调用往往是同步的,消息的发送者要等待接收者返回。

使用消息这个术语更接近人们日常思维,且含义更具一般性。

1.7小结

1.经过30多年的研究和实践,软件工程这门学科已取得了很大的进展。

针对大型软件系统开发中存在的问题,人们提出了各种各样的解决方法,但这些方法都存在这样或那样的缺陷。

大量的事实表明,软件危机依然存在,软件的质量和生产率问题远没有得到解决。

2.软件危机和软件的固有复杂性有关,软件的固有复杂性是由软件本身的特性决定的。

正是由于软件的固有复杂性,带来了软件开发费用超支、开发时间延期、开发出来的产品质量不合要求等问题。

可以说,软件的固有复杂性是导致软件危机的根源。

3.软件的复杂性是大型软件系统一个固有的本质特征,无法彻底消除这些复杂性,只能采用控制复杂性的方法,尽量减少软件复杂性对软件开发的影响。

而分解、抽象、模块化、信息隐蔽等是控制软件复杂性的有效方法。

4.面向对象技术充分体现了分解、抽象、模块化、信息隐蔽等思想,可以有效地提高软件生产率,缩短软件开发时间,提高软件质量。

5.与传统的结构化软件开发方法相比,面向对象软件开发方法具有更大的优势。

学术界、工业界的多年研究和实践表明,面向对象方法是解决软件危机的有效途径之一。

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1