面向对象方法学概述
究竟怎样才算真正的“面向对象”(Object-Oriented,OO)呢?Peter Coad和Edward Yourdon提出了下列等式:
面向对象 = 对象(Objects)
+ 类(Cclasses)
+ 继承(Inheritance)
+ 消息通信(Communication With Messages)
1)对象与封装
对象(Object)是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。面向对象的软件系统是由对象组成的,复杂的对象由比较简单的对象组合而成。也就是说,面向对象方法学使用对象分解取代了传统方法的功能分解。
对象三要素是对象标识、属性和服务。
(1)对象标识(Object Identifier),也就是对象的名字,供系统内部唯一地识别对象。定义或使用对象时,均应指定对象标识。
(2)属性(Attribute),也称状态(State)或数据(Data),用来描述对象的静态特征。在某些面向对象的程序设计语言中,属性通常被称为成员变量(Member Variable)或简称变量(Variable)。
(3)服务(Service),也称为操作(Operation)、行为(Behavior)或方法(Method)等,用来描述对象的动态特征。在某些面向对象的程序设计语言中,服务通常被称为成员函数(Member Function)或简称函数(Function)。
封装(Encapsulation)是对象的一个重要原则。它有两层含义:第一,对象是其全部属性和全部服务紧密结合而形成的一个不可分割的整体;第二,对象是一个不透明的黑盒子,表示对象状态的数据和实现操作的代码都被封装在黑盒子里面。使用一个对象的时候,只需知道它向外界提供的接口形式,无须知道它的数据结构细节和实现操作的算法。从外面看不见,也就更不可能从外面直接修改对象的私有属性了。
2)类
类(Class)是对具有相同属性和服务的一个或一组对象的抽象定义。
类与对象是抽象描述与具体实例的关系,一个具体的对象被称为类的一个实例(instance)。
3)继承与多态性
(1)继承(Inheritance)是面向对象方法学中的一个十分重要的概念,其定义是:特殊类(或称子类、派生类)的对象拥有其一般类(或称父类、基类)的全部属性与服务,称做特殊类对一般类的继承。在面向对象方法学中,继承是提高软件开发效率的重要原因之一。
(2)多态性(Polymorphism)是指一般类中定义的属性或服务被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。使用多态技术时,用户可以发送一个通用的消息,而实现的细节则由接受对象自行决定,这样同一消息就可以调用不同的方法。多态性不仅增加了面向对象软件系统的灵活性,进一步减少了信息冗余,而且显著提高了软件的可重用性和可扩充性。多态有多种不同的形式,其中参数多态和包含多态称为通用多态,过载多态和强制多态称为特定多态。
4)消息通信
消息(Message)就是向对象发出的服务请求,它应该含有下述信息:提供服务的对象标识、消息名、输入信息和回答信息。对象与传统的数据有本质区别,它不是被动地等待外界对它施加操作,相反,它是进行处理的主体,必须发消息请求它执行它的某个操作,处理它的私有数据,而不能从外界直接对它的私有数据进行操作。
消息通信(Communication With Messages)也是面向对象方法学中的一条重要原则,它与对象的封装原则密不可分。封装使对象成为一些各司其职、互不干扰的独立单位;消息通信则为它们提供了唯一合法的动态联系途径,使它们的行为能够互相配合,构成一个有机的系统。
只有同时使用对象、类、继承与消息通信,才是真正面向对象的方法。
面向对象方法学的优点,
与人类习惯的思维方法一致。
稳定性好
可重用性好
易开发大型软件产品
可维护性好。
OMT方法的OOA模型包括对象模型、动态模型和功能模型。
(1)对象模型表示静态的、结构化的系统的“数据”性质。它是对模拟客观世界实体的对象及对象彼此间的关系的映射,描述了系统的静态结构,通常用类图表示。
(2)动态模型表示瞬时的、行为化的系统的“控制”性质,它规定了对象模型中的对象的合法变化序列,通常用状态图表示。
(3)功能模型表示变化的系统的“功能”性质,它指明了系统应该“做什么”,因此更直接地反映了用户对目标系统的需求,通常用数据流图表示。
OMT方法的3个模型,分别从3个不同侧面描述了所要开发的系统:功能模型指明了系统应该“做什么”;动态模型明确了什么时候做(即在何种状态下接受了什么事件的触发);对象模型则定义了做事情的实体。这3种模型相互补充、相互配合,3者之间具有下述关系。
(1)动态模型展示了对象模型中每个对象的状态及它接受事件和改变状态时所执行的操作;而功能模型中的处理则对应于对象模型中的对象所提供的服务。
(2)对象模型展示了动态模型中是谁改变了状态和经受了操作;而功能模型中的处理则可能产生动态模型中的事件。
(3)对象模型展示了功能模型中的动作者、数据存储和流的结构;而动态模型则展示了功能模型中执行加工的顺序。
2)建立对象模型
Peter Coad和Edward Yourdon在1991年出版的《面向对象的分析》(Object-Oriented Analysis)一书中指出,复杂系统的对象模型通常由五个层次组成:类及对象层、结构层、主题层、属性层和服务层。上述五个层次对应着建立对象模型的五项主要活动:确定类与对象、确定结构与关联、划分主题、定义属性和定义服务。但这五项活动完全没必要顺序完成,也无须彻底完成一项活动之后再开始另外一项活动。
(1)确定类与对象:类与对象是在问题域中客观存在的,系统分析的重要任务之一就是找出这些类与对象。首先找出所有候选的类与对象,然后进行反复筛选,删除不正确或不必要的类与对象。
(2)确定结构与关联:结构与关联反应了对象(或类)之间的关系,主要有以下几种。
一般—特殊结构(Generalization-Specialization Structure),又称分类结构(Classification Structure),是由一组具有一般—特殊关系(继承关系)的类所组成的结构。一般—特殊关系(Generalization- Specialization Relation)的表达式为:is a kind of。
整体—部分结构(Whole-Part Structure),又称组装结构(Composition Structure),是由一组具有整体-部分关系(组成关系)的类所组成的结构。整体—部分关系(Whole-Part Relation)的表达式为:Has A。
?实例关联(Instance Connection),即一个类的属性中含有另一个类的实例(对象),它反映了对象之间的静态联系。
?消息关联(Message Connection),即一个对象在执行自己的服务时需要通过消息请求另一个对象为它完成某个服务,它反映了对象之间的动态联系。
(3)划分主题:在开发大型、复杂软件系统的过程中,为了降低复杂程度,需要把系统划分成几个不同的主题。注意,应该按问题域而不是用功能分解方法来确定主题,应该按照使不同主题内的对象相互间依赖和交互最少的原则来确定主题。
(4)定义属性:为了发现对象的属性,首先考虑借鉴以往的OOA结果,看看相同或相似的问题域是否有已开发的OOA模型,尽可能复用其中同类对象的属性定义。然后,按照问题域的实际情况,以系统责任为目标进行正确的抽象,从而找出每一对象应有的属性。
(5)定义服务:发现和定义对象的服务,也应借鉴以往同类系统的OOA结果并尽可能加以复用。然后,研究问题域和系统责任以明确各个对象应该设立哪些服务,以及如何定义这些服务。
3)建立动态模型
建立动态模型的第一步,是编写典型交互行为的脚本。虽然脚本中不可能包括每个偶然事件,但至少必须保证不遗漏常见的交互行为。第二步,从脚本中提取出事件,确定触发每个事件的动作对象及接受事件的目标对象。第三步,排列事件发生的次序,确定每个对象可能有的状态及状态间的转换关系,并用状态图描绘它们。最后,比较各个对象的状态图,检查它们之间的一致性,确保事件之间的匹配。
4)建立功能模型
OMT方法中的功能模型实际上就是结构化方法中的数据流图。从这点看,OMT方法并不是“纯”面向对象的。这是OMT方法的一大缺陷。
1992年,Ivar Jacobson在《面向对象的软件工程——用例驱动的途径》(Object-Oriented Software Engineering,A Use Case Driven Approach)中首次提出了“用例”(Use Case)的概念。随后,有人提出以用例图取代数据流图进行需求分析和建立功能模型,这应该被看做是对OMT方法的重大改进。使用用例图建立起来的系统模型也被称为用例模型。
一个用例是可以被行为者感受到的、系统的一个完整的功能。一幅用例图包含的模型元素有系统、行为者、用例及用例之间的关系。用例模型描述的是外部行为者所理解的系统功能。
目前,“用例驱动”已成为软件开发过程的一条重要原则。
4.面向对象的设计
1)OOA与OOD的关系
与结构化方法不同,面向对象的方法并不强调分析与设计之间严格的阶段划分。OOA与OOD所采用的概念、原则和表示法都是一致的,二者之间不存在鸿沟,不需要从分析文档到设计文档的转换,所以有些工作无论在分析时进行还是在设计时进行都不存在障碍。当然,OOA与OOD仍然有不同的分工和侧重点。
关于OOA与OOD的关系,目前有两种不同的观点。
一种观点是继续沿用传统的分工——分析着眼于系统“做什么”,设计解决“怎么做”的问题。而Peter Coad和Edward Yourdon的OOA&D方法则采用了另外一种分工方式——分析阶段只考虑问题域和系统责任,建立一个独立于实现的OOA模型;设计阶段考虑与实现有关的因素,对OOA模型进行调整并补充与实现有关的部分,形成OOD模型。本书的OOD方法主要依据Coad/Yourdon的观点。
Coad/Yourdon的OOD模型包括以下四个部件:人机交互部件、问题域部件、任务管理部件、数据管理部件。与此对应的OOD过程也包括四项活动:设计人机交互部件、设计问题域部件、设计任务管理部件、设计数据管理部件。
2)设计问题域部件
通过OOA所得出的问题域精确模型,为设计问题域部件奠定了良好的基础。通常,OOD仅需从实现角度对问题域模型做一些补充和修改,主要是增添、合并或分解类与对象、属性及服务、调整继承关系等。
3)设计人机交互部件
在OOA过程中,已经对用户界面需求做了初步分析。在OOD过程中,则应该对系统的人机交互部件进行详细设计,以确定人机交互的细节,其中包括指定窗口和报表的形式、设计命令层次等项内容。
4)设计任务管理部件
主要是识别事件驱动任务,识别时钟驱动任务,识别优先任务,识别关键任务,识别协调任务,审查每个任务并定义每个任务。
5)设计数据管理部件
提供数据管理系统中存储和检索对象的基本结构,隔离具体的数据管理方案(如普通文件、关系数据库、面向对象数据库等)对其他部分的影响。