您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 薪酬管理 > 第10章 面向对象设计(简化版)
华北电力大学计控学院第10章面向对象设计10.1.1面向对象设计过程(1)建立系统环境模型。下图给出了系统环境图的一般的结构。(2)设计系统体系结构。(3)对各个子系统进行设计。(4)对象设计及优化。10.1.1面向对象设计过程模块化面向对象方法中的模块是类、对象、接口、构件等。在面向过程的方法中,数据及在数据上的处理是分离的;而在面向对象方法中,数据及其上的处理是封装在一起的,具有更好的独立性,也能够更好地支持复用。10.1.2面向对象设计准则信息隐藏在面向对象方法中,信息隐藏通过对象的封装性实现。对于类的用户来说,属性的表示方法和操作的实现算法都应该是隐藏的。弱耦合耦合是指软件结构内不同模块之间互连的紧密程度。在面向对象方法中,对象是最基本的模块,因此,耦合主要指不同对象之间相互关联的紧密程度。类与对象之间的耦合分为两种:交互耦合与继承耦合。10.1.2面向对象设计准则交互耦合如果对象之间的耦合通过消息连接来实现,则这种耦合就是交互耦合。为使交互耦合尽可能松散,应该遵守下述准则。减少对象发送(或接收)的消息数。尽量降低消息连接的复杂程度。尽量减少消息中包含的参数个数;降低参数的复杂程度。10.1.2面向对象设计准则继承耦合继承是一般化类与特殊类之间的一种耦合形式。从本质上看,通过继承关系结合起来的基类和派生类,构成了系统中粒度更大的模块。一般化类与特殊类之间结合得越紧密越好。与交互耦合相反,应该提高继承耦合程度。10.1.2面向对象设计准则强内聚内聚是指模块内各个元素彼此结合的紧密程度。在面向对象设计中,存在以下3种内聚:(1)服务内聚:一个服务应该完成一个且仅完成一个功能。(2)类内聚:设计类的原则是,一个类应该只有一个用途,它的属性和服务应该是高内聚的。如果某个类有多个用途,(3)一般—特殊内聚:设计出的一般—特殊结构,应该符合多数人的概念,更准确地说,这种结构应该是对相应的领域知识的正确抽取。10.1.2面向对象设计准则可重用软件重用是提高软件开发生产率和目标系统质量的重要途径。重用有两方面的含义:一是尽量使用已有的类(包括开发环境提供的类库,及以往开发类似系统时创建的类);二是如果确实需要创建新类,则在设计这些新类的协议时,应该考虑将来的可重复使用性。10.1.2面向对象设计准则体系结构设计描述了建立计算机系统所需的数据结构和程序构件。一个好的体系结构设计要求软件模块的分层及编程标准的执行。在面向对象软件中,常见的软件模块有类、接口、包和构件。在设计阶段我们往往关注类、接口和包,在实现阶段关注构件,而在部署阶段则关注构件的部署,也就是将构件部署在哪些结点上。10.2体系结构模块及依赖性在面向对象程序设计中,类和接口是程序的基本组成单元。类的依赖性继承依赖性交互依赖性10.2.1类及其依赖性继承依赖性继承是一种在父类和子类之间共享属性和行为的方式。继承会带来类和方法之间的依赖性。扩展继承:子类继承父类的属性和方法,并增加一些属性和方法,即增量式继承,是恰当的继承方式。约束继承:子类覆盖了继承来的方法,并对一些继承来的功能进行了限制。可能会给维护带来问题。从语言实现角度,继承分为编译时继承依赖性(静态绑定)和运行时继承依赖性(动态绑定)。类及其依赖性类及其依赖性①编译时继承依赖性右图所示的例子说明了一棵树中类之间的编译时依赖性。在这个例子中,B继承A,但没有覆盖A中的方法do1()。因此,B和A之间没有运行时继承依赖性。也就是说,由于编译时依赖性的存在,A中do1()方法的任何变化,都会被B在编译时(静态地)继承。一般来说,所有的继承都会引入编译时依赖性。依赖性是可传递的,也就是说,如果C依赖B,B依赖A,那么C也依赖A。a.do2();②运行时继承依赖性类B的do1()方法是从父类A继承来的,因此Test与B没有运行时继承依赖性,只是一个静态依赖性,通过从Test到A的关联来表明。如果在doTest方法中调用的是do2()方法,或者在B中覆盖了A的do1()方法,则从Test到A和B就会存在运行时依赖性。类及其依赖性滥用继承的问题类及其依赖性交互依赖性交互依赖性也称为方法依赖性,是通过消息连接产生的。类及其依赖性接口是不可直接实例化的特性集合的声明,即其对象不能直接实例化,需要通过类来实现,实现接口的类需要实现接口中声明的方法。接口和抽象类很相似,但其实有着本质的区别。在只支持单继承的语言中,一个类只能有一个直接父类,但是却可以实现多个接口。接口的依赖性分为实现依赖性和使用依赖性。接口及其依赖性实现依赖性在UML2.0中,将一个类和该类实现的接口之间的依赖性称为实现依赖性。接口及其依赖性使用依赖性一个接口所需要的其他接口所提供的服务称为这个类的需求接口。需求接口详细说明一个类或接口需要的服务,从而可以为其客户提供服务。在UML2.0中,通过类(接口)和它所需接口之间的依赖关系来说明需求接口,这称为使用依赖性。下图所示为使用依赖性的UML符号,在箭头尾部的类或接口使用在箭头头部的接口。Class1使用Interface1,Interface1使用Interface2。在Java语言中,不允许接口之间的使用,只允许接口间的扩展继承。接口及其依赖性包(package)又称为层或子系统,是组织类的一种方式,用于划分应用程序的逻辑模型。包可以嵌套。外层包可以直接访问内嵌包中的任何类。包可以导入其他包。在包A中导入了包B,这意味着包A或者包A的元素可以引用包B或者包B的元素。包的导入操作会引入包之间的依赖性以及它们的元素之间的依赖性。包及其依赖性人机交互界面窗口包之间的依赖性来自于两个包中类之间的依赖性。如果包A的一些成员引用了包B的某些成员(包A导入了包B的一些成员),这隐含着双重含义。包A只能和包B一起使用。包B的变化可能会影响包A,通常需要对包A重新进行编译和测试。包及其依赖性包及其依赖性包的循环依赖包之间的循环依赖是特别棘手的问题,好在大多数情况下可以通过重新设计避免循环依赖性。通过在上图中增加新包可以消除包之间的循环依赖性。方法为:在第1个例子中将包B依赖的包A的元素从包A中分离出来,组成包C,使得包B不再依赖包A,而是依赖包C;包及其依赖性在第2个例子中,将包F所依赖的包D中的元素从包D中分离出来,组成包G。消除循环依赖性后如下图所示。包及其依赖性10.3系统分解子系统和类在大型和复杂的软件系统情形,首先根据需求的功能模型(用例模型),将系统分解成若干个部分,每一部分又可分解为若干子系统或类,每个子系统还可以由更小的子系统或类组成。系统结构的类图10.3系统分解Coad&Yourdon的面向对象设计模型Coad&Yourdon基于MVC(Model-View-Controller)模型,在逻辑上将系统划分为4个部分,分别是问题域部分、人机交互部分、任务管理部分及数据管理部分,每一部分又可分为若干子系统。Coad与Yourdon在设计阶段中继续采用了分析阶段中提到的5个层次,用于建立系统的4个组成成分。每一个子系统都由主题、类-&-对象、结构、属性和服务5个层次组成。这5个层次可以被当作整个模型的水平切片。10.3系统分解典型的面向对象设计模型10.3系统分解子系统之间的两种交互方式客户-供应商关系:在这种关系中,客户子系统调用供应商子系统,后者完成某些服务工作并返回结果。使用这种交互方案,作为客户的子系统必须了解作为供应商的子系统的接口,而后者却无须了解前者的接口。平等伙伴关系:在这种关系中,每个子系统都可能调用其他子系统,因此每个子系统都必须了解其他子系统的接口。与第一种方案相比,这种方案中,子系统间的交互更加复杂。典型的面向对象系统一般由三层组成,即数据库层、业务逻辑层及用户界面层。面向对象的设计是以面向对象分析的模型为基础的。面向对象的分析模型包括有用例图、类图、顺序图和包图,主要是对问题领域进行描述,基本上不考虑技术实现,当然也不考虑数据库层和用户界面层。面向对象分析所得到的问题域模型可以直接应用于系统的问题域部分的设计。类的三种形式边界类(BoundaryClass):位于系统与外界的交界处,包括窗体、报表、打印机等硬件接口以及与其他系统的接口。边界类使角色能与系统交互。实体类(EntityClass):表示系统将跟踪的持久信息。控制类(ControlClass):将边界类和实体类关联起来(通常被称为控制器,因为它们通常不是真正的对象)完成指定的功能。。类的三种形式类的符号边界类:参与者通过该对象与系统交流。实体类:代表具体的问题领域对象。控制类:该对象在边界对象与实体对象中扮演“粘合剂”帐户取款处理用户操作台边界类实体类控制类类图实例新建顾客帐户操作员顾客不存在顾客交易计算累积点数计算消费金额/生成报表执行租片界面打印报表报表获得交易信息影片10.4问题域部分的设计对分析得到的问题域模型做以下补充或调整。(1)调整需求一是用户需求或外部环境发生了变化;二是分析员对问题理解不透彻,导致分析模型不能完整、准确地反映用户的真实需求。10.4问题域部分的设计(2)复用已有的类选择有可能被重用的已有类,尽量重用那些能使无用的属性和服务降低到最低程度的类。在被复用的已有类和问题域类之间添加泛化(一般化∕特殊化)关系,继承被复用类或构件属性和方法。标出在问题域类中因继承被复用的已有类或构件而成为多余的属性和服务。修改与问题域类相关的关联。10.4问题域部分的设计(3)把问题域类组合在一起通常要引入一个类,将问题域类组合在一起,它起到“根”类的作用,将全部下层的类组合在一起。当没有一种更满意的组合机制可用时,可以从类库中引进一个根类,作为包容类,把所有与问题领域有关的类关联到一起,建立类的层次。人角色医务角色教育角色医生医学教授教授根10.4问题域部分的设计(4)增添泛化类以建立类间的协议有时某些问题域的类要求一组类似的服务(以及相应的属性)。此时,以这些问题域的类作为特化的类,定义一个泛化类。该泛化类定义了为所有这些特化类共用的一组服务名,作为公共的协议,用来与数据管理或其他外部系统部件通信。这些服务都是虚函数。在各个特化类中定义其实现。(5)调整继承的支持级别使用单继承机制化为单一层次把多继承的层次结构平铺,成为单继承的层次结构。在这种情况下,有些属性或操作在同层的特殊类中会重复出现。使用映射分解多重继承把特殊类的对象看做是一个一般类对象所扮演的角色,通过实例连接把多继承的层次结构转换为单继承的层次结构。10.4问题域部分的设计化为单一层次把多继承的层次结构平铺,成为单继承的层次结构。这种情况下,有些属性或操作在同层的特殊类中会重复出现。人教授医生医学教授人教授医生医学教授使用映射分解多重继承把特殊类的对象看做是一个一般类对象所扮演的角色,通过实例连接把多继承的层次结构转换为单继承的层次结构。医务角色教育角色人角色nn人角色医务角色教育角色医生医学教授教授根10.4问题域部分的设计(6)改进性能1)如果类之间经常需要传送大量消息,可合并相关的类,使得通信成为对象内的通信,而不是对象之间的通信,或者使用全局数据作用域,打破封装的原则,以减少消息传递引起的速度损失。2)增加某些属性到原来的类中,或增加低层的类,以保存暂时结果,避免每次都要重复计算造成速度损失。10.5人机交互部分的设计用户界面设计步骤(1)从系统的输入、输出及与用户的交互中获得信息,定义界面对象和行为(操作)。(2)定义那些导致用户界面状态发生变化的事件,对事件建模。(3)描述最终向用户展示的每一个界面的状态。(4)简要说明用户如何从界面提供的界面信息来解释系统状态。10.7数据管理部分的设计在传统的结构化设计方法中,很容易将实体-关系图映射到关系数据库中。而在面向对象设计中,我们可以将UML类图看作是数据库的概念模型,但在UML类图中除了类之间的
本文标题:第10章 面向对象设计(简化版)
链接地址:https://www.777doc.com/doc-3565784 .html