480 likes | 668 Views
第 8 章 面向对象的设计方法 教学目的:了解面向对象设计的概念和方法。 教学重点:面向对象的设计方法。 教学难点:面向对象的设计方法。. 第 8 章 面向对象的设计方法. 面向对象设计是将面向对象分析所创建的分析模型进一步细化形成软件设计模型的过程。如果说,分析模型描述了系统需要完成的功能,在设计阶段则描述了如何实现分析阶段所定义的软件功能 本章介绍面向对象设计的概念,并主要介绍 Coad / Yourdon 的面向对象设计方法的细节问题。. 8.1 面向对象设计的概念.
E N D
第8章 面向对象的设计方法 教学目的:了解面向对象设计的概念和方法。 教学重点:面向对象的设计方法。 教学难点:面向对象的设计方法。
第8章 面向对象的设计方法 • 面向对象设计是将面向对象分析所创建的分析模型进一步细化形成软件设计模型的过程。如果说,分析模型描述了系统需要完成的功能,在设计阶段则描述了如何实现分析阶段所定义的软件功能 • 本章介绍面向对象设计的概念,并主要介绍Coad/Yourdon的面向对象设计方法的细节问题。
8.1 面向对象设计的概念 • 面向对象分析的任务是解决系统“做什么”的问题。而在面向对象设计阶段则着重完成“如何做”的问题,也就是着重考虑对象的实现细节。设计阶段可能扩展分析阶段所定义类的属性和方法,这些扩展的方法和属性都是实现类行为所必须的,同时扩展的属性和方法应该是内部的。因为定义对象的外部行为是分析阶段的任务。为了实现系统的功能,在设计阶段还可能引入其他的类和对象。
8.1.1 对象、操作和消息 • 在面向对象的设计过程中,数据结构和对数据结构的操作被封装到了对象里,因此对象成了面向对象设计的基本单位,对象之间通过消息进行连接。
8.1.2 类、实例和继承 • 具有共同属性的对象的抽象就是类。本质上,类是对象的模板,通过类可以生成具有该类的特性的对象,该对象称为该类的一个实例,这个过程就是类的实例化。 • 继承提供了一种重用对象的方式,基类(父类)是派生类(子类)的更通用化的抽象。 比如,通过提取取款类、存款类以及转帐类的共同特点就可以抽象出具有一般特性的概念类:交易类。
8.1.2 类、实例和继承 ClassA 图8-1-1 类的继承关系 ClassB
8.2 面向对象的设计方法 • 由Cord和Yourdon提出面向对象的OOD模型如图8-2-1,模型由用户交互部件(HIC)、问题域部件(PDC)、任务管理部件(TMC)和数据管理部件(DMC)组成。 • 每个部件又由主题层、类与对象层、结构层、属性层和服务层组成。五层分别对应面向对象分析的五个活动:定义主题词、标识对象、标识对象所属的类、标识对象的属性和行为。
8.2 面向对象的设计方法 问 题 域 部 件 PDC 用 户 交 互 部 件 HIC 任 务 管 理 部 件 TMC 数 据 管 理 部 件 DMC 主题层 图8-2-1 Cord/Yourdon 的OOD模型 类及对象层 结构层 属性层 服务层
8.2 面向对象的设计方法 • 问题域部件包括完成目标系统主要功能所必须的类或对象。 • 用户界面部件定义用于完成人机交互所必须的类或对象。 • 任务管理部件定义了用于协调系统中各个任务所必须的类或对象。 • 数据库管理部件定义用于实现平台无关的数据操作的类和对象。 • OOD是在OOA模型的基础上对OOA模型进行扩展和精化,从而得到系统设计的过程描述。
8.2.1 问题域部件(PDC)的设计 • 问题域部件的设计是通过对分析阶段模型的扩展和调整,使之满足可修改性和可重用性的目标和要求,并给出为完成系统功能所需要的类、对象、属性和操作的实现细节。
“扩展和调整OOA模型”策略 1.重用已有软部件 1)使用非面向对象的组件 如果软部件库中包含计算利息的面向过程的部件CalculateInterest(AccountID aid),在设计CAccount类时就可以重用这个部件对该帐号进行记息。也就是在CAccount的CalculateInterest方法中直接调用该过程部件CalculateInterest(AccountID aid)即可,从而达到了重用非面向对象软部件的目的。
“扩展和调整OOA模型”策略 2)使用面向对象的软部件 假设组件库中包含CCalcuInterest类用于计算帐号的利息,那么重用可以采用下面的方式: • 继承: class CAccount:public CCalcuInterest { ....... }
聚合: class CAccount { public: CCalcuInterest m_cci; ..... } • 直接使用: CAccount::CalculateInterest() { CCalcuInterest cci(this); cci.CalculateInterest(); }
“扩展和调整OOA模型”策略 2.引入新父类,分组管理相关类 • 主要目的: 增加类库结构的清晰度,便于管理相关类,从而进一步支持软件重用。 如:在银行系统中,为了增加所有业务类之间的亲缘关系,为所有的业务类引入一个公共的父类:CBankObject。其类图如图8-2-2所示。
CBankObject CTransaction CAccount CBank 2.引入新父类,分组管理相关类 图8-2-2 “银行系统”业务类类图
“扩展和调整OOA模型”策略 3.引入新父类,简化软件设计与编码 OOA模型中并没有对类的共性进行适当的识别。在某些场合,若干类由一组类似的操作或属性。在设计主体部件时,可引入一个新类,在新类中提供所有公共操作的协议,而把各个操作的细节隐藏在子类的定义中。
例子 • 在“银行系统”中,无论是转帐、取款和存款都有共性的操作,把这个共性的操作抽象出来形成一个新类CTransaction,便可以提高系统的可修改性和可重用性。转帐、取款和存款的共性包括属性:帐号;操作:交易和保存交易日志。在子类中(如CDeposit)需要重新实现Transaction和SaveLog操作,因为在子类中,要给出操作的具体语义或实现。如图8-2-3所示
CTransaction account:CAccount Transaction() SavaLog() 图8-2-3 提取交易对象的共性 CDeposit CWithdraw CTransfer
“扩展和调整OOA模型”策略 4.转换继承结构适应实现的限制 在面向对象分析和设计阶段,虽然并不涉及到面向对象编程语言,但是由于不同的面向对象的语言对面向对象概念的支持层次不一样,所以在设计阶段要考虑不同面向对象语言的限制。常见的限制是面向对象语言是否支持多重继承。
转换的方法有如下几种: 1)将多重继承结构分离成部分-整体的关系 一个人员可以具备多个角色,而角色则可以是店员、店主等,具体实现很简单,在人员类中聚合多个角色对象,每个对象代表人员应具有的角色,聚合对象可以用线性表来管理。如图8-2-5。 2)平板化 所谓平板化就是将多重继承类在类的继承层次中上移,使纵向结构向横向结构转化,也就是平板化。图8-2-4中的多重继承经过平板化后如图8-2-6。多重继承平板化后某些属性和操作将在子类中被重复定义,因而会影响面向系统的性能。
店主兼店员 人员 人员 图8-2-4 多重继承 图8-2-5 用部分-整体的关系 表示多重继承 角色 店主 店员 店主 店员
人员 图8-2-6 多重继承平板化 店员 店主 店主兼店员
“扩展和调整OOA模型”策略 5.调整OOA模型,提高软件的执行速度 通过合并相互通信频繁的类或对象,可降低因对象之间的通信而给系统带来的性能损失,从而提高系统的效率。另外还可以在类中增加属性或直接增加用于低级操作的类,用以保存中间结果,等等。 6.设计复审 依据高内聚度、低耦合度及简单性等软件设计原则进行设计复审。
8.2.2 用户界面部件(HIC)的设计 • 在分析阶段确定人机交互的属性和外部服务,在设计阶段则要给出人机交互的全部细节。其中包括: ①用户如何与系统交互; ②系统如何响应用户的命令; ③系统的正常操作、成功、以及操作失败时的 提示信息; ④如果系统中包含复杂的输出,如报表或查询 结果,也应在设计阶段给出详细的格式。
用户接口部件的设计过程: 1)熟悉用户并对用户进行合理的分类 通常按照用户的熟练程度、工作性质和权限对用户进行分类。以便设计与用户层次相适应的用户界面。 2)选取用户代表并分析其工作流程与习惯 。 一般的做法是为每一类用户选取代表,对其工作流程与操作习惯进行分析并建立调查表。
用户接口部件的设计过程 • 调查表应包括如下的内容: ①姓名; ②期望软件用途; ③自然特征(年龄、文化程度、限制等); ④主要要求与喜好; ⑤技术熟练程度; ⑥任务客观场景描述。
用户接口部件的设计过程 3)设计并优化命令系统 在设计命令系统时,应该遵循界面设计的原则和规范。通过对用户的分析确定命令系统的原型,然后进行命令系统的优化。命令系统通常表现为菜单、工具栏或按钮。 优化命令时应先考虑命令使用的频度,应该给常用的命令提供快捷键。
用户接口部件的设计过程 4)对用户界面的细节进行设计 包括界面一致性、耗时操作的状态显示、“撤销”和“重做”机制、帮助用户记忆操作序列、自封闭的集成环境等等。 5)增加用户界面类 用户界面类的设计有赖于系统平台以及开发中所使用的底层类库。系统级的窗口包括microsoft的Windows,Unix下的XWindow等。通常开发环境会提供功能强大的界面类库。 6)为用户演示快速原型,依据用户的反馈意见改进界面设计
CTransferWnd CWithdrawWnd CDepositWnd CWnd 图8-2-7 “银行系统”窗口类图
8.2.3 任务管理部件(TMC)的设计 • 任务通常指软件功能需求所载明的软件应完成的功能。任务管理器则用于协调各个功能的调度和执行。在OOA中并未引入任务管理部件,是因为在分析阶段并未涉及系统的具体实现细节。在OOD阶段引入任务管理部件有两点原因: ①多用户、多任务系统之上开发应用程序的需 要; ②通过任务管理部件协调各个子系统之间的通 信和协同;
任务管理部件设计步骤 ①识别由事件驱动的任务 事件一般来自外系统、硬件或用户的处理请求。 当用户在银行系统中点击存款菜单时,就启动了由该菜单事件触发的存款任务。 ②识别时间驱动的任务 时间驱动的任务一般指与时间相关的任务,该任务由时间来触发。如银行系统每月一次的计算利息的任务,就是时间驱动的任务。 ③识别关键性任务及任务的优先级 关键任务是指可靠性高,关系到系统成败的重要任务。在银行系统中,“转帐”、“取款”、“存款”等均属关键性任务。识别关键性任务的同时还要对任务的优先级进行排队,以便任务管理部件对任务进行正确的调度。
任务管理部件设计步骤 ④定义任务协调器 如果系统中包含三个以上的任务,那么系统中应该定义一个任务协调器类用于协调、调度和仲裁系统中的任务。 ⑤定义任务 经过①、②、③步建立的任务草稿要经过详尽的定义和描述。在描述中说明任务的名称、功能、优先级、包含此任务的服务、该任务与其他任务的协同方式。表8-1示出了转帐任务的定义。
任务管理部件设计步骤 ⑥必要时在OOD中扩充有关任务的类和对象,调整原有的语法成分,以适应任务定义的要求。 如果在设计类时违背了高内聚的原则,比如单个类完成多于一个的不相关的任务。必须调整设计。通常一个类只用于实现一个任务。
CTask TName TDescribe TPrivilege TService TCooperateMode TCommunicateMode Initialize() Startup() Wait() Shutdown() CTaskCooperate Cooperate() 图8-2-8 TMC的任务类和任务协调器类 1 m
8.2.4 数据管理部件(DMC)的设计 • 主要目的是将目标软件系统中依赖于开发平台的数据存取部分与其他功能进行分离,从而使数据存储部分与业务逻辑(数据处理)部分进行充分的去耦合。这样在数据设计或业务逻辑发生改变时,可以使改变只限定在各自的部件范围之内,而不会扩散至其他部件。 • 数据存取通过数据管理系统(文件系统、关系数据库或面向对象数据库)来实现。业务逻辑和数据操作的分离同时又有利于软件的扩充、移植、维护并能减少测试的工作量。
举例 • 比如银行系统,可能先前的配置文件(数据部分)使用的是数据库表,由于频繁的访问数据库导致系统响应时间增长。用户提出要提高效率(降低系统的响应时间)的新需求,这样配置数据的存取就要改成效率更高的文件方式。如果先前的系统没有采用数据和业务逻辑分离的设计方式。修改设计将是一个痛苦的过程,如图8-2-9所示。在主体部件内对数据管理系统的操作分布在不同的类的不同方法中,当数据管理系统的设计和实现改变时,对主体部件改动的工作量将会很大。
主体部件 BClass1 BClass2 BClassn 图8-2-9 主体部件直接操作数据管理系统 ······ 数据管理系统(文件或数据库)
举例(续) • 如果我们在主体部件和数据管理系统之间使用数据管理部件进行隔离,数据管理系统设计和实现的改变就不会影响到主体部件,如图8-2-10所示。在数据管理系统改变时,只须在数据管理部件中做相应的修改即可。
主体部件 BClass1 BClass2 BClassn ······ 图8-2-10主体部件通过数据管理部件操作数据管理系统 数据管理部件(DMC) 数据管理系统(文件或数据库)
8.2.4 数据管理部件的设计 • 无论基于哪种数据管理方法,DMC设计都包括定义数据格式和定义相应操作两部分。 1.定义数据格式 1)文件系统: 以表格的形式给出每个类的所有属性: ①将所有表格规范为一阶范式; ②为每个范式定义一个文件; ③针对存储限制和性能要求评估已获得的结果, 迫不得已时只得牺牲范式形式。
8.2.4 数据管理部件的设计 • 为了使文件具有自描述性,文件中的每个记录都由标志名、开始标志、登录项目和结束标志四部分组成。而在数据管理部件的每个定义中应相应地增加属性“标志名”和“按登陆方式存储对对象的操作”。同时还要设计一个分析器,负责对文件的各个字段进行解析,并还原出原来的对象。
8.2.4 数据管理部件的设计 2)关系型数据库: ①列表给出每种类定义的所有属性; ②将所有表规范为第三范式; ③为每一范式定义一个关系; ④针对存储限制和其他性能要求评估已 获得的结果,必要时回退到第二或更 低的范式。
8.2.4 数据管理部件的设计 • 对于由关系数据库扩充而来的面向对象数据库(OODB)。其数据格式的定义步骤基本与关系数据库的定义步骤类似。如果OODB由OOPL扩充而来,则无需对属性进行规范化,因为对象的存储已由数据库系统本身来完成。
8.2.4 数据管理部件的设计 2.定义相应的操作 • 对于数据管理部件类,应该为其增加一个属性和一个操作。增加的属性用于说明对象所属的类。增加的操作用于完成存储和提取操作。因为该属性和方法属于数据管理部件类的实现细节,所以一般不作为外部属性和方法并为外部使用。
8.2.4 数据管理部件的设计 2.定义相应的操作 • Coad和Yourdon建议在设计数据库管理部件时,创建一个数据库管理部件类的根类,并将其称之为对象服务器(object-server)类。该类的职责有两个: 1)通知对象存储自身。 2)检索对象的值,并用检索值初始化对象。
8.2.4 数据管理部件的设计 2.定义相应的操作 • 以上操作通常被称为串行化(Serialize)或对象持久化(Object Persistence)。 • 如图8-2-11所示。在银行系统的数据管理部件中,定义了全部数据管理类的根类CObejectServer,它定义了数据操作的全部功能。通过继承,数据管理部件中的类都具备了更新和初始化的能力。