软件工程与项目管理(第2版) 课件 第10章 面向对象方法学_第1页
软件工程与项目管理(第2版) 课件 第10章 面向对象方法学_第2页
软件工程与项目管理(第2版) 课件 第10章 面向对象方法学_第3页
软件工程与项目管理(第2版) 课件 第10章 面向对象方法学_第4页
软件工程与项目管理(第2版) 课件 第10章 面向对象方法学_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

10.1面向对象的概念

10.2面向对象的模型

10.3面向对象的分析

10.4面向对象的设计

10.5面向对象的实现

10.6面向对象和基于对象的区别10.1面向对象的概念面向对象(ObjectOriented,OO)是20世纪90年代以来主流的软件开发方法。面向对象的概念和应用已超越了程序设计和软件开发,扩展到很宽的范围,如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。起初,“面向对象”是专指在程序设计中采用封装、继承、抽象等设计方法。可是,这个定义显然不适合现在的情况。面向对象的思想已经涉及软件开发的各个方面,如面向对象的分析(ObjectOrientedAnalysis,OOA),面向对象的设计(ObjectOrientedDesign,OOD)以及面向对象的编程实现(ObjectOrientedProgramming,OOP)。10.1.1传统开发方法存在的问题传统开发方法存在以下几个问题。1.软件重用性差重用性是指同一事物不经修改或稍加修改就可多次重复使用的性质。传统的程序设计通过库函数的方式来实现重用,实践表明标准函数库缺乏灵活性,往往难以适应不同应用场合的不同要求。对于用户自己设计的功能模块,对它的重用也有限制,一方面要保证功能完全相同,否则需要进行修改,另一方面,过程和数据是相互依赖的,功能的变化往往涉及数据结构的改变,如果新的应用中的数据与原来模块中的数据不同,则对数据进行修改的同时,功能模块也需要修改。2.软件可维护性差软件工程强调软件的可维护性,强调文档资料的重要性,规定最终的软件产品应该由完整、一致的配置成分组成。在软件开发过程中,始终强调软件的可读性、可修改性和可测试性是软件的重要的质量指标。实践证明,用传统方法开发出来的软件,维护时其费用和成本仍然很高,其原因是可修改性差,维护困难,导致可维护性差。3.开发出的软件不能满足用户需要用传统的结构化方法开发大型软件系统涉及各种不同领域的知识,在开发需求模糊或需求动态变化的系统时,所开发出的软件系统往往不能真正满足用户的需要。用结构化方法开发的软件,其稳定性、可修改性和可重用性都比较差,这是因为结构化方法的本质是功能分解,从代表目标系统整体功能的单个处理着手,自顶向下不断把复杂的处理分解为子处理,这样一层一层地分解下去,直到仅剩下若干个容易实现的子功能处理为止,然后用相应的工具来描述各个最底层的处理。因此,结构化方法是围绕实现处理功能的“过程”来构造系统的。然而,用户需求的变化大部分是针对功能的,因此,这种变化对于基于过程的设计来说是灾难性的。用这种方法设计出来的系统结构常常是不稳定的,用户需求的变化往往造成系统结构的较大变化,从而需要花费很大代价才能实现这种变化。10.1.2面向对象的基本概念1.对象对象是人们要进行研究的任何事物,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。我们所指的对象是计算机中的对象,是对现实中对象的模拟,它抽象出现实世界中对象的特征和行为,分别用数据和函数刻画,并封装成一个整体。模拟后的计算机对象既能体现现实世界事物的状态,也具有相应的行为。在不同领域中对于对象有不同理解。一般地认为,对象就是一种事物,一个实体。在面向对象的领域中,则应当从概念和实现形式两个角度来理解对象。从概念上讲,对象是代表着正在创建的系统中的一个实体。例如,一个商品销售系统,像顾客、商品、柜台、厂家等都是对象,这些对象对于实现系统的完整功能都是必要的。从实现形式上讲,对象是一个状态和操作(方法)的封装体。状态是由对象的数据结构的内容和值定义的,方法是一系列的实现步骤,它是由若干操作构成的。对象实现了信息隐藏,对象与外部是通过操作接口联系的,方法的具体实现外部是不可见的。封装的目的就是阻止非法的访问,操作接口提供了这个对象的功能。对象是通过消息与另一个对象传递信息的,每当一个操作被调用时,就有一条消息被发送到这个对象上,消息带来了将被执行的这个操作的详细内容。一般地讲,消息传递的语法随系统不同而不同,其他组成部分包括:目标对象、所请求的方法和参数。2.对象的状态和行为对象具有状态,一个对象用数据值来描述它的状态。对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为。对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中。3.类我们习惯上把具有相同或相似性质的对象划分成类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象。类是创建对象的样板,它包含着所创建对象的状态描述和方法的定义。类的完整描述包含了外部接口和内部算法以及数据结构的形式。由一个特定的类所创建的对象被称为这个类的实例,因此类是对象的抽象及描述,它是具有共同行为的若干对象的统一描述体。类中要包含生成对象的具体方法。类是抽象数据类型的实现。一个类的所有对象都有相同的数据结构,并且共享相同的实现操作的代码,而各个对象有着各自不同的状态,即私有的存储。因此,类是所有对象的共同的行为和不同状态的集合体。类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。4.类的结构在客观世界中有若干类,这些类之间有一定的结构关系。通常有两种主要的结构关系,即一般—具体结构关系,整体—部分结构关系。(1)一般—具体结构称为分类结构,也可以说是“或”关系,或者是“isa”关系。(2)整体—部分结构称为组装结构,它们之间的关系是一种“与”关系,或者是“hasa”关系。5.消息和方法对象之间进行通信的结构叫做消息。在对象的操作中,当一个消息发送给某个对象时,消息包含接收对象去执行某种操作的信息。发送一条消息至少要包括说明接受消息的对象名、发送给该对象的消息名(即对象名、方法名)。一般还要对参数加以说明,参数可以是认识该消息的对象所知道的变量名,或者是所有对象都知道的全局变量名。类中操作的实现过程叫做方法,一个方法有方法名、参数和方法体。消息传递如图10.1所示。10.1.3面向对象的特征(1)对象唯一性。每个对象都有自身唯一的标识,通过这种标识,可找到相应的对象。在对象的整个生命期中,它的标识都不改变,不同的对象不能有相同的标识。(2)分类性。分类性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。(3)继承性。继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。继承性是面向对象程序设计语言不同于其他语言的最重要的特点,是其他语言所没有的。在类层次中,子类只继承一个父类的数据结构和方法,则称为单重继承。在类层次中,子类继承了多个父类的数据结构和方法,则称为多重继承。在软件开发中,类的继承性使所建立的软件具有开放性、可扩充性,这是信息组织与分类的行之有效的方法,它简化了对象、类的创建工作量,增加了代码的可重性。采用继承性,提供了类的规范的等级结构。通过类的继承关系,使公共的特性能够共享,提高了软件的重用性。(4)多态性。多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。多态性允许每个对象以适合自身的方式去响应共同的消息。多态性增强了软件的灵活性和重用性。10.1.4面向对象的要素面向对象的要素包括:(1)抽象。抽象是指强调实体的本质、内在的属性。在系统开发中,抽象指的是在决定如何实现对象之前的对象的意义和行为。使用抽象可以尽可能避免过早考虑一些细节。类实现了对象的数据(即状态)和行为的抽象。(2)封装性(信息隐藏)。封装性是保证软件部件具有优良的模块性的基础。面向对象的类是封装良好的模块,类定义将其说明(用户可见的外部接口)与实现(用户不可见的内部实现)显式地分开,其内部实现按其具体定义的作用域提供保护。对象是封装的最基本单位。封装防止了程序相互依赖性而带来的变动影响。面向对象的封装比传统语言的封装更为清晰、更为有力。(3)共享性。面向对象技术在不同级别上促进了共享同一类中的共享。同一类中的对象有着相同的数据结构。这些对象之间是结构、行为特征的共享关系。在同一应用中共享。在同一应用的类层次结构中,存在继承关系的各相似子类中,存在数据结构和行为的继承,使各相似子类共享共同的结构和行为。使用继承来实现代码的共享,这也是面向对象的主要优点之一。另一种共享是在不同应用中的共享。面向对象不仅允许在同一应用中共享信息,而且为未来目标的可重用设计准备了条件。通过类库这种机制和结构来实现不同应用中的信息共享。(4)强调对象结构而不是程序结构。10.1.5面向对象的开发方法1. Booch方法Booch最先描述了面向对象的软件开发方法的基础问题,指出面向对象开发是一种根本不同于传统的功能分解的设计方法。面向对象的软件分解更接近人对客观事务的理解,而功能分解只通过问题空间的转换来获得。2. Coad方法Coad方法是1989年Coad和Yourdon提出的面向对象开发方法。该方法的主要优点是通过多年来大系统开发的经验与面向对象概念的有机结合,在对象、结构、属性和操作的认定方面,提出了一套系统的原则。该方法完成了从需求角度进一步进行类和类层次结构的认定。尽管Coad方法没有引入类和类层次结构的术语,但事实上已经在分类结构、属性、操作、消息关联等概念中体现了类和类层次结构的特征。3. OMT方法OMT方法是1991年由JamesRumbaugh等5人提出来的,其经典著作为“面向对象的建模与设计”。该方法是一种新兴的面向对象的开发方法,开发工作的基础是对真实世界的对象建模,然后围绕这些对象使用分析模型来进行独立于语言的设计,面向对象的建模和设计促进了对需求的理解,有利于开发出更清晰、更容易维护的软件系统。该方法为大多数应用领域的软件开发提供了一种实际的、高效的保证,努力寻求一种问题求解的实际方法。4. UML(UnifiedModelingLanguage)语言软件工程领域在1995—1997年取得了前所未有的进展,其成果超过软件工程领域过去15年的成就总和,其中最重要的成果之一就是统一建模语言(UML)的出现。UML将是面向对象技术领域内占主导地位的标准建模语言。UML不仅统一了Booch方法、OMT方法和OOSE(面向对象软件工程)方法的表示方法,而且对其作了进一步的发展,最终统一为大众接受的标准建模语言。UML是一种定义良好、易于表达、功能强大且普遍适用的建模语言。它融入了软件工程领域的新思想、新方法和新技术。它的作用域不限于支持面向对象的分析与设计,还支持从需求分析开始的软件开发全过程。10.2面向对象的模型10.2.1对象模型对象模型表示了静态的、结构化的系统数据性质,描述了系统的静态结构,它是从客观世界实体的对象关系角度来描述,表现了对象的相互关系。该模型主要关心系统中对象的结构、属性和操作,它是分析阶段3个模型的核心,是其他两个模型的框架。1.对象和类对象和类涉及以下内容:(1)对象。对象建模的目的就是描述对象。(2)类。通过将对象抽象成类,可以使问题抽象化,抽象增强了模型的归纳能力。类的符号表示如图10.2所示。(3)属性。属性指的是类中对象所具有的性质(数据值)。(4)操作和方法。操作是类中对象所使用的一种功能或变换。类中的各对象可以共享操作,每个操作都有一个目标对象作为其隐含参数。方法是类的操作的实现步骤。2.关联关联用于描述类与类之间的连接。由于对象是类的实例,因此,类与类之间的关联也就是其对象之间的关联。类与类之间有多种连接方式,每种连接的含义各不相同(语义的连接),但外部表示形式相似,故统称为关联。关联关系一般都是双向的,即关联的对象双方彼此都能与对方通信。反过来说,如果某两个类的对象之间存在可以互相通信的关系,或者说对象双方能够感知另一方,那么这两个类之间就存在关联关系。描述这种关系常用的字句是:“彼此知道”“互相连接”等。根据不同的含义,关联可分为普通关联、递归关联、限定关联、或关联、有序关联、三元关联(见图10.3)和聚合7种。比较常用的关联有普通关联、递归关联和聚合。1)普通关联普通关联是最常见的一种关联,只要类与类之间存在连接关系就可以用普通关联表示。比如,作家使用计算机,计算机会将处理结果等信息返回给作家,那么,在其各自所对应的类之间就存在普通关联关系。普通关联的图示是连接两个类之间的直线,如图10.4所示。2)递归关联如果一个类与它本身有关联关系,那么这种关联称为递归关联。任何关联关系中都涉及与此关联有关的角色,也就是与此关联相连的类中的对象所扮演的角色关联中的角色通常用字符串命名。在类图中,把角色的名字放置在与此角色有关的关联关系(直线)的末端,并且紧挨着使用该角色的类。角色名是关联的一个组成部分,建模者可根据需要选用。引入角色的好处是能够指明类和类的对象之间的联系。注意,角色名不是类的组成部分,一个类可以在不同的关联中扮演不同的角色。3)聚合聚合是关联的特例。如果类与类之间的关系具有“整体与部分”的特点,则把这样的关联称为聚合。例如,汽车由车轮、发动机、底盘等构成,则表示汽车的类与表示轮子的类、发动机的类、底盘的类之间的关系就具有“整体与部分”的特点,因此,这是一个聚合关系。识别聚合关系的常用方法是寻找“由……构成”“包含”“是……的一部分”等字句,这些字句很好地反映了相关类之间的“整体-部分”关系。聚合的图示方式为,在表示关联关系的直线末端加一个空心的小菱形,空心菱形紧挨着具有整体性质的类,如图10.8所示,聚合关系中可以出现重数、角色(仅用于表示部分的类)和限定词,也可以给聚合关系命名,图10.8所示的聚合关系表示海军由许多军舰组成。除去上述的一般聚合外,聚合还有两种特殊的聚合方式,即共享聚合和复合聚合。如果聚合关系中的处于部分方的对象同时参与了多个处于整体方对象的构成,则该聚合称为共享聚合。比如,一个球队(整体方)由多个球员(部分方)组成,但是一个球员还可能加入了多个球队,球队和球员之间的这种关系就是共享聚合。共享聚合关系可以通过聚合的重数反映出来,如果作为整体方的类的重数不是1,那么该聚合就是共享聚合,如图10.9所示。如果构成整体类的部分类,完全隶属于整体类,则这样的聚合称为复合聚合。换句话说,如果没有整体类,则部分类也没有存在的价值,部分类的存在是因为有整体类的存在。比如,窗口由文本框、列表框、按钮和菜单组成。整体方的重数必须是零或1,部分方的重数可取任意范围值,如图10.10所示。3.继承一个类的所有信息(属性或操作)能被另一个类继承,继承某个类的子类中不仅可以有属于自己的信息,而且还拥有了被继承类中的信息。引入继承的好处在于由于把一般的公共信息放在父类中,因此处理某个具体特殊情况时只需要定义该情况的个别信息,公共信息从父类中继承得来,增强了系统的灵活性、易维护性和可扩充性。程序员只要定义新扩充或更改的信息就可以了,旧的信息完全不必修改(仍可继续使用),大大缩短了维护系统的时间。继承某类所有信息的具体类,称为子类,被继承类称为父类。可以从父类中继承的信息有属性、操作和所有的关联关系。建模过程如下:(1)识别继承关系。确定了类中应该定义的属性之后,就可以利用继承机制共享公共性质,并对系统中众多的类加以组织。继承关系的建立实质上是知识抽取的过程,它应该反映出一定深度的领域知识,因此必须有领域专家密切配合才能完成。许多归纳关系都是根据客观世界现有的分类模式建立起来的,只要可能,就应该使用现有的概念。一般说来,可以使用以下两种方式建立继承(即归纳)关系。①自底向上:抽象出现有类的共同性质泛化出父类,这个过程实质上模拟人类归纳思维过程。②自顶向下:把现有类细化成更具体的子类,这模拟了人类的演绎思维过程。从应用域中常常能明显看出应该做的自顶向下的具体化工作。例如,带有形容词修饰的名词词组往往暗示了一些具体类。但是,在分析阶段应该避免过度细化。使用多重继承机制时,通常应该指定一个主要父类,从它继承大部分属性和行为;次要父类只补充一些属性和行为。(2)反复修改。在实际的建模过程中,仅仅经过一次建模过程很难得到完全正确的对象模型。事实上,软件建模过程本身就是一个反复修改、逐步完善的过程。在建模的任何一个步骤中,如果发现了模型的缺陷,都必须返回到前期阶段进行修改。由于面向对象的概念和符号在整个开发过程中都是一致的,因此更容易实现反复修改及逐步完善的过程。4.对象模型对象模型由一个或若干个模板组成。模板将模型分为若干个便于管理的子块,在整个对象模型和类及关联的构造块之间,模板提供了一种集成的中间单元,模板中的类名及关联名是唯一的。10.2.2动态模型动态模型是与时间和变化有关的系统性质。该模型描述了系统的控制结构,它表示了瞬间的、行为化的系统控制性质,它关心的是系统的控制,操作的执行顺序,它表示从对象的事件和状态的角度出发,表现了对象的相互行为。该模型描述的系统属性是触发事件、事件序列、状态、事件与状态的组织。使用状态图作为描述工具。它涉及事件、状态、操作等重要概念。1.事件事件是指定时刻发生的某件事。2.状态状态是对象属性值的抽象。对象的属性值按照影响对象显著行为的性质将其归并到一个状态中去。状态指明了对象对输入事件的响应。3.状态图状态图用来描述一个特定对象的所有可能状态及其引起状态转移的事件。大多数面向对象技术都用状态图表示单个对象在其生命周期中的行为。一个状态图包括一系列的状态以及状态之间的转移。10.2.3功能模型功能模型描述了系统的所有计算。功能模型指出发生了什么,动态模型确定什么时候发生,而对象模型确定发生的客体。功能模型表明一个计算如何从输入值得到输出值,它不考虑计算的次序。功能模型由多张数据流图组成。数据流图用来表示从源对象到目标对象的数据值的流向,它不包含控制信息,控制信息在动态模型中表示,同时数据流图也不表示对象中值的组织,值的组织在对象模型中表示。数据流图中包含有处理、数据流、动作对象和数据存储对象。(1)处理。数据流图中的处理用来改变数据值。最低层处理是纯粹的函数,一张完整的数据流图是一个高层处理。(2)数据流。数据流图中的数据流将对象的输出与处理、处理与对象的输入、处理与处理联系起来。在一个计算机中,用数据流来表示中间数据值,数据流不能改变数据值。(3)动作对象。动作对象是一种主动对象,它通过生成或者使用数据值来驱动数据流图。(4)数据存储对象。数据流图中的数据存储是被动对象,它用来存储数据。它与动作对象不一样,数据存储本身不产生任何操作,它只响应存储和访问的要求。10.3面向对象的分析面向对象分析的目的是对客观世界的系统进行建模。以上面介绍的模型概念为基础,结合“银行网络系统”的具体实例来构造客观世界问题的准确、严密的分析模型。分析模型有3种用途:用来明确问题需求;为用户和开发人员提供明确需求;为用户和开发人员提供一个协商的基础,作为后继的设计和实现的框架。10.3.1面向对象的分析过程面向对象的分析过程如图10.15所示。系统分析的第一步是:陈述需求。分析者必须同用户一起工作来提炼需求,因为这样才表示了用户的真实意图,其中涉及对需求的分析及查找丢失的信息。下面以“银行网络系统”为例,用面向对象方法进行开发。银行网络系统问题陈述:设计一个支持银行ATM计算机网络系统的软件。这个网络包括柜员机和自动取款机(ATM),由联营机构共享。每个营业部提供各自的计算机来维护它的账户和处理面临的事务。柜员机属于各营业部,并且直接与营业部计算机通信,柜员输入账务和处理数据。ATM与中心处理机通信。中心处理机分理事务到相应的营业部。ATM接收现金卡,与用户交互,与中心计算机通信完成事务处理,分配现金和打印收据。系统需要恰当的记录和安全保证。系统必须正确控制并发访问同一账号。营业部提供自己的计算机软件。共享系统的费用由各营业部根据现金卡数量来分担。图10.16给出银行网络系统的示意图。10.3.2建立对象模型首先标识和关联,因为它们影响了整体结构和解决问题的方法;其次是增加属性,进一步描述类和关联的基本网络,使用继承合并和组织类;最后操作增加到类中去作为构造动态模型和功能模型的副产品。1.确定类构造对象模型的第一步是标出来自问题域的相关的对象类,对象包括物理实体和概念。所有类在应用中都必须有意义,在问题陈述中,并非所有类都是明显给出的。有些是隐含在问题域或一般知识中的。按图10.17所示的过程确定类。查找问题陈述中的所有名词,产生暂定类。根据下列标准,去掉不必要的类和不正确的类。(1)冗余类:若两个类表述了同一个信息,则保留最富有描述能力的类。(2)不相干的类:除掉与问题没有关系或根本无关的类。(3)模糊类:类必须是确定的,有些暂定类边界定义模糊或范围太广。(4)属性:如果某些名词描述的是其他对象的属性,则从暂定类中删除。如果某一性质的独立性很重要,就应该把它归属到类,而不把它作为属性。(5)操作:如果问题陈述中的名词有动作含义,则描述的操作就不是类。但是具有自身性质而且需要独立存在的操作应该描述成类。2.准备数据字典为所有建模实体准备一个数据字典。准确描述各个类的精确含义,描述当前问题中的类的范围,包括对类的成员、用法方面的假设或限制。3.确定关联两个或多个类之间的相互依赖就是关联。一种依赖表示一种关联,可用各种方式来实现关联,但在分析模型中应删除实现的考虑,以便设计时更为灵活。关联常用描述性动词或动词词组来表示,其中有物理位置的表示、传导的动作、通信、所有者关系、条件的满足等。从问题陈述中抽取所有可能的关联表述,把它们记下来,但不要过早去细化这些表述。所有可能的关联,大多数是直接抽取问题中的动词词组而得到的。在陈述中,有些动词词组表述的关联是不明显的。最后,还有一些关联与客观世界或人的假设有关,必须同用户一起核实这种关联,因为这种关联在问题陈述中找不到。使用下列标准去掉不必要和不正确的关联:(1)若某个类已被删除,那么与它有关的关联也必须删除或者用其他类来重新表述。(2)不相干的关联或实现阶段的关联:删除所有问题域之外的关联或涉及实现结构中的关联。(3)动作:关联应该描述应用域的结构性质而不是瞬时事件。(4)派生关联:省略那些可以用其他关联来定义的关联。因为这种关联是冗余的。4.确定属性属性是个体对象的性质,属性通常用修饰性的名词词组来表示。形容词常常表示具体的可枚举的属性值,属性不可能在问题陈述中完全表述出来,必须借助于应用域的知识及对客观世界的知识才可以找到它们。只考虑与具体应用直接相关的属性,不要考虑那些超出问题范围的属性。首先找出重要属性,避免那些只用于实现的属性,要为各个属性取有意义的名字。按下列标准删除不必要的和不正确的属性:(1)对象:若实体的独立存在比它的值重要,那么这个实体不是属性而是对象。(2)限定词:若属性值取决于某种具体上下文,则可考虑把该属性重新表述为一个限定词。(3)名称:名称常常作为限定词而不是对象的属性,当名称不依赖于上下文关系时,名称即为一个对象属性,尤其是它不唯一时。(4)标识符:在考虑对象模糊性时,引入对象标识符表示,在对象模型中不列出这些对象标识符,它是隐含在对象模型中的,只列出存在于应用域的属性。(5)内部值:若属性描述了对外不透明的对象的内部状态,则应从对象模型中删除该属性。(6)细化:忽略那些不可能对大多数操作有影响的属性。5.使用继承来细化类使用继承来共享公共机构,以此来组织类,可以用两种方式来进行。(1)自底向上通过把现有类的共同性质一般化为父类,寻找具有相似的属性、关系或操作的类来发现继承。有些一般化结构常常是基于客观世界边界的现有分类,只要可能,尽量使用现有概念。对称性常有助于发现某些丢失的类。(2)自顶向下将现有的类细化为更具体的子类。具体化常常可以从应用域中明显看出来。应用域中各枚举字情况是最常见的具体化的来源。当同一关联名出现多次且意义也相同时,应尽量具体化为相关联的类。在类层次中,可以为具体的类分配属性和关联。各属性都应分配给最一般的适合的类,有时也加上一些修正。6.完善对象模型对象建模不可能一次就能保证模型是完全正确的,软件开发的整个过程就是一个不断完善的过程。模型的不同组成部分多半是在不同的阶段完成的,如果发现模型的缺陷,就必须返回到前期阶段去修改,有些细化工作是在动态模型和功能模型完成之后才开始进行的。具体的完善过程如下:(1)对于丢失对象的情况分析及解决办法:·若同一类中存在毫无关系的属性和操作,则分解这个类,使各部分相互关联;·若一般化体系不清楚,则可能分离扮演两种角色的类;·若存在无目标类的操作,则找出并加上失去目标的类;·若存在名称及目的相同的冗余关联,则通过一般化创建丢失的父类,把关联组织在一起。(2)查找多余的类。(3)若类中缺少属性、操作和关联,则可删除这个类。(4)查找丢失的关联。(5)若丢失了操作的访问路径,则加入新的关联以回答查询。10.3.3建立动态模型1.准备脚本动态分析从寻找事件开始,然后确定各对象的可能事件顺序。在分析阶段不考虑算法的执行,算法是实现模型的一部分。2.确定事件确定所有外部事件。事件包括所有来自或发往用户的信息、外部设备的信号、输入、转换和动作,可以发现正常事件,但不能遗漏条件和异常事件。3.准备事件跟踪表把脚本表示成一个事件跟踪表,即不同对象之间的事件排序表,对象为表中的列,给每个对象分配一个独立的列。4.构造状态图对各对象类建立状态图,反映对象接收和发送的事件,每个事件跟踪都对应于状态图中的一条路径。10.3.4建立功能模型功能模型用来说明值是如何计算的,表明值之间的依赖关系及相关的功能,数据流图有助于表示功能依赖关系,其中的处理对应于状态图的活动和动作,其中的数据流对应于对象图中的对象或属性。建立功能模型的具体步骤如下:(1)确定输入值、输出值。先列出输入、输出值,输入、输出值是系统与外界之间的事件的参数。(2)建立数据流图。数据流图说明输出值是怎样从输入值得来的,数据流图通常按层次组织。10.3.5确定操作在建立对象模型时,确定了类、关联、结构和属性,还没有确定操作。只有建立了动态模型和功能模型之后,才可能最后确定类的操作。10.4面向对象的设计1.面向对象设计的概念OOA主要通过对类的认定和划分,以确定问题空间中存在的类、确定类和类的结构等,然后建立一个完整的分析模型。OOD将面向对象分析建立的分析模型变换成设计模型。软件设计人员需要发现相关的对象,将它们的因子化为适当粒度的类、定义类的接口和继承层次结构,并且建立它们之间的关系等。应避免重复设计,至少使重复设计降到最低程度。设计可重用的面向对象软件是困难的,但是,人们总是在设计过程中充分利用重用技术。软件设计完成后,设计人员都试图重用它,并不断地修改该设计,使它不断完善和成熟。OOD把主要的系统构件组织为子系统的系统级“模块”。数据和操作数据的方法被封装为对象,对象(类)是OO系统的构造积木块。OOD必须具有描述对象属性的特定数据结构、数据组织以及个体操作过程的细节。OOD为了实现软件需求,可能引入其他类和对象,也可能为提高软件设计质量和效率而改进类结构。例如,重用类库中的类,通过类的认定和类层次结构的组织,确定解空间中存在的类和类结构,并确定外部接口和主要数据结构等。OOA和OOD很难截然分开,也就是说,面向对象分析与面向对象设计之间不会用阶段和时序来区分。但是,OOD建造系统仍然基于软件设计的基本概念——抽象、信息隐藏、功能独立、模块性等。在传统方法和OOD方法中有10种设计建模的主要构成成分,它们可以用于比较各种传统方法和面向对象设计方法。这10种设计建模的主要构成成分是:①模块层次的表示;②数据定义的规格;③过程逻辑的规格;④端到端处理序列的说明;⑤对象状态和变迁的表示;⑥类及层次的定义;⑦类中操作的表示;⑧操作的详细定义;⑨消息连接的规格;⑩排他服务的标识。2.面向对象系统设计模型传统的设计方法有4个层次——体系结构设计、数据设计、接口设计和构件设计。OOD方法与传统方法相比,也存在以下4个层次:(1)体系结构设计(系统设计);(2)数据设计(当属性被确定);(3)接口设计(当消息模型被开发);(4)构件设计(当对象被认定后进行对象设计等)。值得注意的是,OO设计的“体系结构”更多的是关注对象之间的协助,而不是构件间的功能控制流。系统模型设计过程如下:(1)子系统设计。一个软件系统往往有几个主要组成部分,可以按主题把主要的系统构件组织为子系统。子系统是可以相对独立运作的,各子系统之间具有尽可能简单的明确的接口。子系统设计应包括每一个子系统的表示,这些子系统能够满足用户的软件需求,并且实现支持用户需求的技术设施。(2)类与对象设计。这里应该包括每一个类与对象的表示和类结构的创建。例如类的层次结构的创建,可以用一般化类以及不断逼近目标的特殊化类的机制实现;组装结构可以用分析类的聚集来实现。(3)消息设计。它包括每一个对象能够与协作对象通信的设计细节。通过消息设计建立系统的内部和外部接口。(4)责任设计。它包括每一个对象的所有属性和操作的数据结构以及算法设计(服务、方法的具体实现的细节)。在面向对象系统中,存在着类和通信对象重复出现的模式,利用这些模式可以解决特定的问题,使得面向对象设计更灵活和重用性更好。设计模式是基于过去的经验而帮助设计者重用成功的设计,把设计模式应用于设计问题中,就不需要重复设计。在面向对象系统中,设计模式可以通过应用继承和组合这两种不同的机制被使用。使用继承,现存的设计模式变成了新子类的模板,存在于模式中的属性和操作也被子类所继承而变成子类的一部分;组合导致对象的聚合概念。一个问题可能需要具有复杂功能的对象,复杂对象可以通过选择一组设计模式并且聚合适当的对象组装而成。当然可以考虑继承和组合并存的方法,在实际设计中,往往组合要优先于继承。过分地使用继承会导致类层次越来越庞大而变得难以管理,组合关注的目标是小的类层次和对象,组合可以用不修改的方式使用现存的设计模式——重用构件。每一个设计模式可以被处理为黑盒,在模式之间的通信仅仅通过良好的接口来实现。Rumbaugh方法中的对象建模技术提出的设计活动,有两个不同抽象的级别,即系统设计和对象设计。(1)系统设计。它着重于构造一个完整的软件产品或者系统所有构件的布局。具体来说,系统分析模型被划分为若干个子系统,然后被分配给处理器和任务,实现数据管理的策略被定义,访问它们所需要的全局资源和控制被标识。(2)对象设计。它着重于个体对象的详细布局。具体来说,从系统分析模型中,为对象选择出操作,并且为每一个操作定义算法;适合于属性和算法的数据结构被表示;类和类属性的设计应该能够优化对数据的访问,并提高计算的功效;消息模型被创建,用以实现对象关联。由Coad/Yourdon提出的OOD模型如图10.25所示。该模型表示系统由4个部件组成,即垂直分成4个部分:①主体部件(PDC)设计(问题领域部分);②用户界面部件(HIC)设计(人机交互部分);③任务管理部件(TMC)设计;④数据管理部件(DMC)设计。每一个部件又有5个层次,即水平切片分成5层:①主题层;②类与对象层;③结构层(分类、聚集);④属性层;⑤服务层。虽然有各种各样的设计方法,每一种设计方法有各自不同的术语。但是,整体的OOD过程是基本一致的。为了完成面向对象设计,软件设计人员应该完成下列步骤:(1)描述每个子系统并将其分配到处理器或任务;(2)选择实现数据管理、界面支持和任务管理的设计策略;(3)为系统设计合适的控制机制;(4)通过创建每个操作的过程表示和类属性的数据结构,从而完成对象设计;(5)使用对象间的协作和对象关系,完成消息设计;(6)创建消息模型;(7)评审设计模型并在需要时迭代。3.面向对象设计原则在传统设计中,有5种标准用于判断设计方法的模块化能力,它也可以用于面向对象设计中。(1)分解性(Decomposability):设计方法帮助设计者将一个大型问题分解为易于求解的子问题的程度。(2)组装性(Composability):设计方法保证程序构件(模块)一旦被设计和建造后,可被重用创建其他系统的程度。(3)易理解性(Understandability):程序构件在不参考其他信息或者其他模块的情况下,易于理解的程度。(4)连贯性(Continuity):在程序中进行小修改的能力,这些修改展示它们自己与一个或少数几个模块中对应修改的能力。(5)保护性(Protection):如果一个错误在特定的模块中发生,将减少副作用传播的能力。优秀的面向对象设计应该权衡各种因素,降低设计成本,提高软件的可维护性。根据以上5个设计标准可导出以下的基本原则:(1)模块化。与传统的设计方法一样,面向对象设计方法也支持系统分解和系统模块化的设计原理。实际上对象就可以理解为构件(模块),它是把数据结构和操作这些数据方法紧密地结合在一起的构件(模块)。(2)抽象。面向对象方法不仅支持过程抽象,而且支持数据抽象。类实际上就是一种抽象数据类型,类的公共接口构成了类的规格说明,使用者通过类的接口就可以使用类中定义的数据,无须知道类中具体算法的实现细节和数据元素表示方法,通常把这类抽象称为规格说明抽象。有一些面向对象语言支持参数化抽象。C++语言提供的“模板”机制就是一种参数化抽象机制。由模板定义的类称为参数化类,也称为类属类。类属类本身不依赖具体的数据类型,即与实际操作的基本数据类型无关,它主要描述数据结构的特征。例如,类属栈的主要特征是栈中的元素先进后出,而元素的数据类型作为类属类的参数,在类属类实例化时才确定。这意味着把数据类型作为参数传递。参数化抽象使得类的抽象程度更高,应用范围更广,可重用性更高。(3)信息隐藏。在面向对象方法中,信息隐藏体现在封装性,封装性是重要机制之一,也是软件设计的重要原则之一。把属性和操作封装为对象,对于类的用户而言,属性的表示方法和具体操作的算法实现细节都应该是隐藏的。(4)低耦合。耦合指一个软件结构内不同模块之间互连的紧密程度。在面向对象方法中,对象是最基本的模块,因此,耦合主要指不同对象之间相互关联的紧密程度。低耦合是优秀设计的重要标准之一,低耦合使得系统中某一部分的变化对其他部分的影响降到最低程度。在理想情况下,对某一部分的理解、测试或修改,无须涉及系统的其他部分。如果一个类(对象)过多地依赖其他类(对象)来完成自己的工作,则不仅给理解、测试或修改这个类带来很大困难,而且还将大大降低类的可重用性和可移植性。为了达到低耦合,模块之间应该有很少的接口、很小的接口和显式的接口。很少的接口是指模块之间接口的数量应该最小化;很小的接口就是某一个接口移动的信息量应该最小化;显式的接口就是当模块通信时应该用明显的和直接的方式。如果对象之间的耦合通过消息连接来实现,则这种耦合就是交互耦合。交互耦合应该尽量减少消息中包含的参数个数,降低消息连接的复杂程度,应减少对象发送或接收的消息数。继承耦合是一般化类与特殊类之间的一种耦合形式,应该提高继承耦合程度。为获得紧密的继承耦合,特殊类应该确实是对它的一般化类的一种具体化。在设计时应该使特殊类尽量多继承并使用其一般化类的属性和服务,从而更紧密地耦合到它的一般化类。(5)高内聚。内聚是衡量一个模块内各个元素彼此结合的紧密程度,或者说,设计中使用的一个构件内的各个元素,对完成一个定义明确的目的所做出的贡献程度。设计中应该力求做到高内聚。在面向对象设计中,服务内聚是指一个服务应该完成一个且仅完成一个功能。类内聚就是它的属性和服务应该是高内聚的,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论