您好,欢迎访问三七文档
当前位置:首页 > 建筑/环境 > 设计及方案 > 软件工程-第九章-面向对象设计
软件工程SoftwareEngineering第九章面向对象设计提取了用户需求,建立了问题域模型后,系统分析的任务基本完成。下一步则是将分析的成果用于设计当中。从面向对象分析到面向对象设计,是一个逐渐扩充模型的过程。分析处理以问题为中心,设计则是面向计算机的“实现”开发活动。相对于传统方法中,从数据流图到结构图的变化突然而不连续,分析人员很在跟踪整个设计过程,而面向对象方法学保证了在各个开发阶段之间的平滑过渡,这是面向对象方法与传统方法相比起来所具有的一大优势。9.1设计的准则综合考虑各种因素,使得在整个软件生命周期总开销最小的设计,就是一个优秀的设计。鉴于目前软件维护占了整个软件总费用的60%以上。所以,维护的简易性成为优秀软件设计的主要特点。9.1.1转向面向对象的设计分析阶段给出了一个基于面向对象的软件开发模型,现在是增加各种组成部分以扩充这个模型。具体来说,面向对象分析(OOA)与面向对象设计(OOD)有如下一些关系:①OOA识别和定义的类和对象,是一些直接反映问题空间和系统任务的;而OOD识别和定义的对象则是附加的,反映需求的一种实现。②OOA与OOD分别在不同的抽象层次上进行。OOA是独立于程序设计语言的,属于较高的抽象层次的。但详细OOD则一般都会依赖于程序设计语言,属于较低的抽象层次。③从非面向对象分析到面向对象设计,应将一个非面向对象的需求说明快速转变为面向对象分析模型,用服务说明去跟踪所得到的需求说明中的功能,消除用这种方法未曾发现的漏洞。然后进行初步面向对象的设计,在借助用于实现的程序设计语言进行详细的OOD。9.1.2抽象把众多的事物归纳,划分出一些类是人类在认识客观世界时经常采用的思维方法。分类所依据的原则是抽象,即是忽略事物的非本质特征,只注意那些与当前目标相关的本质特征,从而找出事物的特性,把具有共同性质的事物划分为一类,得到一个抽象的概念。面向对象方法支持过程抽象和数据抽象。类就是一种抽象数据类型,对外提供方法,对内封装数据及实现。使用者可以通过方法来说明数据,通常把这类抽象称为规格说明抽象。此外,某些对象的程序设计语言还支持参数化抽象。9.1.3信息隐藏“信息隐蔽”是指对外尽可能隐藏对象的内部细节,利用有限的对外接口或方法与外界保持联系。9.1.4模块化面向对象软件开发模式很自然地支持了把系统划分成模块的设计原理,对象就是模块,它是由一组属性和对这组属性进行操作的一组服务构成。9.1.5类的设计准则在面向对象的应用中,类实例是系统的主要组成部分,下面列出一些设计类时应考虑的因素和应遵循的准则。(1)类的公共接口的单独成员应该是类的操作符。(2)类A的实例不应直接发送信息给类B的成员。(3)只有当类实例的用户可用,操作符才是公共的。(4)属于类的每个操作符只能赋予修改成访问类中某个数据的权限,两者只能择一。(5)类必须保持独立性,尽可能少地依赖其它类。(6)两个类之间的相互作用应是显式的。(7)采用子类继承超类的公共接口,开发子类成为超类的专用。(8)目标概念的抽象换型应是继承结构中的根类。前四种着重考虑接口的形式及使用,后四种着重类之间的关系。9.1.6面向对象的设计基本原理抽象(过程,数据)封装继承消息组织方法(对象和属性、类专成员、整体与部分)功能分类(基本函数、状态-文件-响应、对象生命历程)分类结论组装结构实例连接消息连接9.1.7软件复用支持软件复用是人们对面向对象方法寄托的主要希望之一。面向对象方法之所以有利于软件复用,是由于它的主要概念及原则与软件复用十分吻合。支持软件复用的OO概念和原则是:对象与类、抽象、封装、继承与一般—特殊结构,聚合与整体—部分结构,粒度控制、多态性。9.1.8面向对象设计的步骤–指出对象及其属性;–指出可能适用于对象的服务;–说明对象及服务;–确定将为对象提供实现描述的详细设计问题;–细化面向对象分析的工作,找出子类、消息特性和其它详尽的细节;–表示与对象属性关联的数据结构;–表示与每个服务关联的过程细节。9.2启发式规则何谓启发式规则,乃是人们使用面向对象方法学的过程中所积累的经验,往往能帮助软件开发人员提高面向对象的质量。9.2.1简单(1)类简单小而简单的类利于开发管理。建议类的定义不超过一页纸(或两屏)。避免包含过多的属性与提供太多的服务,定义明确,简化对象间的合作关系。但由于类的规格较小,则有可能导致类的数目增多,带来一定的复杂性。此时,可将类按分组,划分“主题“予以解决。(2)服务简单简单的服务一般只包含3-5行源程序语句,功能描述用一个简单句子即可。case语句的使用,或者语句嵌套的层次增多,都会导致服务的复杂化。应该设法分解和简化它,譬如对于case语句,可考虑采用一般—特殊结构予以取代。(3)协议简单建议消息中参数不要超过3个,经验表明,通过复杂信息相互关联的对象是紧耦合的,对一个对象的修改往往导致其它对象的修改。9.2.2设计变动尽可能小设计质量的水平与设计结果的稳定性(保持不变的时间)是成正比的。即使必须修改,也应该尽量缩小范围,理想的设计变动曲线如图9-1所示:图9-1理想的设计变动曲线一般情况下,在设计初期变化很大,而后随着设计方案的日趋成熟,变化应该越来越小。图9-1中的峰值对应于出现设计错误或发生非预期变动的情况。峰值越高,表现设计质量越差,可重用性程度越低。9.2.3设计结果的可懂性欲提高软件的维护性及重用性,其中一个主要措施在于使得设计结果清晰易读易懂。以下是对于提高设计结果可读可懂的一些建议。1.一致性命名应与其所代表的事务一致,与人们习惯的名字一致,可从类名较容易的推想到它的用途。不同类中的相似服务器命名应一致,避免模糊的定义。2.使用已有的协议已有的协议包括同一软件的其他设计人员已经建立了的类的协议,及已在所使用的类库中相应的协议。3.减少信息模式的数目在自己建立的消息协议中,建议使信息具有一致的模式,利于读者理解。9.3系统分解在现实世界当中,人们解决复杂的,“大而难”的问题的一般对策是“分而治之”。这同样适用于软件设计当中。首先把系统按照一定的策略分解成若干个较小的部分,再分别设计每个部分。子系统是系统的主要组成部分。划分子系统的原则有很多,但通常均以功能来划分,而且子系统的数目应该与系统规模基本匹配。例如:编译系统可划分为词法分析、语法分析、中间代码生成、优化、目标代码生成和出错处理等子系统。在划分和设计子系统时,应遵循下列几个原则:1.应保持设计的各个子系统相对独立。2.减少子系统彼此间的依赖性。3.每个子系统应具备尽可能简单、明确的接口,子系统之间的交互形式及信息流传递由接口确定。4.不须规定子系统内部的实现算法。9.3.1子系统之间的两种交互方式子系统之间存在两种可能的交互方式,分别是客户-供应商(CLIENT-SUPPLIER)关系和平等伙伴(PEERTOPEER)关系。1.客户-供应商关系“供应商”子系统提供借口作为“客户”的子系统的调用,并返回结果给“客户”。2.平等伙伴关系相对前者而言,在这种关系中,每个子系统都是客户,亦都是供应商,可以互相调用9.3.2组织系统的两种方案可以采用水平层次方案或垂直块组织方案将子系统组织成完整的系统。1.层次组织一个系统中的各个子系统构成一个层次结构,每层是一个子系统,各层内部所包含的对象彼此间相互独立,而不同层之间的对象却往往存在关联。层次结构又可分为两种模式:封闭式和开放式。封闭式上层只能调用其直接下层提供的服务。开放式上层可以调用其下面任意一层所提供的服务。通常,需求陈述中只描述了对系统顶层和底层的需求,将目标系统,即用户看到的那部分置于顶层,供调用的资源全部置于底层。两层之间差异很大,这要求设计者设计一些中间层次,在减少概念差异的同时,将顶层底层首尾有效的具体的联系起来。2.块状结构整个软件系统由垂直分解地若干个相对独立的、弱耦合的子系统所组成,每个垂直子系统称作块,提供一种类型的服务。可以单独利用层次结构和块状结构将多个子系统组成一个完整的软件系统,当然可以混合的使用层次结构和块状机构,用若干块组成一层,而同一块也可以分为若干层。图9-2是一个运用层状块状混合结构来表示的一个应用系统的组织结构。图9—2混合结构表示9.3.3设计系统的拓扑结构子系统可利用一些典型的拓扑,如树型、星型,管道型来组成完整的系统。设计应该以简单,减少子系统之间的交互数量为原则,采用与问题结构相适应的拓扑结构。9.4设计问题域子系统在面向对象分析阶段,得出的概念模型已描述了我们要解决的问题,为设计问题域子系统奠定了良好的基础。在设计阶段,应当继续OOA阶段的工作,保持已经建立的结构,对其进行改进和增补。主要是根据需求的变化,对OOA产生的模型中的某些类与对象、结构、属性、操作进行组合和分解。由于面向对象方法的优越性,可在分析与设计阶段保持问题域组织框架的一致性,从而便于跟踪分析、设计和编程的结果。在设计过程中进行的修改,不会影响结果的稳定性。以下为读者列出可能对问题域模型进行改进和增补的几个方面。1.调整需求:需求的变化可能贯穿于软件开发的全过程,但是这种变化出现的越早越好,就越容易更改。其变化主要来自于以下两点:分析初期对问题域不甚了解,导致面向对象分析模型不能完整准确地反映用户的真实需求。用户需求或外部环境的变化。2.复用设计:可以通过重用已有类的方法来从设计阶段开始实现代码重用。如果因为没有合适的类供重用,在创建新类时必须考虑到将来的可重用性。重用已有类的典型过程如下:①根据问题解决的需要,在问题的解决方案中添加从类库或其他来源得到的既存类。②在被重用的已有类和问题域类之间添加归纳关系(即从被重用的已有类派生出问题域类),增加从既存类到应用类之间的一般-特殊化关系。③进一步把标出应用中因继承既存类而成为多余的属性和服务。④修改与问题域类相关的关联,改为与被重用的已有类相关的关联,修改应用类的结构和连接,必要时把它们变成可复用的既存类。3.把问题域类组合在一起。在设计中,设计者往往从类库中因近一个根类,作为包容类,而把问题域类组合在一起,建立了类的层次。把同一问题论域的一些类集合起来,存于类库中。此外,这样的根类还可以用来建立协议。4.加入一般化类以建立类间协议有时,某些特殊类要求一组类似的服务,或者还需要相应的属性。在这种情况下可以引进一个一般化的类(例如根类),以定义虚函数的形式建立这个协议,定义为所有这些特殊类共用的一组服务名。5.对继承机制的分析因为在分析阶段可建立的模型是独立于程序设计语言的,所以可能包括有多继承关系,但是不同的程序设计语言对继承级别的支持不同,有些可能只有单继承,甚至没有继承机制,这样就需对分析结果进行修改,稍作一些调整。–分几种情况讨论:①使用多重机制使用多重机制时应该避免出现属性及服务的命名冲突。图9-3是多继承模式。这种模式可以成为窄菱形模式户或叫做狭义的菱形。图9-4是另一种多重继承的模式,成为阔菱形模式或者叫做广义的菱形。图9-3窄菱形模式图9—4阔菱形模式②使用单继承机制如果所用的程序设计语言仅支持单继承,则必须把多重继承结构转换为单继承结构。有两种常见的转换方法,下面结合汽车类的例子,进行说明。使用映射分解多重映射在两个层次间建立整体-部分关系或关联关系称之为映射。通过映射可将多重继承结构分解成两个层次。把特殊类的对象看作是一个一般类对象所扮演的角色,通过实例连接把多继承的层次结构转换为单继承的层次结构。例如,图9-4所示的多重继承关系,可以分解成如图9-5或图9-6所示的单重继承关系图9—5利用整体-部分关系改多重继承为单继承图9—6利用关联将多重继承为单继承化为单一层次把多继承的层次结构平铺,成为单继承的层次结构,如图9-7所示。显然,在多重继承结构中的某些一般-特殊关系,经简化后将不再出现。在这种情况下,有些属性或服务在同层的特殊类中会重复出现。图9—7将多重继承调整为单继承不具备继承机制建议软件设计者尽最大可能使用支持
本文标题:软件工程-第九章-面向对象设计
链接地址:https://www.777doc.com/doc-4007943 .html