1、第第8 8章章 面向对象设计面向对象设计 从面向对象分析到面向对象设计从面向对象分析到面向对象设计(通常通常缩写为缩写为OOD),是一个,是一个逐渐扩充模型逐渐扩充模型的过的过程。或者说,面向对象设计就是用面向对程。或者说,面向对象设计就是用面向对象观点建立象观点建立求解域求解域模型的过程。模型的过程。 尽管分析和设计的定义有明显区别,尽管分析和设计的定义有明显区别,但是在实际的软件开发过程中二者的但是在实际的软件开发过程中二者的界限界限是模糊的是模糊的。 许多分析结果可以直接映射成设计结许多分析结果可以直接映射成设计结果,而在设计过程中又往往会加深和补充果,而在设计过程中又往往会加深和补充对
2、系统需求的理解,从而进一步完善分析对系统需求的理解,从而进一步完善分析结果。因此,分析和设计活动是一个多次结果。因此,分析和设计活动是一个多次反复迭代反复迭代的过程。的过程。 面向对象设计的准则面向对象设计的准则8.1启发规则启发规则8.2设计人设计人_机交互子系统机交互子系统8.5设计问题域子系统设计问题域子系统8.4系统分解系统分解8.3设计任务管理子系统设计任务管理子系统8.6小小 结结8.12设计优化设计优化8.10面向对象分析与设计实例面向对象分析与设计实例8.11设计关联设计关联8.9设计类中的服务设计类中的服务8.8设计数据管理子系统设计数据管理子系统8.7 所谓优秀设计,就是权
3、衡了各种因素,所谓优秀设计,就是权衡了各种因素,从而使得系统在其整个生命周期中的总从而使得系统在其整个生命周期中的总开开销最小销最小的设计。的设计。 8.1.1 8.1.1 模块化模块化 对象就是模块对象就是模块。它是把数据结构和操。它是把数据结构和操作这些数据的方法紧密地结合在一起所构作这些数据的方法紧密地结合在一起所构成的模块。成的模块。 8.1.2 8.1.2 抽象抽象 面向对象方法不仅支持过程抽象,而面向对象方法不仅支持过程抽象,而且支持数据抽象。类实际上是一种且支持数据抽象。类实际上是一种抽象数抽象数据类型据类型。 8.1.3 8.1.3 信息隐藏信息隐藏 在面向对象方法中,信息隐藏
4、通过对在面向对象方法中,信息隐藏通过对象的封装性实现。象的封装性实现。 8.1.4 8.1.4 弱耦合弱耦合 耦合主要指不同对象之间耦合主要指不同对象之间相互关联相互关联的的紧密程度。一般来说,对象之间的耦合可紧密程度。一般来说,对象之间的耦合可分为两大类,下面分别讨论这两类耦合。分为两大类,下面分别讨论这两类耦合。 1. 1.交互耦合交互耦合 如果对象之间的耦合通过如果对象之间的耦合通过消息连接消息连接来来实现,则这种耦合就是交互耦合。为使交实现,则这种耦合就是交互耦合。为使交互耦合尽可能松散,应该遵守下述准则。互耦合尽可能松散,应该遵守下述准则。 尽量降低消息连接的复杂程度。尽量降低消息连
5、接的复杂程度。 减少对象发送减少对象发送( (或接收或接收) )的消息数。的消息数。 2. 2.继承耦合继承耦合 与交互耦合相反,应该与交互耦合相反,应该提高继承耦合提高继承耦合程度程度。为获得紧密的继承耦合,特殊类应。为获得紧密的继承耦合,特殊类应该确实是对它的一般化类的一种具体化。该确实是对它的一般化类的一种具体化。 8.1.5 8.1.5 强内聚强内聚 1. 1.服务内聚服务内聚 一个服务应该完成一个且仅完成一个一个服务应该完成一个且仅完成一个功能。功能。 2. 2.类内聚类内聚 设计类的原则是,一个类应该只有一设计类的原则是,一个类应该只有一个用途,它的属性和服务应该是高内聚的。个用途
6、,它的属性和服务应该是高内聚的。 3. 3.一般一般特殊内聚特殊内聚 设计出的一般设计出的一般特殊结构,应该符合特殊结构,应该符合多数人的概念,更准确地说,这种结构应多数人的概念,更准确地说,这种结构应该是对相应的领域知识的正确抽取。该是对相应的领域知识的正确抽取。 8.1.6 8.1.6 可重用可重用 一是尽量一是尽量使用已有的类使用已有的类(包括开发环境包括开发环境提供的类库,及以往开发类似系统时创建提供的类库,及以往开发类似系统时创建的类的类),二是如果确实需要创建新类,则在,二是如果确实需要创建新类,则在设计这些新类的协议时,应该设计这些新类的协议时,应该考虑将来考虑将来的的可重复使用
7、性。可重复使用性。 8.2.1 8.2.1 设计结果应该清晰易懂设计结果应该清晰易懂 使设计结果清晰、易读、易懂,是提使设计结果清晰、易读、易懂,是提高软件可维护性和可重用性的重要措施。高软件可维护性和可重用性的重要措施。保证设计结果清晰易懂的主要因素有以下保证设计结果清晰易懂的主要因素有以下几点:几点: 1. 1. 用词一致用词一致 2. 2. 使用已有的协议使用已有的协议 3. 3. 减少消息模式的数目减少消息模式的数目 4. 4. 避免模糊的定义避免模糊的定义 8.2.2 8.2.2 一般一般特殊结构的深度特殊结构的深度应适当应适当 应该使类等级中包含的层次数适当。应该使类等级中包含的层
8、次数适当。 8.2.3 8.2.3 设计简单的类设计简单的类 应该尽量设计小而简单的类,以便于应该尽量设计小而简单的类,以便于开发和管理。开发和管理。 1. 1. 避免包含过多的属性避免包含过多的属性 2. 2. 有明确的定义有明确的定义 3. 3. 尽量简化对象之间的合作关系尽量简化对象之间的合作关系 4. 4. 不要提供太多服务不要提供太多服务 8.2.4 8.2.4 使用简单的协议使用简单的协议 一般来说,消息中的参数不要超过一般来说,消息中的参数不要超过3个。个。 8.2.5 8.2.5 使用简单的服务使用简单的服务 面向对象设计出来的类中的服务通常都很小,面向对象设计出来的类中的服务
9、通常都很小,一般只有一般只有3 35 5行源程序语句,可以用仅含一个行源程序语句,可以用仅含一个动动词和一个宾语的简单句子描述它的功能。词和一个宾语的简单句子描述它的功能。 8.2.6 8.2.6 把设计变动减至最小把设计变动减至最小 通常,设计的质量越高,设计结果保通常,设计的质量越高,设计结果保持不变的时间也越长。持不变的时间也越长。图图8.1 8.1 理想的设计变动情况理想的设计变动情况 大多数系统的面向对象设计模型,在大多数系统的面向对象设计模型,在逻辑逻辑上都由上都由四大部分四大部分组成。这四大部分对组成。这四大部分对应于组成目标系统的四个子系统,它们分应于组成目标系统的四个子系统,
10、它们分别是别是问题域子系统问题域子系统、人人- -机交互子系统机交互子系统、任任务管理子系统务管理子系统和和数据管理子系统数据管理子系统。 在不同的软件系统中,这四个子系统在不同的软件系统中,这四个子系统的重要程度和规模可能相差很大,规模过的重要程度和规模可能相差很大,规模过大的在设计过程中应该进一步划分成更小大的在设计过程中应该进一步划分成更小的子系统,规模过小的可合并在其他子系的子系统,规模过小的可合并在其他子系统中。统中。图图8.2 8.2 典型的面向对象设计模典型的面向对象设计模型型 8.3.1 8.3.1 子系统之间的两种交互方式子系统之间的两种交互方式 在软件系统中,子系统之间的交
11、互有两种在软件系统中,子系统之间的交互有两种可能的方式,分别是可能的方式,分别是客户客户供应商供应商关系和关系和平等伙平等伙伴伴关系。关系。 1. 1. 客户客户供应商关系供应商关系 2. 2. 平等伙伴关系平等伙伴关系 总的说来,单向交互比双向交互更容总的说来,单向交互比双向交互更容易理解,也更容易设计和修改,因此应该易理解,也更容易设计和修改,因此应该尽量使用客户尽量使用客户供应商关系供应商关系。 8.3.2 8.3.2 组织系统的两种方案组织系统的两种方案 把子系统组织成完整的系统时,有把子系统组织成完整的系统时,有水水平层次组织平层次组织和和垂直块组织垂直块组织两种方案可供选两种方案可
12、供选择。择。 1. 1. 层次组织层次组织 这种组织方案把软件系统组织成一个这种组织方案把软件系统组织成一个层次系统,层次系统,每层是一个子系统每层是一个子系统。上层在下。上层在下层的基础上建立,下层为实现上层功能而层的基础上建立,下层为实现上层功能而提供必要的服务。提供必要的服务。 每一层内所包含的对象,彼此间相互每一层内所包含的对象,彼此间相互独立独立,而处于不同层次上的对象,彼此间,而处于不同层次上的对象,彼此间往往有往往有关联关联。 实际上,在实际上,在上、下层上、下层之间存在客户之间存在客户供应商供应商关关系系。低层子系统提供服务,相当。低层子系统提供服务,相当于供应商,上层子系统使
13、用下层提供的服于供应商,上层子系统使用下层提供的服务,相当于客户。务,相当于客户。 2. 2. 块状组织块状组织 这种组织方案把软件系统这种组织方案把软件系统垂直地分解垂直地分解成若干个相对独立的、弱耦合的子系统,成若干个相对独立的、弱耦合的子系统,一个子系统相当于一块,每块提供一种类一个子系统相当于一块,每块提供一种类型的服务。型的服务。 8.3.3 8.3.3 设计系统的拓扑结构设计系统的拓扑结构 由子系统组成完整的系统时,典型的由子系统组成完整的系统时,典型的拓扑结构有管道型、树型、星型等。设计拓扑结构有管道型、树型、星型等。设计者应该采用与问题结构相适应的、尽可能者应该采用与问题结构相
14、适应的、尽可能简单的拓扑结构,以减少子系统之间的交简单的拓扑结构,以减少子系统之间的交互数量。互数量。 通过面向对象分析所得出的问题域精通过面向对象分析所得出的问题域精确模型,为设计问题域子系统奠定了良好确模型,为设计问题域子系统奠定了良好的基础,建立了完整的框架。的基础,建立了完整的框架。 只要可能,就应该只要可能,就应该保持保持面向对象分析面向对象分析所建立的所建立的问题域结构问题域结构。通常,面向对象设。通常,面向对象设计仅需从实现角度对问题域模型作一些补计仅需从实现角度对问题域模型作一些补充或修改,主要是增添、合并或分解类充或修改,主要是增添、合并或分解类对象、属性及服务,调整继承关系
15、等。对象、属性及服务,调整继承关系等。 当问题域子系统过分复杂庞大时,应当问题域子系统过分复杂庞大时,应该把它进一步分解成若干个更小的子系统。该把它进一步分解成若干个更小的子系统。 对面向对象分析所得出的问题域模型作对面向对象分析所得出的问题域模型作的补充或修改所涉及的问题如下:的补充或修改所涉及的问题如下: 1. 1.调整需求调整需求 2.2.重用已有的类重用已有的类 3.3.把问题域类组合在一起把问题域类组合在一起 在面向对象设计过程中,设计者往往在面向对象设计过程中,设计者往往通过引入一个通过引入一个根类根类而把问题域类组合在一起。而把问题域类组合在一起。 4. 4.增添一般化类以建立协
16、议增添一般化类以建立协议 5.ATM5.ATM系统之例系统之例 图图8.4描绘了上章给出的描绘了上章给出的ATM系统的系统的问题域子系统的结构。问题域子系统的结构。 8.5.1 8.5.1 设计人设计人- -机交互界面机交互界面的准则的准则 遵循下列准则有助于设计出让用户满遵循下列准则有助于设计出让用户满意的人意的人- -机交互界面。机交互界面。 1. 1. 一致性一致性 使用一致的术语,一致的步骤,一致使用一致的术语,一致的步骤,一致的动作。的动作。 2. 2. 减少步骤减少步骤 应使用户为做某件事情尽量减少操作步骤。应使用户为做某件事情尽量减少操作步骤。 还应使得技术水平不同的用户,为获得
17、有意还应使得技术水平不同的用户,为获得有意义的结果所需使用的时间都减至最少。特别应该义的结果所需使用的时间都减至最少。特别应该为熟练用户提供简捷的操作方法为熟练用户提供简捷的操作方法( (例如,热键例如,热键) )。 3. 3. 及时提供反馈信息及时提供反馈信息 每当用户等待系统完成一项工作时,每当用户等待系统完成一项工作时,系统都应该向用户提供有意义的、及时的系统都应该向用户提供有意义的、及时的反馈信息,以便用户能够知道系统目前已反馈信息,以便用户能够知道系统目前已经完成该项工作的多大比例。经完成该项工作的多大比例。 4. 4. 提供撤消命令提供撤消命令 人在与系统交互的过程中难免会犯错人在
18、与系统交互的过程中难免会犯错误,因此,应该提供误,因此,应该提供“撤消撤消(undo)”(undo)”命令,命令,以便用户及时撤消错误动作,消除错误动以便用户及时撤消错误动作,消除错误动作造成的后果。作造成的后果。 5. 5. 无须记忆无须记忆 不应该要求用户记住在某个窗口中显不应该要求用户记住在某个窗口中显示的信息,然后再用到另一个窗口中,这示的信息,然后再用到另一个窗口中,这是软件系统的责任而不是用户的任务。是软件系统的责任而不是用户的任务。 此外,在设计人此外,在设计人- -机交互部分时应该力机交互部分时应该力求达到下述求达到下述目标目标:用户在使用该系统时用:用户在使用该系统时用于思考
19、人于思考人- -机交互方法所花费的时间减至最机交互方法所花费的时间减至最少,而用于做他实际想做的工作所用的时少,而用于做他实际想做的工作所用的时间达到最大值。更理想的情况是,人间达到最大值。更理想的情况是,人- -机交机交互界面能够增强用户的能力。互界面能够增强用户的能力。 6. 6. 易学易学 人人- -机交互界面应该易学易用,应该机交互界面应该易学易用,应该提供联机参考资料,以便用户在遇到困难提供联机参考资料,以便用户在遇到困难时可随时参阅。时可随时参阅。 7. 7. 富有吸引力富有吸引力 人人- -机交互界面不仅应该方便、高效,机交互界面不仅应该方便、高效,还应该使人在使用时感到心情愉快
20、,能够还应该使人在使用时感到心情愉快,能够从中获得乐趣,从而吸引人去使用它。从中获得乐趣,从而吸引人去使用它。 8.5.2 8.5.2 设计人设计人- -机交互子系机交互子系统的策略统的策略 1. 1. 分类用户分类用户 为了更好地了解用户的需要与爱好,为了更好地了解用户的需要与爱好,以便设计出符合用户需要的界面,设计者以便设计出符合用户需要的界面,设计者首先应该把将来可能与系统交互的用户分首先应该把将来可能与系统交互的用户分类。通常从下列几个不同角度进行分类。类。通常从下列几个不同角度进行分类。 按技能水平分类按技能水平分类( (新手新手/ /初级初级/ /中级中级/ /高级高级) )。 按
21、职务分类按职务分类( (总经理总经理/ /经理经理/ /职员职员) )。 按所属集团分类按所属集团分类( (职员职员/ /顾客顾客) )。 2. 2. 描述用户描述用户 应该仔细了解将来使用系统的每类用应该仔细了解将来使用系统的每类用户的情况,把获得的下列各项信息记录下户的情况,把获得的下列各项信息记录下来。来。 3. 3. 设计命令层次设计命令层次 设计命令层次的工作通常包含以下几设计命令层次的工作通常包含以下几项内容。项内容。 (1) (1) 研究现有的人研究现有的人- -机交互含义和准机交互含义和准则则 (2) (2) 确定初始的命令层次确定初始的命令层次 所谓所谓命令层次命令层次,实质
22、上是用过程抽象,实质上是用过程抽象机制组织起来的、可供选用的服务的表示机制组织起来的、可供选用的服务的表示形式。设计命令层次时,通常先从对服务形式。设计命令层次时,通常先从对服务的过程抽象着手,然后再进一步修改它们,的过程抽象着手,然后再进一步修改它们,以适合具体应用环境的需要。以适合具体应用环境的需要。 (3) (3) 精化命令层次精化命令层次 为进一步修改完善初始的命令层次,为进一步修改完善初始的命令层次,应该考虑下列一些因素。应该考虑下列一些因素。 次序:仔细选择每个服务的名字,次序:仔细选择每个服务的名字,并在命令层的每一部分内把服务排好次序。并在命令层的每一部分内把服务排好次序。排序
23、时或者把最常用的服务放在最前面,排序时或者把最常用的服务放在最前面,或者按照用户习惯的工作步骤排序。或者按照用户习惯的工作步骤排序。 整体整体部分关系:寻找在这些服务部分关系:寻找在这些服务中存在的整体中存在的整体部分模式,这样做有助于部分模式,这样做有助于在命令层中分组组织服务。在命令层中分组组织服务。 宽度和深度:由于人的短期记忆能宽度和深度:由于人的短期记忆能力有限,命令层次的宽度和深度都不应该力有限,命令层次的宽度和深度都不应该过大。过大。 操作步骤:应该用尽量少的单击、操作步骤:应该用尽量少的单击、拖动和击键组合来表达命令,而且应该为拖动和击键组合来表达命令,而且应该为高级用户提供简
24、捷的操作方法。高级用户提供简捷的操作方法。 4. 4. 设计人设计人- -机交互类机交互类 人人-机交互类与所使用的操作系统及编机交互类与所使用的操作系统及编程语言密切相关。程语言密切相关。 8.6.1 8.6.1 分析并发性分析并发性 通过面向对象分析建立起来的通过面向对象分析建立起来的动态模动态模型型,是,是分析并发性的主要依据分析并发性的主要依据。如果两个。如果两个对象彼此间不对象彼此间不存在交互,或者它们同时接存在交互,或者它们同时接受事件,则这两个对象在本质上是受事件,则这两个对象在本质上是并发并发的。的。 8.6.2 8.6.2 设计任务管理子系统设计任务管理子系统 常见的常见的任
25、务任务有事件驱动型任务、时钟有事件驱动型任务、时钟驱动型任务、优先任务、关键任务和协调驱动型任务、优先任务、关键任务和协调任务等。任务等。设计任务管理子系统设计任务管理子系统,包括确定,包括确定各类任务并把任务分配给适当的硬件或软各类任务并把任务分配给适当的硬件或软件去执行。件去执行。 1. 1. 确定事件驱动型任务确定事件驱动型任务 某些任务是由事件驱动的,这类任务某些任务是由事件驱动的,这类任务可能主要完成可能主要完成通信通信工作。工作。 2. 2. 确定时钟驱动型任务确定时钟驱动型任务 某些任务每隔一定时间间隔就被触发某些任务每隔一定时间间隔就被触发以执行某些处理,例如,某些设备需要周以
26、执行某些处理,例如,某些设备需要周期性地获得数据;在这些场合往往需要使期性地获得数据;在这些场合往往需要使用时钟驱动型任务。用时钟驱动型任务。 3. 3. 确定优先任务确定优先任务 优先任务可以满足高优先级或低优先优先任务可以满足高优先级或低优先级的处理需求。级的处理需求。 高优先级:某些服务具有很高的优高优先级:某些服务具有很高的优先级,为了在严格限定的时间内完成这种先级,为了在严格限定的时间内完成这种服务,可能需要把这类服务分离成独立的服务,可能需要把这类服务分离成独立的任务。任务。 低优先级:与高优先级相反,有些低优先级:与高优先级相反,有些服务是低优先级的,属于低优先级处理。服务是低优
27、先级的,属于低优先级处理。设计时可能用额外的任务把这样的处理分设计时可能用额外的任务把这样的处理分离出来。离出来。 4. 4. 确定关键任务确定关键任务 关键任务是有关系统成功或失败的关关键任务是有关系统成功或失败的关键处理,这类处理通常都有严格的可靠性键处理,这类处理通常都有严格的可靠性要求。在设计过程中可能用额外的任务把要求。在设计过程中可能用额外的任务把这样的关键处理分离出来,以满足高可靠这样的关键处理分离出来,以满足高可靠性处理的要求。对高可靠性处理应该精心性处理的要求。对高可靠性处理应该精心设计和编码,并且应该严格测试。设计和编码,并且应该严格测试。 5. 5. 确定协调任务确定协调
28、任务 当系统中存在三个以上任务时,就应当系统中存在三个以上任务时,就应该增加一个任务,用它作为协调任务。该增加一个任务,用它作为协调任务。 6. 6. 尽量减少任务数尽量减少任务数 必须仔细分析和选择每个确实需要的必须仔细分析和选择每个确实需要的任务。应该使系统中包含的任务数尽量少。任务。应该使系统中包含的任务数尽量少。 7. 7. 确定资源需求确定资源需求 使用多处理器或固件,主要是为了满使用多处理器或固件,主要是为了满足高性能的需求。足高性能的需求。 数据管理子系统是系统存储或检索对数据管理子系统是系统存储或检索对象的基本设施象的基本设施,它建立在某种数据存储管,它建立在某种数据存储管理系
29、统之上,并且隔离了数据存储管理模理系统之上,并且隔离了数据存储管理模式式( (文件、关系数据库或面向对象数据库文件、关系数据库或面向对象数据库) )的影响。的影响。 8.7.1 8.7.1 选择数据存储管理模式选择数据存储管理模式 不同的数据存储管理模式有不同的特不同的数据存储管理模式有不同的特点,适用范围也不相同,设计者应该根据点,适用范围也不相同,设计者应该根据应用系统的特点选择适用的模式。应用系统的特点选择适用的模式。 1. 1. 文件管理系统文件管理系统 2. 2. 关系数据库管理系统关系数据库管理系统 3. 3. 面向对象数据库管理系统面向对象数据库管理系统 面向对象数据库管理系统是
30、一种新技面向对象数据库管理系统是一种新技术,主要有两种设计途径:扩展的关系数术,主要有两种设计途径:扩展的关系数据库管理系统和扩展的面向对象程序设计据库管理系统和扩展的面向对象程序设计语言。语言。 8.7.2 8.7.2 设计数据管理子系统设计数据管理子系统 设计数据管理子系统,既需要设计数设计数据管理子系统,既需要设计数据格式又需要设计相应的服务。据格式又需要设计相应的服务。 1. 1. 设计数据格式设计数据格式 设计数据格式的方法与所使用的数据设计数据格式的方法与所使用的数据存储管理模式密切相关,下面分别介绍适存储管理模式密切相关,下面分别介绍适用于每种数据存储管理模式的设计方法。用于每种
31、数据存储管理模式的设计方法。 (1) (1) 文件系统文件系统 (2) (2) 关系数据库管理系统关系数据库管理系统 (3) (3) 面向对象数据库管理系统面向对象数据库管理系统 2. 2. 设计相应的服务设计相应的服务 如果某个类的对象需要存储起来,则如果某个类的对象需要存储起来,则在这个类中增加一个属性和服务,用于完在这个类中增加一个属性和服务,用于完成存储对象自成存储对象自身的工作。 下面介绍使用不同数据存储管理模式下面介绍使用不同数据存储管理模式时的设计要点。时的设计要点。 (1) (1) 文件系统文件系统 注意,为提高性能应该批量处理访问注意,为提高性能应该批量处理访问文件的要求。文
32、件的要求。 (2) (2) 关系数据库管理系统关系数据库管理系统 (3) (3) 面向对象数据库管理系统面向对象数据库管理系统 8.8.1 8.8.1 确定类中应有的服务确定类中应有的服务 需要综合考虑对象模型、动态模型和需要综合考虑对象模型、动态模型和功能模型,才能正确确定类中应有的服务。功能模型,才能正确确定类中应有的服务。对象模型是进行对象设计的基本框架。对象模型是进行对象设计的基本框架。 但是,面向对象分析得出的对象模型,但是,面向对象分析得出的对象模型,通常只在每个类中列出很少几个最核心的通常只在每个类中列出很少几个最核心的服务。设计者必须把动态模型中对象的行服务。设计者必须把动态模
33、型中对象的行为以及功能模型中的数据处理,转换成由为以及功能模型中的数据处理,转换成由适当的类所提供的服务。适当的类所提供的服务。 8.8.2 8.8.2 设计实现服务的方法设计实现服务的方法 在面向对象设计过程中还应该进一步在面向对象设计过程中还应该进一步设计实现服务的方法,主要应该完成以下设计实现服务的方法,主要应该完成以下几项工作。几项工作。 1. 1. 设计实现服务的算法设计实现服务的算法 设计实现服务的算法时,应该考虑下设计实现服务的算法时,应该考虑下列几个因素。列几个因素。 (1) (1) 算法复杂度算法复杂度 (2) (2) 容易理解与容易实现容易理解与容易实现 (3) (3) 易
34、修改易修改 2. 2. 选择数据结构选择数据结构 3. 3. 定义内部类和内部操作定义内部类和内部操作 在对象模型中,关联是联结不同对象在对象模型中,关联是联结不同对象的纽带,它指定了对象相互间的访问路径。的纽带,它指定了对象相互间的访问路径。在面向对象在面向对象设计过程中,设计人员必须确设计过程中,设计人员必须确定实现关联的具体策略。定实现关联的具体策略。 8.9.1 8.9.1 关联的遍历关联的遍历 在应用系统中,使用关联有两种可能在应用系统中,使用关联有两种可能的方式:单向遍历和双向遍历。的方式:单向遍历和双向遍历。 8.9.2 8.9.2 实现单向关联实现单向关联 用指针可以方便地实现
35、单向关联。如用指针可以方便地实现单向关联。如果关联的阶是一元的果关联的阶是一元的( (如图如图8.58.5所示所示) ),则实,则实现关联的指针是一个简单指针;如果阶是现关联的指针是一个简单指针;如果阶是多元的,则需要用一个指针集合实现关联多元的,则需要用一个指针集合实现关联( (参见图参见图8.6)8.6)。 8.9.3 8.9.3 实现双向关联实现双向关联 许多关联都需要双向遍历,当然,两许多关联都需要双向遍历,当然,两个方向遍历的频度往往并不相同。实现双个方向遍历的频度往往并不相同。实现双向关联有下列三种方法。向关联有下列三种方法。 只用属性实现一个方向的关联,当只用属性实现一个方向的关
36、联,当需要反向遍历时就执行一次正向查找。需要反向遍历时就执行一次正向查找。 两个方向的关联都用属性实现。两个方向的关联都用属性实现。 用独立的关联用独立的关联对象实现双向关联。对象实现双向关联。图图8.5 8.5 用指针实现单向关联用指针实现单向关联(a)(a)关联;关联;(b)(b)实现实现图图8.6 8.6 用指针实现双向关联用指针实现双向关联(a)(a)关联;关联;(b)(b)实现实现 8.9.4 8.9.4 链属性的实现链属性的实现 如果某个关联具有链属性,则实现它如果某个关联具有链属性,则实现它的方法取决于关联的阶数。对于一对一关的方法取决于关联的阶数。对于一对一关联来说,链属性可作
37、为其中一个对象的属联来说,链属性可作为其中一个对象的属性而存储在该对象中。性而存储在该对象中。 对于一对多关联来说,链属性可作为对于一对多关联来说,链属性可作为“多多”端对象的一个属性。如果是多对多端对象的一个属性。如果是多对多关联,则链属性不可能只与一个关联对象关联,则链属性不可能只与一个关联对象有关,通常使有关,通常使用一个独立的类来实现链属用一个独立的类来实现链属性,这个类的每个实例表示一条链及该链性,这个类的每个实例表示一条链及该链的属性的属性(参见图参见图8.7)。图图8.7 8.7 用对象实现关联用对象实现关联 8.10.1 8.10.1 确定优先级确定优先级 系统的各项质量指标并
38、不是同等重要系统的各项质量指标并不是同等重要的,设计人员必须确定各项质量指标的相的,设计人员必须确定各项质量指标的相对重要性对重要性( (即确定优先级即确定优先级) ),以便在优化设,以便在优化设计时制定折衷方案。计时制定折衷方案。 8.10.2 8.10.2 提高效率的几项技术提高效率的几项技术 1. 1. 增加冗余关联以提高访问效率增加冗余关联以提高访问效率 2 2调整查询次序调整查询次序 3. 3. 保留派生属性保留派生属性图图8.8 8.8 公司、雇员及技能之间的关联链公司、雇员及技能之间的关联链图图8.9 8.9 为雇员技能数据库建立索引为雇员技能数据库建立索引 8.10.3 8.1
39、0.3 调整继承关系调整继承关系 在面向对象设计过程中,建立良好的在面向对象设计过程中,建立良好的继承关系是优化设计的一项重要内容。继承关系是优化设计的一项重要内容。 下面讨论与建立类继承有关的问题。下面讨论与建立类继承有关的问题。 1. 1. 抽象与具体抽象与具体 在设计类继承时,很少使用纯粹自顶在设计类继承时,很少使用纯粹自顶向下的方法。通常的作法是,首先创建一向下的方法。通常的作法是,首先创建一些满足具体用途的类,然后对它们进行归些满足具体用途的类,然后对它们进行归纳,一旦归纳出一些通用的类以后,往往纳,一旦归纳出一些通用的类以后,往往可以根据需要再派生出具体类。可以根据需要再派生出具体
40、类。 在进行了一些具体化在进行了一些具体化( (即专门化即专门化) )的工的工作之后,也许就应该再次归纳了。对于某作之后,也许就应该再次归纳了。对于某些类继承来说,这是一个持续不断的演化些类继承来说,这是一个持续不断的演化过程。过程。(a)(a)先创建一些先创建一些具体类;具体类;(b)(b) 归纳出抽归纳出抽象类;象类;(c)(c) 进一步具进一步具体化;体化;(d)(d)再次归纳再次归纳图图8.108.10设计设计类继承的类继承的例子例子 2. 2. 为提高继承程度而修改类定义为提高继承程度而修改类定义 如果在一组相似的类中存在公共的属如果在一组相似的类中存在公共的属性和公共的行为,则可以
41、把这些公共的属性和公共的行为,则可以把这些公共的属性和行为抽取出来放在一个共同的祖先类性和行为抽取出来放在一个共同的祖先类中,供其子类继承,如图中,供其子类继承,如图8.10(a)8.10(a)和和(b)(b)所所示。示。 在对现有类进行归纳的时候,要注在对现有类进行归纳的时候,要注意下述两点:意下述两点: (1)(1)不能违背领域知识和常识;不能违背领域知识和常识; (2) (2) 应该确保现有类的协议应该确保现有类的协议( (即同即同外部世界的接口外部世界的接口) )不变。不变。 3. 3. 利用委托实现行为共享利用委托实现行为共享 仅当存在真实的一般仅当存在真实的一般特殊关系特殊关系(
42、(即子即子类确实是父类的一种特殊形式类确实是父类的一种特殊形式) )时,利用继时,利用继承机制实现行为共享才是合理的。承机制实现行为共享才是合理的。 如果你只想把继承作为实现操作共享如果你只想把继承作为实现操作共享的一种手段,则利用委托的一种手段,则利用委托( (即把一类对象作即把一类对象作为另一类对象的属性,从而在两类对象间为另一类对象的属性,从而在两类对象间建立组合关系建立组合关系) )也可以达到同样目的,而且也可以达到同样目的,而且这种方法更安全。这种方法更安全。 使用委托机制时,只有有意义的操作使用委托机制时,只有有意义的操作才委托另一类对象实现,因此,不会发生才委托另一类对象实现,因
43、此,不会发生不慎继承了无意义不慎继承了无意义( (甚至有害甚至有害) )操作的问题。操作的问题。(a) (a) 用继承实现;用继承实现;(b) (b) 用委托实现用委托实现图图8.118.11用表实现栈的两种方法用表实现栈的两种方法 8.11.18.11.1面向对象分析面向对象分析 1. 1. 需求需求 这个类库管理系统的主要用途,是管这个类库管理系统的主要用途,是管理用户在用理用户在用C+KG-*4/9+语言开发软件语言开发软件的漫长过程中逐渐积累起来的类,以便在的漫长过程中逐渐积累起来的类,以便在今后的软件开发过程中能够从库中方便地今后的软件开发过程中能够从库中方便地选取出可重用的类。选取
44、出可重用的类。 它应该具有编辑它应该具有编辑( (包括添加、修改和删包括添加、修改和删除除) )、储存和浏览等基本功能,、储存和浏览等基本功能, 2. 2.建立对象模型建立对象模型 (1) (1) 确定问题域中的类确定问题域中的类 从对这个类库管理系统的需求不难看从对这个类库管理系统的需求不难看出,组成这个系统的基本对象是出,组成这个系统的基本对象是“类库类库”和和“类类”。类是类库中的。类是类库中的“条目条目”,不妨,不妨把它称为把它称为“类条目类条目”(ClassEntry)。 (2) 分析类之间的关系分析类之间的关系 图图8.128.12是本问题域的对象模型。是本问题域的对象模型。图图8
45、.12 8.12 类库管理系统的对象模型类库管理系统的对象模型 8.11.2 8.11.2 面向对象设计面向对象设计 1. 1.设计类库结构设计类库结构 当用链表存储类条目的时候,链表中当用链表存储类条目的时候,链表中每个节点都是一个类条目。这种结构的优每个节点都是一个类条目。这种结构的优点是:结构简单,插入和删除的算法都相点是:结构简单,插入和删除的算法都相当简单;容易遍历。缺点是这种存储结构当简单;容易遍历。缺点是这种存储结构并不反映继承关系。并不反映继承关系。 2. 2.设计问题域子系统设计问题域子系统 在面向对象设计过程中,仅需从实现在面向对象设计过程中,仅需从实现的角度出发,并根据我
46、们所设计的类库结的角度出发,并根据我们所设计的类库结构,对图构,对图8.12所示的对象模型做一些补充所示的对象模型做一些补充和细化。和细化。图图8.13 8.13 类库示意图类库示意图 3. 3.设计人设计人- -机交互子系统机交互子系统 (1) (1) 窗口窗口 主要设计了下述一些窗口。主要设计了下述一些窗口。 登录窗口登录窗口 主窗口主窗口 创建窗口创建窗口 面向对象设计,就是用面向对象观点面向对象设计,就是用面向对象观点建立求解空间模型的过程。通过面向对象建立求解空间模型的过程。通过面向对象分析得出的问题域模型,为建立求解空间分析得出的问题域模型,为建立求解空间模型奠定了坚实基础。模型奠
47、定了坚实基础。 分析与设计本质上是一个多次反复迭分析与设计本质上是一个多次反复迭代的过程,而面向对象分析与面向对象设代的过程,而面向对象分析与面向对象设计的界限尤其模糊。计的界限尤其模糊。 优秀设计是使得目标系统在其整个生优秀设计是使得目标系统在其整个生命周期中总开销最小的设计,为获得优秀命周期中总开销最小的设计,为获得优秀的设计结果,应该遵循一些基本准则。本的设计结果,应该遵循一些基本准则。本章结合面向对象方法学固有的特点讲述了章结合面向对象方法学固有的特点讲述了面向对象设计准则,并介绍了一些有助于面向对象设计准则,并介绍了一些有助于提高设计质量的启发式规则。提高设计质量的启发式规则。 用面
48、向对象方法设计软件,原则上也用面向对象方法设计软件,原则上也是先进行总体设计是先进行总体设计( (即系统设计即系统设计) ),然后再,然后再进行详细设计进行详细设计( (对象设计对象设计) ),当然,它们之,当然,它们之间的界限非常模糊,事实上是一个多次反间的界限非常模糊,事实上是一个多次反复迭代的过程。复迭代的过程。 大多数求解空间模型,在逻辑上由四大多数求解空间模型,在逻辑上由四大部分组成。本章分别讲述了问题域子系大部分组成。本章分别讲述了问题域子系统、人统、人- -机交互子系统、任务管理子系统和机交互子系统、任务管理子系统和数据管理子系统的设计方法。此外还讲述数据管理子系统的设计方法。此
49、外还讲述了设计类中服务的方法及实现关联的策略。了设计类中服务的方法及实现关联的策略。 通常应该在设计工作开始之前,对系通常应该在设计工作开始之前,对系统的各项质量指标的相对重要性做认真分统的各项质量指标的相对重要性做认真分析和仔细权衡,制定出恰当的系统目标。析和仔细权衡,制定出恰当的系统目标。在设计过程中根据既定的系统目标,做必在设计过程中根据既定的系统目标,做必要的优化工作。要的优化工作。 本章本章8.118.11节讲述了一个简化的节讲述了一个简化的C+C+类库类库管理系统的面向对象分析与设计过程,认管理系统的面向对象分析与设计过程,认真阅读这一节有助于读者深入、具体地理真阅读这一节有助于读者深入、具体地理解面向对象分析与设计的方法,同时,这解面向对象分析与设计的方法,同时,这一节的内容也为读者提供了一份较好的实一节的内容也为读者提供了一份较好的实习材料。习材料。