面向对象(Object Oriented)掠影

面向对象(Object Oriented,简称OO)是当前计算机界关心的重点,它是90年代软件开发方法的主流。

 

其初,面向对象是专指在程序设计中基于对象概念,以对象为中心,以类和继承为构造机制,来认识、理解、刻画客观世界和设计、构建相应的软件系统;它是一种把面向对象的思想运用于软件开发过程中,指导开发活动的系统方法,它是建立在“对象”概念(对象、类和继承)基础上的方法学而如今面向对象的思想已经涉及到软件开发的各个方面。如面向对象的分析(OOAObject Oriented Analysis)、面向对象的设计(OODObject Oriented Design)以及我们经常说的面向对象的编程实现(OOPObject Oriented Programming)。现在面向对象的概念和应用已超越了程序设计和软件开发,扩展到很宽的范围。如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。 

 

面向对象是一种思想

 


在八十年前面向对象是作为认识世界的哲学思想被提出的,这种思想由本世纪最伟大的哲学家维特根斯坦阐述于1922出版的《逻辑哲学论》(《Logisch-Philosophische Abhandlung)这一著作中。维特根斯坦认为:世界是由简单的基本的对象构成的(《逻辑哲学论》2.021 对象构成世界的实体,因此它们不能是复合的),这就是面向对象设计的基石。

 

面向对象是对现实世界的一种抽象


我们知道现实世界是由物质(存在物、事物)构成的。在信息领域或者计算机业界的我们由此抽象出:某一问题域是由对象构成的,这样对象就映射了现实世界中的存在物。
现实世界中事物是由它的性质和功能来表征的。例如,我的自行车是铝合金的车架,可以前进、刹车,铝合金就是自行车的性质,前进、和刹车就是自行车的功能。这些都是我们捕获(抽象)现实世界中存在物(事物、物质)的信息。对这些信息编码就成为了数据。数据是计算机能识别的信息。于是我们把现实世界中的事物映射为信息领域中的对象,并进一步抽象为数据领域中的类。

 

计算机科学中对象的提出 


计算机科学中对象和实例概念的最早萌芽可以追溯到麻省理工大学的PDP-1系统。这一系统大概是最早的基于容量架构(capability based architecture)的实际系统。另外1963Ivan SutherlandSketchpad应用中也蕴含了同样的思想。

对象作为编程实体最早是于1960年代由Simula 67语言引入。 Simula这一语言是Ole-Johan DahlKristen Nygaard在挪威奥斯陆计算机中心为模拟环境而设计的。(据说,他们是为了模拟船只而设计的这种语言,并且对不同船只间属性的相互影响感兴趣。他们将不同的船只归纳为不同的类,而每一个对象,基于它的类,可以定义它自己的属性和行为。)这种办法是分析式程序的最早概念体现。在分析式程序中,我们将真实世界的对象映射到抽象的对象,这叫做“模拟”。Simula不仅引入了“类”的概念,还应用了实例这一思想——这可能是这些概念的最早应用。当时的程序设计领域正面临着一种危机:在软硬件环境逐渐复杂的情况下,软件如何得到良好的维护?

20世纪70年代施乐PARC研究所发明的Smalltalk语言将面向对象程序设计的概念定义为,在基础运算中,对对象和消息的广泛应用。Smalltalk的创建者深受Simula 67的主要思想影响,但Smalltalk中的对象是完全动态的——它们可以被创建、修改并销毁,这与Simula中的静态对象有所区别。此外,Smalltalk还引入了继承性的思想,它因此一举超越了不可创建实例的程序设计模型和不具备继承性的Simula,面向对象思想得到了完善和标准化,它奠定了面向对象程序设计的基础。

此外,Simula 67的思想亦被应用在许多不同的语言,如LispPascal

面向对象程序设计在80年代成为了一种主导思想,这主要应归功于C++——C语言的扩充版。在图形用户界面(GUI)日渐崛起的情况下,面向对象程序设计很好地适应了潮流。GUI和面向对象程序设计的紧密关联在Mac OS X中可见一斑。Mac OS X是由面向对象C语言写成的,这一语言是一个仿SmalltalkC语言扩充版。面向对象程序设计的思想也使事件处理式的程序设计更加广泛被应用(虽然这一概念并非仅存在于面向对象程序设计)。一种说法是,GUI的引入极大地推动了面向对象程序设计的发展。

