面向对象设计
- 格式:docx
- 大小:34.79 KB
- 文档页数:11
面向对象的设计概述
OOA和OOD之间有紧密的衔接关系,从OOA到OOD是一个慢慢扩充模型的进程。分析处置以问题为中心,能够不考虑任何与特定运算机有关的问题,而OOD那么把咱们带进了面向运算机的“实地”开发活动中去。通常,OOD分为两个时期,即高层设计和低层设计。高层设计成立应用的体系结构。低层设计集中于类的详细设计。
(1) 高层设计
高层设计时期开发软件的体系结构,构造软件的总体模型。在那个时期,标识在运算机环境中进行问题解决工作所需要的概念,并增加了一批需要的类。这些类包括那些可使应用软件与系统的外部世界交互的类。现在期的输出是适合应用软件要求的类、类间的关系、应用的子系统视图规格说明。通常,利用面向对象设计取得的系统框架如图所示。
① 高层设计模型
一个典型的高层设计模型即客户-效劳器模型,它构造起应用软件的整体模型,那个模型导出的体系结构既可在进程性系统中利用,又可在面向对象的系统中利用。
客户-效劳器模型的方式是让系统的一个部份(效劳器子系统)提供一组效劳给系统的另一个部份(客户子系统)。请求效劳的对象都归于客户子系统,而同意请求提供效劳的部份确实是效劳器。
图 OOD设计导出的体系结构
② 高层设计的规那么
▪ 最小化各构件间的通信:在子系统的各个高层构件之间的通信量应当达到最小。一个用户界面应当能够自行处置交互、错误更正和硬件操纵,而不需打搅主应用。
▪ 隐藏复杂性:子系统应当把那些成组的类打包,形成高度的内聚。
▪ 逻辑功能分组:尽管输入和输出设备可能彼其间不通信,但逻辑上把它们归组到一个处置输入/输出的子系统中。如此比较容易识别并定位问题论域中的事件。
类与通过概念封装的子系统十分类似。事实上,每一个子系统都能够被当做一个类来实现,那个类聚集它的构件,提供了一组操作。类和子系统的结构是正交的,一个单个类的实例可能是不止一个子系统的一部份。
高层设计时期增加了一批必要的类,要紧包括了那些可使应用软件与系统的外部世界交互的类。这些交互那么包括与其它软件系统(如数据库治理系统、鼠标和键盘)的界面,与利用来进行数据搜集或负责操纵的硬件设备的界面等。
高层设计能够表征为标识和概念模块的进程。但这种模块能够是单个的类,还能够是由一些类组合成的子系统。概念进程是职责驱动的。
高层设计和类设计这两个时期是相对封锁的。在这种情形下,应用软件中的每一个事物都是一个对象,包括应用软件自身在内! 依照那个思想,这两个时期又是连接的。应用软件的设计是大类的设计,这种类设计考察应用软件所期望的每一个行为,并利用这些行为形成应用类的界面。
(2) 类设计的目标和方针
类设计的第一步是标识应用所需的概念。应用分析进程包括了对问题论域所需的类的模型化;但在最终实现应历时不只有这些类,还需要追加一些类。类设计的要紧目标如下:
① 单一概念的模型 :在分析与高层设计时期, 常常需要利用多个类来表示一个“概念”。一样人们在利用面向对象方式开发软件时,常常把一个概念进行分解,用一组类来表示那个概念。固然,也能够只用一个独立的类来表示一个概念。
② 可复用的构件 :咱们希望所开发的构件能够在以后的应用中利用。因此,需要一些附加特性。例如,在相关的类的集合中界面的标准化
③ 靠得住的构件 :应用软件必需是靠得住的(健壮的和正肯概念的)软件。而这种靠得住性与它的构件有关。每一个构件必需通过充分的测试。但由于本钱关系,往往测试不够完备。但是,若是咱们要成立可复用的类,那么通过测试确保构件的靠得住性是绝对必要的。
④ 可集成的构件 :咱们希望把类的实例用到其它类的开发和应用中,这要求类的界面应当尽可能小,一个类所需要的数据和操作都概念在类概念中。因此,类的设计应当尽可能减少命名冲突。面向对象语言的消息语法可通过辨别带有实例名的操作名来减少可能的命名冲突。
类结构提供的封装使得把概念集成到应用的工作变得很容易。封装特性保证了把一个概念的所有细节都组合在一个界面下,而信息隐蔽那么保证了实现级的名字将可不能其它类的名字相互干扰。 咱们讨论的方针是类的模块设计的方针,还要给出类设计质量的气宇。
① 信息隐蔽 :软件设计通过信息隐蔽可增强抽象,并可爱惜类的存储表示不被抽象数据类型实例的用户直接存取。对其表示的唯一存取途径只能是界面。
② 消息限制 :类的设计者应当为类的命令设计一个明确的界面,该类实例的用户应当只利用界面提供的操作。
③ 狭小界面 :不是所有的操作都是公共的。只有对其它类的实例是必要的操作才放到界面上,其它操作应是隐蔽实现的部份。
④ 强内聚 :模块内部各个部份之间应有较强的关系
⑤ 弱耦合 :一个单独模块应尽可能不依托于其它模块。若是在类A的实例中成立了类B的实例,或若是类A的操作需要类B的实例做为参数,或若是类A是类B的一个派生类,那么称类A“依托于”类B。一个类应当尽可能少地依托于其它类。
耦合程度部份依托于所利用的分解方式。类A之因此依托于类B,是因为类A要求类B提供效劳。那个依托性可通过复制类A中的类B的功能来排除。但代码的复制减少了系统的灵活性并增加了保护的困难。继承结构损害了弱耦合的概念。因为在成立一样化-特殊化关系的时候,继承引入了依托。
⑥ 显式信息传递 :除依托于最少的类外,还应该明确在这些类之间的信息流。在类之间全局变量的共享隐含了信息的传递,而且是一种依托形式。因此,两个类之间的交互应当仅涉及显式信息传递。显式信息传递是通过参数表来完成的。
⑦ 派生类当做派生类型 :继承结构的利用是面向对象开发方式的一大特色。每一个派生类应该当做基类的特殊化来开发,而基类所具有的公共界面成为派生类的共有界面的一个子集。C++许诺设计者选择类的基类是共有的或私有的。若是基类是共有的,那么其共有界面将成为新的派生类的共有界脸部份,这说明基类的行为成为派生类的行为部份。这种似于类型与派生类型之间的关系。若是基类是私有的,它的行为将不是继承类的公共行为部份而是实现部份。它的提出是为了提供实现新类的效劳。
⑧ 抽象类 :某些语言提供了一个类,用它做为继承结构的开始点,所有效户概念的类都直接或间接以那个类为基类。Smalltalk提供了一个类Object做为所有类的继承树的根,而C++那么支持多重继承结构。每一种结构都包括了一组类,它们是(或应该是)某种概念的特殊化。那个概念应抽象地由结构的根类来表示。因此,每一个继承结构的根类应当是目标概念的一个抽象模型。那个抽象模型生成一个类,它不用于产生实例。它概念了一个最小的共有界面,许多派生类能够加到那个界面上以给出概念的一个特定视图。
(3) 通过复用设计类
利用既存类来设计类,有4种方式:选择,分解,配置和演变。这是面向对象技术的一个重要优势。许多类的设计都是基于既存类的复用。
① 选择 :设计类最简单的方式是从既存构件中简单地选择合乎需要的构件。这确实是开发软件库的目的。一个OO开发环境应提供经常使用构件库,大多数语言环境都带有一个原始构件库(如整数、实数和字符),它是基础层。任一大体构件库(如“大体数据结构”构件)都应成立在这些原始层上。这些都是些一样的可复用的类。那个层还包括一组提供其它应用论域效劳的一样类,如窗口系统和图形图
图 建立子类 元。表显示了成立在这些层上面的特定域的库。最低层的论域库包括了应用论域的基础概念并支持普遍的应用开发。特定项目和特定组的库包括一些论域库,它包括为相应层所概念的信息。
表 一个面向对象构件库的层次
特定组的构件 ─ 一个小组为他们自己组内所有成员使用而开发
特定项目的构件 ─ 一个小组为某一个项目而开发
特定问题论域的构件 ─ 购自某一个特定论域的软件销售商
一般构件 ─ 购自专门提供构件的销售商
特定语言原操作 ─ 购自一个编译器的销售商
② 分解 :最初标识的“类”常常是几个概念的组合。在设计时,可能会发觉所标识的操作落在分散的几个概念中,或会发觉,数据属性被分开放到模型中拆散概念形成的几个组内。如此咱们必需把一个类分成几个类,希望新标识的类容易实现,或它们已经存在。
③ 配置 :在设计类时,可能会要求由既存类的实例提供类的某些特性。通过把相应类的实例声明为新类的属性来配置新类。例如,一种仿真效劳器可能要求利用一个计时器来跟踪效劳时刻。设计者没必要开发在那个行为中所需的数据和操作,而是应当找到计时器类,并在效劳器类的概念中声明它。
④ 演变 :要开发的新类可能与一个既存类超级类似,但不完全相同。现在,不适宜采纳“选择”操作,但能够从一个既存类演变成一个新类,能够利用继承机制来表示一样化-特殊化的关系。特殊化处置有三种可能的方式。
▪ 由既存类成立子类 :现要成立一个新类“起重车”。它的许多属性和效劳都在既存类“汽车”中。关系如下图。新类是既存类的特殊情形。这时直接让“起重车”类作为“汽车”类的子类即可。
② 成立继承层次由既存类成立新类 :现要增加一个新类“拖沓机”。它的属性与效劳有的与“汽车”类相同,有的与“汽车”类不同。关系如下图。这时,调整继承结构。成立一个新的一样的“车辆”类,把“拖沓机”与“汽车”类的共性放到“车辆”类中,“拖沓机”与“汽车”类都成为“车辆”类的子类。“车辆”是抽象类,相关操作到子类“汽车”类去找。
拖拉机类 车辆
汽车 拖拉机 汽车类 起重车
类
图 调整继承结构
③ 成立既存类的父类 :另一种情形是想在既存类的基础上加入新类,使得新类成为既存类的一样类。例如,已经存在“三角形”类,“四边形”类,想加入一个“多边形”类,并使之成为“三角形”和“四边形”类的一样类。继承结构如下图。从那个“多边形”类又可派生出新的类,如“六边形”类。
图 成立一样类
后两种涉及既存类的修改。在这两种情形下,既存类中概念的操作或数据被移到新类中。若是遵循信息隐蔽和数据抽象的原理,这种移动应不阻碍已有的利用这些类的应用。类的界面维持一致,尽管某些操作是通过继承而不是通过类的概念伸到那个类的。
(4) 类设计方式
通常,类中的实例具有相同的属性和操作,应当做立一个机制来表示类中实例的数据表示、操作概念和引用进程。这时,类的设计是由数据模型化、功能概念和ADT概念混合而成的。类是某些概念的一个数据模型,类的属性确实是模型中的数据域,类的操作确实是数据模型许诺的操作。要明确规定它们两个谁先确信是不可能的,两个处置是互补的。
类的标识有主动和被动之分。被动类是数据为中心的,它们是依照系统的其它对象发送来的消息而修改其封装数据的;主动类那么提供许多系统必需履行的大体操作。与被动类的实例(被动对象)一样,主动类的实例(主动对象)接收消息,但这些对象是负责发送追加消息和操纵某些应用部份的。在窗口环境,一个窗口是一个被动对象,它基于发送给窗口的消息来显示某些内容。窗口治理器是一个主动对象,它担负着各类在它操纵的窗口上的操作。
在被动类与主动类的设计之间不存在明显的不同。在设计主动类时,需要优先确信数据模型,稍后再确信操作;在设计被动类时,把类提供的效劳翻译成操作。在标识了效劳以后再设计为支持效劳所需要的数据。许多类都是这两个极端的混合。