第9章面向对象的分析设计与实现主要学习内容:传统方法学的缺点面向对象的基本概念面向对象分析面向对象设计面向对象实现9.1传统方法学存在的缺点1、存在的问题生产率提高的幅度远不能满足需要。传统的软件工程方法需要的人力,物力都比较多,流程比较长,所以它的生产率的提高并不快软件重用程度很低。作为结构化软件设计,程序设计,分析技术等,都是针对问题空间提出的解决方案,而没有考虑提出一些能适用于另外一个程序的模块软件仍然很难维护个软件项目。虽然有很多方法为软件提供功能,性能的维护,但当软件运行时,仍然有很多困难,所以不得不找到原来的开发人员。软件往往不能真正满足用户需要。需求分析之后,后面的人就跟用户没关系了,直到验收测试时才请用户过来,这时用户说,这段时间为什么不找我,我们单位里面有些变化,所以不能真正满足用户需要。9.2面向对象的基本概念9.2.1基本概念1.对象对象是系统中描述客观事物的一个实体,它是构成系统的一个基本单位,由一组属性和对这组属性进行操作的一组服务组成。属性是用来描述对象静态特征的一个数据项2.类类是具有相同属性和服务的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述,其内部包括属性和服务两个主要部分9.2.1基本概念3.类对象类对象指的是类和类中的对象,其符号表示如图9-2所示,类分3个区域,对象用围绕着类的三个区域的虚框表示,在表示类的3个区域内,标出类对象的名称、属性及服务,这是具有对象的类,是一种具体类。4.消息消息是对象发出的服务请求,一般包含提供服务的对象标识、服务标识、输入和应答等信息。5.封装性封装性是把对象的属性和服务结合成一个独立的系统单位。6.继承性继承性是指子类可以自动拥有父类的全部属性和服务7.多态性不同层次中的类可以共享或共用一个行为(方法)的名子,但在不同层次中,每个类却可以各自按自己的需要来实现这个行为,并且得到不同的结果。8.事件事件是建立动态模型时常用的术语,是指某一时刻引发对象状态改变的控制信息。现实世界中,各对象之间相互触发,一个触发行为就称作是一个事件。9.状态状态也是建立动态模型时常用的术语,是对象所具有的属性值的一种抽象,按照影响对象显著行为的性质将值集中归并到一个状态中去。10.行为行为也是建立动态模型时常用的术语,是对象要达到某种状态时所做的操作9.2.2面向对象建模1、对象模型对象模型是用来描述系统数据结构。主题层通过划分主题把一个大型,复杂的对象模型分解几个不同的概念范畴。类与对象层类实体结构层类与对象之间的关系属性层对象的固有数据服务层服务或方法2.动态模型动态模型是用来描述系统控制结构,描述对象在遇到某些事件时它的响应,意味着每个对象实际上有自已的状态,并且这个状态是可保持的事件:引发对象状态改变的控制信息(瞬时)状态:即对象的attributes所处的情形(可持续)行为:对象要达到某种status所做的操作(耗时)3.功能模型功能模型是用来描述系统功能。要考虑整个软件系统是一个整体,具有什么样的功能。在面向对象里面,对象模型确定了发生操作的客体,动态模型确定操作什么时候发生,功能模型指出发生了什么操作,所以功能模型是操作的一个实体,由多张数据流图组成,数据流图说明数据流是如何从外部输入,经过操作和内部存储输出到外部的。9.3面向对象分析9.3.1面向对象分析的特点1.有利于对问题及系统责任的理解2.有利于对人员之间的交流3.对需求变化有较强的适应性4.支持软件重用9.3.2需求陈述需求陈述包括问题范围、功能需求、性能要求、应用环境、假设条件等五个方面。如一个远程教育学院,想做一个学位查询系统,就可以发个招标公告向社会去招标,某公司想去应标,要根据招标书上的要求,写出相应的应标书,应标书上有相当一大部分内容是需求陈述,要写出关于开发出的这个学位查询系统所能具备的功能、性能、可靠性、接口和应用环境等方面的内容,同时给出当某些特殊情况存在时的解决方案等等。9.3.3建立对象模型1.确定类-&-对象(1)列出所有候选对象。跟据需求陈述里面的名词列出所有候选对象,这些对象可能是物理实体,也可以是人或组织或要处理的事件,也可以是对象间的活动,如上面提到的远程教育学院学位查询系统中,可以确定以下类-&-对象,分别是学生,系统,服务器,客户机,教师,网络,成绩,科目,软件,类别,院,系,班级,学年,家庭住址,联系电话,及格,账户,事务,学校,学士,性别,分数,学制,信息,密码,类型,访问,校园网。(2)去粗取精。把以上所有可能的候选对象进行抽象,找到哪个是实体,哪一个是属性。如学生,教师,院,学校等是实体,而成绩,性别,分数等是属性。2.确定关联(1)收集要收集需求陈述中涉及对象的动词短语。关联常用描述性动词或动词词组来表示,如“服务器,客户机组成网络”,“学位录入系统设置在学校内部”等。收集需求陈述中对象间隐含的关联如“学位的获取由各个学年成绩决定”,“学校保管学生和老师的帐户”等。根据问题域知识得出的关联如“成绩等于平时成绩和卷面折合成绩之和”等。2.确定关联(2)筛选删除与已删去的对象有关的关联。在上例中如果删除对象“网络”,则与“网络”相关联的“校园网”也删去。删除与问题无关的或应在实现阶段考虑的关联,包括瞬时事件、三元关联和派生关联。瞬时事件要注意关联描述的静态结构。如“学生访问服务器查学位”描述了学生和服务器进行交互周期中的一个动作,它并不是服务器与学位之间的固有关系,因此应该删去。三元关联要分解为二元关联或限定关联。如“教师输入针对成绩的事务”可以分解成“教师输入事务”和“事务修改成绩”这样两个二元关联。派生关联是去掉可用其它关联定义的冗余关联,如“学校管理帐户”的实际含义是“学校保管账户”和“事务修改账户”。(3)完善完善包括正名、分解补充和标明阶数几部分,正名就是给出个容易理解的名字。分解补充是将一个综合功能的事务分解为两个单一功能的事务,如将查询事务分解为远程事务和终端事务。标明阶数就是这个对象或类跟多少个其它对象或类有关联。3.划分主题关联主题,属性都属于对象模型里面的某一个视图,划分关联一般注意两方面.一方面是按问题域将这个问题大概分为几块另一方面是主题间的依赖和交互尽可能少。4.确定属性首先,要识别属性,要明白某个类的对象应该描述什么东西,属性不表示对象之间的关系,只表示其本质性质,一些数字性的性质,如学生具有学号、姓名、性别等属性。另外,在确定属性时暂不考虑纯用于实现的属性(即单纯的内部状态)。还有在需求陈述中与已确定的对象有关的名词、形容词可能是选择的线索。这些名词、形容词可能是属性的后选,如每个学生都有成绩,成绩这就是一个属性。5.识别继承关系一般从两方面识别继承关系,一方面是自底向上,将具有相同属性的类向上归纳出父类。一方面是自顶向下,将现有类向下细化出子类,识别出从上到下的继承的层次,这样便于在建立对象模型时的组织结构。6.反复修改在以上五个步骤之后,还要对已经得到的类-&-对象、关联、属性、结构反复进行推敲和修改,并及时与用户进行沟通,复审,以便得到更具体,准确的模型9.3.4建立动态模型1.编写脚本一般编写脚本有以下三种情况的脚本,一种是正常情况脚本,正常运行时执行的脚本程序。另一种是特殊情况脚本,在输入或输出需要取边界值时执行的脚本程序。第三种是异常情况脚本,由于用户不懂计算机程序,避免不了会在操作中出现失误,这时需要执行用户进行异常中止或取消操作的脚本。2.设想用户界面用户界面的美观程度、方便程度、易学程度、效率都是需要考虑的因素,一般这时会做几个用户界面方案,并用相关软件画出来,供用户参考,让用户确定能够令其满意的界面。3.画事件跟踪图在确定事件之后需要画出事件跟踪图。在事件跟踪图中,一条竖线代表一个对象,每个事件用一条水平的箭头线表示,箭头方向从事件的发送对象指向接受对象。时间从上向下递增,也就是说,画在最上面的水平箭头线代表最先发生的事件,画在最下面的水平箭头线所代表的事件最晚发生。箭头线之间的间距并没有具体含义,图中仅用箭头线在垂直方向上的相对位置表示事件发生的先后,并不表示两个事件之间的精确时间差4.画状态图状态图是描述一个实体基于事件反应的动态行为,显示了该实体如何根据当前所处的状态对不同的时间做出反应的。5.审查动态模型9.3.5建立功能模型1、画出基本系统模型图本系统模型由若干个数据源点/终点,及一个处理框组成,这个处理框代表了系统加工、变换数据的整体功能。基本系统模型指明了目标系统的边界。由数据源点输入的数据和输出到数据终点的数据,是系统与外部世界之间的交互事件的参数2.画出功能级数据流图3.描述处理框功能为每个处理框添加详细的功能描述,并形成一个说明文档9.3.6定义服务1.对象的基本服务。1)存在服务工:指最一般的服务,即创建、变动、删除及选择等操作。2)计算服务:一个实例需要另一个实例加工结界时,所需的服务。3)监控服务:模型中某些部件需要快速实时处理时,所需的服务。2.对象的特殊服务3.认定消息关联4.对服务进行说明9.4面向对象设计9.4.1面向对象设计准则1.模块化对象被定义为模块,对象把数据结构和作用在数据上的操作封装起来构成模块,成为组成系统的基本。2.抽象抽象是抽出事物的本质、内在的特性,忽略一些无关紧要的属性。3.信息隐藏信息隐藏通过对象的封装性实现,类结构分离了接口和实现,那么对于类用户来讲,属性的表示方法和操作的实现算法是隐藏的。用户只能通过公共接口访问类中的属性。4.弱耦合5.强内聚在面向对象设计中,内聚可分为下述3类。(1)服务内聚。模块是单一的,一个模块只完成一项任务或一个服务只完成一种功能。(2)类内聚。类内聚要求类的属性和服务应该是高内聚的,而且它们应该是系统任务所必须的。一个类只有一个功能或用途,如果这个类有多个功能,通常把它分解成多个专用的类。(3)一般——特殊内聚。一般——特殊结构符合领域知识的表示形式,即特殊类应该尽量地继承一般类的属性和服务,它们是通用性和特殊性的一种方式,这种结构是高内聚的。6.可重用1)是尽量使用已有的类(包括弄好环境提供的类库,及以往开发类似系统时创建的类)。2)是如果确实需要创建新类,则在设计这些新类的协议时,应该考虑将来的可重复使用性。9.4.2启发规则1.设计结果应该清晰易懂(1)命名一致。命名应该与专业领域中的名字一致,并且要符合人们的习惯。不同类中相似服务的名字应该相同。(2)重用协议(公共接口)。在设计中应该使用已经建立了的类协议,避免重复劳动或重复定义带来的差异,或不统一,这些协议或是其它设计人员已经建立了的类协议,也可能是类库中已有的协议。(3)减少消息连接。尽量采用已有标准的消息连接,去掉不必要的消息连接。采用统一模式建立自己需要的消息连接,也就是说尽量减少消息模式的数目,增强可理解性和可使用性。(4)避免模糊定义。应该定义具有明确、有限用途的类,避免那些模糊的,不准确的类的定义。2.一般——特殊结构的深度应适当一般来说,在一个中等规模(大约包含100个类)的系统中,类层次数应保持为7±2。3.设计简单的类(1)避免包含过多的属性。。(2)避免提供太多服务。一般来说,一个类提供的公共服务不要超过7个。(3)明确精练的定义。通常用几个简单的语句描述一个类的任务。(4)简化对象间的通信。4.使用简单的协议一般来说,简单消息中的参数不要超过3个,因为过多的参数会导致对象的修改复杂。5.使用简单的服务类中的服务应该设计得既简单又小,用3~5行源程序代码比较合适。6.把设计变动减至最小随着设计方案逐渐成熟,改动也应该越来越小,这样才能设计出优良的结果9.4.3系统分解可以把面向对象设计模型的四大组成部分想象成整个模型的四个垂直切片。1.子系统之间的两种交互方式(1)客户——供应商关系(2)平等伙伴关系2.组织系统的两种方案(1)水平层次组织这种组织方案把软件系统组织成一个层次系统,每层是—个子系统。(2)垂直块组织这种组织方案把软件系统垂直地分解成若