ETH ZürichNiklaus Wirth 和他的同事们对抽象数据和模块化程序设计进行了调查。Modula-2将这些都包括了进去,而Oberon则包括了一种特殊的面向对象方法——不同于SmalltalkC++

面向对象的特性也被加入了当时较为流行的语言:AdaBASICLispFortranPascal以及种种。由于这些语言最初并没有面向对象的设计,故而这种糅合常常会导致兼容性和维护性的问题。与之相反的是,“纯正的”面向对象语言却缺乏一些程序员们赖以生存的特性。在这一大环境下,开发新的语言成为了当务之急。作为先行者,Eiffel成功地解决了这些问题,并成为了当时较受欢迎的语言。

在过去的几年中,Java语言成为了广为应用的语言,除了它与CC++语法上的近似性。Java的可移植性是它的成功中不可磨灭的一步,因为这一特性,已吸引了庞大的程序员群的投入。

近日,一些既支持面向对象程序设计,又支持面向过程程序设计的语言悄然浮出水面。它们中的佼佼者有PythonRuby等等.

与此同时在80年代中期到90年代,研究重点已经从语言转移到设计方法学方面,尽管还不成熟,但已陆续提出了一些面向对象的开发方法和设计技术。其中具有代表性的工作有: B.H.SollersJ.M.Edwards提出的面向对象软件生存周期的“喷泉”模型、GBooch提出的面向对象开发方法学、E.Yourdorl等人提出的面向对象分析等等。这些方法的提出,标志着面向对象方法逐步发展成为一类完整的方法学和系统化的技术体系。

正如面向过程程序设计使得结构化程序设计的技术得以提升,现代的面向对象程序设计方法使得对设计模式的用途、契约式设计和建模语言(如UML)技术也得到了一定提升。

 

面向对象的特征 


关于OO方法确切需要哪些特征学术界是有争议的,但大致上它们都包含四个方面:标识(identity)、分类(classification) 、继承(inheritance)、多态(polymorphism)

  •  标识(identity:数据被量化成称为对象的离散的,可辨别的实体。每个对象都有自身唯一的内部标识,通过这种标识,可找到相应的对象(即使所有的属性都相同,两个对象也是有差别的)。在对象的整个生命期中,它的标识都不改变,不同的对象不能有相同的标识。
  •  分类(classification):拥有相同数据结构(属性)和行为(操作)的对象被分组成为一个类。分类性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。
  •  继承(inheritance):多个类基于一种分层关系,共享类间的属性和操作(合称为特征)。继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。在类层次中,子类只继承一个父类的数据结构和方法,则称为单重继承。在类层次中,子类继承了多个父类的数据结构和方法,则称为多重继承。继承性是面向对象程序设计语言不同于其它语言的最重要的特点,是其他语言所没有的。通过类的继承关系,使公共的特性能够共享,提高了软件的重用性。在软件开发中,类的继承性使所建立的软件具有开放性、可扩充性,这是信息组织与分类的行之有效的方法,它简化了对象、类的创建工作量,增加了代码的可重性并提供了类的规范的等级结构。对象的继承是将对象组织为从一般到特殊的层次结构。
  • 多态(polymorphism):对于不同的类来说相同的操作会有不同的动作。多态性使指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。多态性允许每个对象以适合自身的方式去响应共同的消息。多态性增强了软件的灵活性和重用性。

 

面向对象的开发方法


目前,面向对象开发方法的研究已日趋成熟,国际上已有不少面向对象产品出现。面向对象开发方法有Coad方法、Booch方法和OMT方法等。

  •  Booch方法

Booch最先描述了面向对象的软件开发方法的基础问题,指出面向对象开发是一种根本不同于传统的功能分解的设计方法。面向对象的软件分解更接近人对客观事务的理解,而功能分解只通过问题空间的转换来获得。

  • Coad方法

Coad方法是1989CoadYourdon提出的面向对象开发方法。该方法的主要优点是通过多年来大系统开发的经验与面向对象概念的有机结合,在对象、结构、属性和操作的认定方面,提出了一套系统的原则。该方法完成了从需求角度进一步进行类和类层次结构的认定。尽管Coad方法没有引入类和类层次结构的术语,但事实上已经在分类结构、属性、操作、消息关联等概念中体现了类和类层次结构的特征。

  • OMT方法

OMT方法是1991年由James Rumbaugh5人提出来的,其经典著作为面向对象的建模与设计

该方法是一种新兴的面向对象的开发方法,开发工作的基础是对真实世界的对象建模,然后围绕这些对象使用分析模型来进行独立于语言的设计,面向对象的建模和设计促进了对需求的理解,有利于开发得更清晰、更容易维护的软件系统。该方法为大多数应用领域的软件开发提供了一种实际的、高效的保证,努力寻求一种问题求解的实际方法。

  •  统一建模语言UML(Unified Modeling Language)

软件工程领域在1995年~1997年取得了前所未有的进展,其成果超过软件工程领域过去15年的成就总和,其中最重要的成果之一就是统一建模语言(UML)的出现。UML将是面向对象技术领域内占主导地位的标准建模语言。

UML不仅统一了Booch方法、OMT方法、OOSE方法的表示方法,而且对其作了进一步的发展,最终统一为大众接受的标准建模语言。UML是一种定义良好、易于表达、功能强大且普遍适用的建模语言。它融入了软件工程领域的新思想、新方法和新技术。它的作用域不限于支持面向对象的分析与设计,还支持从需求分析开始的软件开发全过程。

 

面向对象的要素 

  • 抽象

抽象是指强调实体的本质、内在的属性。在系统开发中,抽象指的是在决定如何实现对象之前的对象的意义和行为。使用抽象可以尽可能避免过早考虑一些细节。类实现了对象的数据(即状态)和行为的抽象。

  • 封装性(Encapsulation)与信息隐藏

对象的属性(数据)不能被对象的使用者直接访问,只允许通过由对象提供的方法访问数据;对象的方法(行为、操作)可以公开被任何使用者使用,也可以私有被限定的使用者使用,这就是封装。封装的最基本单位是对象,它通过限制只有特定类的实例可以访问这一特定类的成员,而它们通常利用接口实现消息的传入传出。

具备封装性的面向对象程序设计隐藏了某一方法的具体执行步骤,取而代之的是通过消息传递机制传送消息给它。因此封装防止了程序相互依赖性而带来的变动影响,是保证软件部件具有优良的模块性的基础。面向对象的封装比传统语言的封装更为清晰、更为有力。

面向对象的类是封装良好的模块,类定义将其说明(用户可见的外部接口)与实现(用户不可见的内部实现)显式地分开,其内部实现按其具体定义的作用域提供保护。

  • 共享性

面向对象技术在不同级别上促进了共享

同一类中的共享:同一类中的对象有着相同数据结构,这些对象之间是结构、行为特征的共享关系。

在同一应用中共享:在同一应用的类层次结构中,存在继承关系的各相似子类中,存在数据结构和行为的继承,使各相似子类共享共同的结构和行为。使用继承来实现代码的共享,这也是面向对象的主要优点之一。

在不同应用中共享:面向对象不仅允许在同一应用中共享信息,而且为未来目标的可重用设计准备了条件。通过类库这种机制和结构来实现不同应用中的信息共享。

  • 强调对象结构而不是程序结构

而现在我们则以“对象”将相关的数据和过程函数结合为一体,使得两者的关系看起来更明白,这是面向对象程序设计最大的特点之一。

面向对象的模型

 


对象模型

对象模型表示了静态的、结构化的系统数据性质,描述了系统的静态结构,它是从客观世界实体的对象关系角度来描述,表现了对象的相互关系。该模型主要关心系统中对象的结构、属性和操作,它是分析阶段三个模型的核心,是其他两个模型的框架。

对象和类

 

  • 对象(Object

对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。对象建模的目的就是描述对象。

  • 对象的状态和行为

对象具有状态,一个对象用数据值来描述它的状态。对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为。对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中。 

  • 类(Class

类是具有相同或相似性质的对象的抽象,它定义了一类事物的抽象特点。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象。类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。一个类的方法和属性被称为“成员”。通过将对象抽象成类,我们可以使问题抽象化,抽象增强了模型的归纳能力。

对于具有类似性质、相同的行为、意义及共同关系的对象的描述就称为类。浅白的说,类就是具相同性质对象的集合;反之,对于类而言,对象就是它的实例(instance)

  • 属性(Property

属性的是类中对象所具有的性质(数据值)。

  • 操作和方法(Method

操作是类中对象所使用的一种功能或变换。类中的各对象可以共享操作,每个操作都有一个目标对象作为其隐含参数。

方法是一个类能做的事情,是对象操作的实现步骤,但方法并没有去做这件事,对一个具体对象的方法进行调用并不影响其它对象。

例如狗的吠叫则是方法,而银狐犬的吠叫则属于操作。

关联和链

关联是建立类之间关系的一种手段,而链则是建立对象之间关系的一种手段。

  • 关联和链

链表示对象间的物理与概念联结,关联表示类之间的一种关系,链是关联的实例,关联是链的抽象。

  • 角色

角色说明类在关联中的作用,它位于关联的端点。

  • 受限关联

受限关联由两个类及一个限定词组成,限定词是一种特定的属性,用来有效的减少关联的重数,限定词在关联的终端对象集中说明。
限定提高了语义的精确性,增强了查询能力,在现实世界中,常常出现限定词。

  • 关联的多重性

关联的多重性是指类中有多少个对象与关联的类的一个对象相关。重数常描述为

  • 消息传递(Message Passing

对象之间进行通信的结构叫做消息。在对象的操作中,当一个消息发送给某个对象时,消息包含接收对象去执行某种操作的信息。发送一条消息至少要包括说明接受消息的对象名、发送给该对象的消息名(即对象名、方法名)。一般还要对参数加以说明,参数可以是认识该消息的对象所知道的变量名,或者是所有对象都知道的全局变量名。

一个对象通过接受消息、处理消息、传出消息或使用其他类的方法来实现一定功能,这叫做消息传递机制。对象之间通过对象提供的接口协议进行通信,与函数调用不同的是消息传递必须指定特定的对象。

类的层次结构

  • 聚集关系

聚集是一种“整体-部分”关系。在这种关系中,有整体类和部分类之分,部分结构称为组装结构,它们之间的关系是一种“has a”的关系。。聚集最重要的性质是传递性,也具有逆对称性。

聚集可以有不同层次,可以把不同分类聚集起来得到一颗简单的聚集树,聚集树是一种简单表示,比画很多线来将部分类联系起来简单得多,对象模型应该容易地反映各级层次。

  • 一般化关系

一般化关系是在保留对象差异的同时共享对象相似性的一种高度抽象方式。它是“一般-具体”的关系,也可以说是“is a”的关系。。一般化类称为父类,具体类又称为子类,各子类继承了父类的性质,而各子类的一些共同性质和操作又归纳到父类中。因此,一般化关系和继承是同时存在的。一般化关系的符号表示是在类关联的连线上加一个小三角形。

对象模型

  • 模板

模板是类、关联、一般化结构的逻辑组成。

  • 对象模型

对象模型是由一个或若干个模板组成。模板将模型分为若干个便于管理的子块,在整个对象模型和类及关联的构造块之间,模板提供了一种集成的中间单元,模板中的类名及关联名是唯一的。

 

动态模型

动态模型是与时间和变化有关的系统性质。该模型描述了系统的控制结构,它表示了瞬间的、行为化的系统控制

动态模型是与时间和变化有关的系统性质。该模型描述了系统的控制结构,它表示了瞬间的、行为化的系统控制性质,它关心的是系统的控制,操作的执行顺序,它表示从对象的事件和状态的角度出发,表现了对象的相互行为。
该模型描述的系统属性是触发事件、事件序列、状态、事件与状态的组织。使用状态图作为描述工具。它涉及到事件、状态、操作等重要概念。

  • 事件

事件是指定时刻发生的某件事。

  • 状态

状态是对象属性值的抽象。对象的属性值按照影响对象显着行为的性质将其归并到一个状态中去。状态指明了对象
对输入事件的响应。

  • 状态图

状态图是一个标准的计算机概念,他是有限自动机的图形表示,这里把状态图作为建立动态模型的图形工具。状态图反映了状态与事件的关系。当接收一事件时,下一状态就取决于当前状态和所接收的该事件,由该事件引起的状态变化称为转换。 状态图是一种图,用结点表示状态,结点用圆圈表示;圆圈内有状态名,用箭头连线表示状态的转换,上面标记事件名,箭头方向表示转换的方向。

 

功能模型

功能模型描述了系统的所有计算。功能模型指出发生了什么,动态模型确定什么时候发生,而对象模型确定发生的客体。功能模型表明一个计算如何从输入值得到输出值,它不考虑计算的次序。功能模型由多张数据流图组成。数据流图用来表示从源对象到目标对象的数据值的流向,它不包含控制信息,控制信息在动态模型中表示,同时数据流图也不表示对象中值的组织,值的组织在对象模型中表示。

功能模型描述了系统的所有计算。功能模型指出发生了什么,动态模型确定什么时候发生,而对象模型确定发生的客体。功能模型表明一个计算如何从输入值得到输出值,它不考虑计算的次序。功能模型由多张数据流图组成。数据流图用来表示从源对象到目标对象的数据值的流向,它不包含控制信息,控制信息在动态模型中表示,同时数据流图也不表示对象中值的组织,值的组织在对象模型中表示。图10-15给出了一个窗口系统的图标显示的数据流图。

数据流图中包含有处理、数据流、动作对象和数据存储对象。

  • 处理

数据流图中的处理用来改变数据值。最低层处理是纯粹的函数,一张完整的数据流图是一个高层处理。

  • 数据流

数据流图中的数据流将对象的输出与处理、处理与对象的输入、处理与处理联系起来。在一个计算机中,用数据流来表示一中间数据值,数据流不能改变数据值。

  • 动作对象

动作对象是一种主动对象,它通过生成或者使用数据值来驱动数据流图。

  • 数据存储对象

数据流图中的数据存储是被动对象,它用来存储数据。它与动作对象不一样,数据存储本身不产生任何操作,它只响应存储和访问的要求。

 

传统开发方法存在问题


  • 软件重用性差

重用性是指同一事物不经修改或稍加修改就可多次重复使用的性质。软件重用性是软件工程追求的目标之一。

  • 软件可维护性差

软件工程强调软件的可维护性,强调文档资料的重要性,规定最终的软件产品应该由完整、一致的配置成分组成。在软件开发过程中,始终强调软件的可读性、可修改性和可测试性是软件的重要的质量指标。实践证明,用传统方法开发出来的软件,维护时其费用和成本仍然很高,其原因是可修改性差,维护困难,导致可维护性差。

  • 开发出的软件不能满足用户需要

用传统的结构化方法开发大型软件系统涉及各种不同领域的知识,在开发需求模糊或需求动态变化的系统时,所开发出的软件系统往往不能真正满足用户的需要。

用结构化方法开发的软件,其稳定性、可修改性和可重用性都比较差,这是因为结构化方法的本质是功能分解,从代表目标系统整体功能的单个处理着手,自顶向下不断把复杂的处理分解为子处理,这样一层一层的分解下去,直到仅剩下若干个容易实现的子处理功能为止,然后用相应的工具来描述各个最低层的处理。因此,结构化方法是围绕实现处理功能的过程来构造系统的。然而,用户需求的变化大部分是针对功能的,因此,这种变化对于基于过程的设计来说是灾难性的。用这种方法设计出来的系统结构常常是不稳定的 ,用户需求的变化往往造成系统结构的较大变化,从而需要花费很大代价才能实现这种变化。

 

面向对象程序设计(OOP, Object Oriented Programming


编程范型对于OOP的准确定义及其本意存在着不少争论。

通常,面向对象程序设计,指一种程序设计范型,同时也是一种程序开发的方法论。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。

面向对象程序设计可以被视作一种在程序中包含各种独立而又互相调用的单位和对象的思想,这与传统的思想刚好相反:传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,或者说是负有责任的角色。

OOP理论及与之同名的OOP实践相结合创造出了新的一个编程架构;OOP思想被广泛认为是非常有用的,以致一套新的编程范型被创造了出来。(其它的编程范型例如函数式编程或过程序编程专注于程序运行的过程,而逻辑编程专注于引发程序代码执行的断言)

目前已经被证实的是,面向对象程序设计推广了程序的灵活性和可维护性,并且在大型项目设计中广为应用。 此外,支持者声称面向对象程序设计要比以往的做法更加便于学习,因为它能够让人们更简单地设计并维护程序,使得程序更加便于分析、设计、理解。反对者在某些领域对此予以否认。

 

 

posted @ 2011-07-09 10:49  狼の禅  阅读(1929)  评论(2编辑  收藏  举报
我要啦免费统计