1
 软件工程
1.9.2.2 7.2.2 系统设计

7.2.2 系统设计

系统设计是对问题的解和建立解法的高层策略。系统设计解决的问题有将整个系统划分为子系统的软件和硬件部分分配,为详细设计指定框架等。也就是说,系统设计是将系统划分为几个子系统,建立系统的基本框架,每个子系统使用与面向对象分析一致的表示法建立模型。可以说,系统设计是逐步扩充面向对象分析模型的扩充过程。系统设计就是软件总体结构的设计,也就是进行子系统的划分及子系统之间的通信。在系统设计过程中,需要完成的主要任务有子系统划分、问题域子系统设计、人机界面子系统设计、任务管理子系统设计和数据管理子系统设计等相关工作。

1.子系统划分

在现实生活中,人们解决一个复杂的问题常常采用“分而治之”的策略。这种策略同时适用于软件系统的设计。一个复杂的软件系统可以按照一定的策略分解成若干个子系统,每个子系统又可以分解为若干个软件组件。系统设计的任务之一就是把分析模型中紧密相关的类、关系等设计元素包装成子系统,这样,分析模型被划分为若干个子系统。

一个子系统不是一个对象,也不是一种功能,而是类、管理、服务(操作)、事件和约束的一个包,它们是相互联系的,并在进行合理定义接口后,希望其他子系统有很少的接口。通常,一个子系统由它所提供的服务来识别,一个服务是一组具有共同目标的相关功能,如I/O处理、画图等。一个子系统定义了观察问题的一个方面解的本质方式,如操作系统中的文件系统是一个子系统,它相对于抽象集合来说是很大的,但不是全部,它独立于另外的子系统,如进程管理或存储管理。

每个子系统和其他子系统之间有一个很好定义的接口,这个接口指明了原有交互的形式和通过子系统边界的信息,但是不指出这个子系统的内部实现。每个子系统能够独立进行设计,这些设计并不影响其他子系统。

两个子系统之间的关系可以是客户-供应商关系或平等伙伴关系。在客户-供应商关系中,“供应商”子系统提供的接口作为“客户”子系统的调用,并返回结果给“客户”。整个调用过程是由“客户”子系统所驱动的,所以它必须了解“供应商”子系统提供的接口,而“供应商”子系统无须了解“客户”子系统的接口。在平等伙伴关系中,每个子系统可以调用其他子系统,一个子系统与另一个子系统的通信不必立即紧跟着一个响应。相对于客户-供应商关系来说,平等伙伴关系中的子系统之间交换复杂,存在难以理解和容易出错的通信环路。因此,建议尽可能采用客户-供应商关系。

一个软件系统的结构通常可以有层次(水平切片)组织和块状(垂直切片)组织两种方式。

1)层次组织

这种组织方式把软件系统组织成一个层次系统,每一层是一个子系统。上层子系统在下层的基础上,下层子系统为实现上层功能而提供必要的服务。系统的每一层可以包含一个或多个子系统,并且表示了完成系统功能所需功能性的不同抽象层次。

每一层子系统所包含的对象,彼此相互独立。而处在不同层次上的对象,彼此间往往有联系。显然,在上、下层子系统之间存在着客户-供应商关系。下层子系统提供服务,相当于供应商;上层子系统使用下层子系统提供的服务,相当于客户端。

在设计中,顶层是用户看到的目标系统,底层则是可以使用的资源。为了减少不同层次之间的概念差异,设计者还必须设计一些中间层子系统。

例如,计算机系统的层次结构如图7-11所示。

img128

图7-11 计算机系统的层次结构

层次结构的模式又可进一步划分为封闭模式和开发模式。封闭模式就是每层子系统仅仅使用其直接(直属)下层子系统提供的服务。由于一个层次的接口只影响与其相邻的上一层,因此,这种模式降低了各层次之间的相互依赖性,容易理解和修改。

开发模式就是某一层子系统可以使用处于它下面的任何一层子系统所提供的服务。这种模式的优点是减少了需要在每层子系统重新定义的服务数目,使得整个系统更高效、更紧凑。但是,开放模式的系统不符合信息隐藏原则,对任何一个子系统的修改都会影响处在更高层次的子系统。设计软件系统时到底采用哪种结构模式,需要全面权衡效率和模块独立性等因素。

组织层次结构子系统时,可以采用以下的步骤。

(1)建立分层的标准,决定子系统将如何被组合成层次的体系结构。

(2)确定层次(子系统)的数量,层次(子系统)太多,将导致不必要的复杂性,层太少则可能破坏功能的独立性。

(3)命名层(子系统)。在这一过程中,将子系统及其封装的类分配到某一层;确立在同一层的子系统(类)之间,以及与其他层子系统(类)的通信机制。在一个封闭式体系结构中,一个层次(子系统)的消息只发送到相邻的低层。在一个开放的体系结构中,一个层次(子系统)的消息可以发送至任意层。

(4)定义每一层的接口。

(5)精化子系统以建立每个层的类结构。

(6)定义层通信的消息模型。

(7)评审层设计以保证层间的耦合度最小(客户机/服务器协议可以帮助达成此目标)。

(8)迭代以精化分层设计。

2)块状组织

这种组织方式把软件系统垂直地分解成若干个相对独立的、低耦合的子系统,一个子系统相当于一块,每块提供一种本地的服务。

当然,可以使用层次和块状的混合结构,即利用层次和块的各种可能的组合成功地由多个子系统组成一个完整的软件系统。

划分子系统的原则有很多,人们通常是按照功能来划分的,而且子系统的数目应该与系统规模基本匹配。例如,一个操作系统可以划分为进程管理、存储管理、设备管理、文件管理、作业管理、中断处理等子系统。下面是划分子系统时应该遵循的一些原则。

(1)子系统应该具有良好的接口,接口尽可能简单、明确。接口确定了交互形式和通过子系统边界的信息流。

(2)子系统之间应尽可能减少依赖性。

(3)子系统数量不应太多,子系统的数目应该与系统的规模基本匹配。

(4)子系统可以在内部再划分以得到较低复杂性。

(5)无须规定子系统内部的实现算法。

2.问题域子系统设计

在面向对象设计中,面向对象分析的结果恰好符合面向对象设计的问题域部分,这个结果是面向对象设计模型中的一个完整部分,而且,分析结果可以被改动和增补,在分析和设计之间不存在宽大的、不可回溯、不可追踪的鸿沟。因此,对面向对象分析结果的改动和增补是设计的开端。

从面向对象分析到面向对象设计是一个平滑的过渡,即没有间断和没有明确的分界线。面向对象分析是建立系统的问题域对象模型,而面向对象设计是建立求解域的对象模型。它们虽然都是建模,但两者的性质不同,分析建模可以与系统的具体实现无关,设计建模则要考虑系统的具体实现环境的约束,如需要考虑系统准备使用的编程语言、可用的软件构件库及程序员的编程经验等约束问题。

面向对象方法中的一个主要目标是保持问题域组织框架的完整性、稳定性,这样可提高分析、设计到实现的追踪性。因为系统的总体框架都是建立在问题域基础上的,所以,在设计与实现过程中无论做怎样的修改,如增加具体类、属性或服务等,都不会影响开发结果的稳定性。对于需求可能随时间变化的系统来说,稳定性是至关重要的。稳定性是在类似系统中实现重用分析、设计和编程结果的关键因素。为了更好地支持系统的补充,也同样需要稳定性。面向对象分析和面向对象设计结果的稳定性是系统评估的基础,所以,在问题域部分进行的修改必须经过仔细的检查和验证。

下面介绍在面向对象设计过程中,可能对面向对象分析所得出的问题域模型做的补充和修改。

1)需求变更

当用户需求或外部环境发生了变化,或者分析员对问题域理解不透彻或缺乏领域专家帮助,以致建立了不能完整、准确地反映用户真实需求的面向对象分析模型时,需要对面向对象分析所确定的系统需求进行修改。通常,首先需要修改面向对象分析的结果,然后再把这些修改反映到问题域子系统中。

2)重新设计编程类

首先,考虑如何从自己的或别人的源程序中把现成的类增加到问题域部分。现成的类可能是用面向对象方法编写的,也可能是用某种非面向对象方法编写的可用软件,在后一种情况中,把软件封装在一个特意设计的、基于服务的界面中,改造成类的形式,把现成的类增加到问题域中。

其次,划掉现成类中任何不用的属性和服务,并增加一个现成类到问题域类之间的一般-特殊关系。

接着,划掉问题域类中不需要的属性和服务,这些属性和服务现在是从现成类中继承的,并修正问题域类的结构和连接,必要时把它们移向现成类。

3)组合问题域类

在面向对象的分析中,没有引进一个类放在所有类的上层。在面向对象设计中,通常先引入一个类以便把问题域专用的类组合在一起,它仅仅起到“根”类的作用,把全部下层的类组合在一起。为什么需要这样做呢?因为它可以形成一个一般/特殊结构,从而概括面向对象分析模型中的几乎所有的类及对象。

当没有一个更满意的组合机制可用时,这实际上就是一种把类库中的某些类组织在一起的方法,而且这样的类可以用于建立一个协议。

4)增加一般化类以建立协议

当若干个类存在着一组类似的服务(也许还需要相应的属性)时,可考虑引入一个新类(如把抽象类作为父类)提供公共操作协议(如对象创建、删除等),而把各个服务具体的实现细节由子类完成,可以简化软件设计并提高编码的效率。

5)调整继承层次

如果面向对象分析的一般-特殊结构包括多继承,在使用一种只有单继承或无继承性的编程语言时,就需要对面向对象分析的结果作一些修改。

(1)多继承模式。

第一种多继承模式可称为狭义的菱形,如图7-12所示。这个模式中属性与服务命名的冲突比较频繁,使用者必须注意这种冲突。

第二种多继承模式可称为广义菱形模式,如图7-13所示。这里,菱形开始于最高的一般类,即通常称为“根”类的地方。这里,属性和服务命名的冲突比较少,但它需要更多的类表示设计。

(2)针对单继承语言的调整。

对于单继承语言可用两种方法从多继承结构转换为单继承结构。一种是分解多继承,使用它们之间的映射。这种方法把多继承模式分为两个层次结构,使它们之间的映射用一个整体-部分结构或一个实例连接。另一种是展开为单继承,这种方法把多继承的层次结构展平而形成一个单继承的层次结构,这意味着,有一个或者多个一般-特殊结构在设计中就不再那么清晰了。同时也意味着,有些属性和服务在特殊类中会重复出现,容易造成冗余。图7-14为多继承简化为单一层次的单继承的示意图。

6)增加低层细节

为了设计和编程的方便,可以在低层成分中分离出一些独立的类,这种方法有助于把与计算机细节有关的内容放在低层类中隔离起来。

7)对面向对象分析结果的增补进行重新审查

img129

图7-12 多继承模式

img130

图7-13 广义菱形模式

考察所做的选择,重新审查对问题域部分的内容所做的任何修改。无论何时何地,要尽可能地保持建立的基本问题域的结构。

img131

图7-14 多重继承简化为单一层次的单继承

3.人机界面子系统设计

人机界面子系统提供用户界面,是系统与用户直接打交道的部分,是实现系统的外部表现。人机界面子系统的设计结果将决定用户界面的美观程度、方便程度、易学程度等,这些将对用户情绪和工作效率都会产生重要的影响。如果该子系统提供的人机交互界面设计得好,会使系统对用户产生吸引力,用户在使用系统的过程中会感到兴奋,能够激发用户的创造力,提高工作效率;相反,人机界面设计得不好,用户在使用过程中就会感到不方便、不习惯,甚至会产生厌烦和恼怒的情绪。

设计人机界面子系统的任务是提供使用方便、友好的用户界面,设计工作的内容包括用户分类、描述交互场景、设计人机交互操作命令层次和操作顺序、设计详细交互过程、设计人机交互类(如窗口、对话框、菜单等)。

1)设计用户界面应遵循的原则

设计用户界面应当密切结合业务领域的特点,要符合业务应用的习惯,同时要利用计算机的优点,使所设计的用户界面具有现代化气息,生动活泼,富有吸引力。一般来说,用户界面的设计可以遵循以下原则。

(1)一致性。采用一致的术语、一致的步骤和一致的活动。

(2)操作步骤少。尽可能地减少敲击键盘和点击鼠标的次数,减少完成某件事情所需下拉菜单的次数。

(3)及时反馈信息。当用户在等待系统完成某一项活动时,应不时地在屏幕上显示一些信息,向用户反馈工作的进展情况。

(4)响应时间快。界面操作的响应时间是很重要的,用户一般要求系统的响应时间比较迅速,以提高生产率。例如,一个优秀打字员每分钟可以键入大约1000个字符,如果交互响应时间为0.1~0.2秒/字符,那么,该打字员在击键时就有可能丢失数据,因此不得不降低其输入效率。

(5)要有联机帮助。联机帮助是用户界面友好的一个重要特征。所谓联机帮助是指,无论用户工作在任何进程或任何时刻,均能得到系统和应用程序提供的帮助信息。系统应通过联机帮助减少用户的学习时间,提高学习效果。

(6)要有错误处理机制。在操作出现错误时,应提供错误警告提示和出错恢复的手段,如提供复原(Undo)、终止(Abort)、取消(Cancel)、校正(Correct)等功能。

2)设计人机界面子系统的步骤

(1)从定义应用语句的对象中分离出形成用户界面的对象。

(2)如果可能的话,用预定的对象与外部作用交互,如窗口、菜单、按钮、表单、对话框和适合应用的其他类型对象。

(3)用动态模型作为程序的结构。最好用并发控制或事件驱动控制方式来实现。

(4)区分物理事件和逻辑事件。通常一个逻辑事件对应于多个物理事件,如一个图形接口能从一个表格、弹出式菜单、一个命令序列或一个间接的命令文件中获取输入。

(5)完整说明由接口调用应用功能,确保实现功能的信息已经存在。

人机界面子系统中的类与所使用的操作系统与编程语言密切相关。现在的软件系统一般都采用图形界面(GUI)和人机应答方式,力求界面友好,操作简单。面向对象程序设计语言提供了丰富的预定义的动态链接库DLL,如C++语言的MFC类库,这些类库一般都能提供窗口、菜单、对话框等。设计人机界面子系统时,通常只要从预定义的动态链接库中选择合适的类,再从这些类派生出实现人机交互所需的类。

原则上讲,用户界面与系统的功能要求是分离的。一个用户的界面有多种选择,但是系统要完成的业务处理功能和用户界面要保持相对独立,这样,当用户的场景发生微小变化时,重用处理功能,只需修改界面。例如,在图书管理系统中,为借阅者提供查询图书目录的功能,当开发B/S结构上的图书查询功能时,希望重用C/S结构上的查询图书代码,只需要修改用户界面即可。保持系统功能和用户界面分离的方法是分离信息的内容和形式。信息的内容由应用程序的功能来决定,信息的形式由用户界面来决定。

由于对人机界面的评价在很大程度上由人的主观因素决定,因此,使用由原型支持的系统化的设计策略是成功地设计人机交互子系统的关键。

基于以上的分析,教务信息管理系统不宜采用命令语言,而应该采用图形化的界面,因为系统需要运行在因特网上,因此界面应该采用网页风格,要体现简洁、实用的特点。网页运行速度快、简单的操作和友好的界面易让用户第一时间捕获重点内容等。图7-15为教务信息管理系统中学生信息管理的界面,其风格简洁、实用,界面左侧提供系统的导航功能,系统管理员可以通过左侧的导航,很方便地进入到相关的管理模块中去,界面右侧集成了添加学生基本信息、搜索学生基本信息、删除学生基本信息、修改学生基本信息等功能,为学生基本信息管理提供了集成的界面和平台,同时系统管理员可以按照所在班级、学生姓名、学号等方式来检索学生信息,简化和方便了信息查找的步骤。

4.任务管理子系统设计

一般来说,任务是处理进程的别名,通常把多个任务的并发执行称为多任务。为什么要进行任务管理呢?原因有两个:一个是多用户、多任务或多线程操作上开发应用程序的需要;一个是可以通过任务描述目标软件系统中各个子系统间的通信和协同。

在任务管理子系统设计中,需要进行并发性分析,要识别和确定哪些是必须同时活动的对象,哪些是独立活动的对象。可以在动态模型中分析识别并发性任务(多任务)。如果两个类(或者子系统)不是同时活动的,则不需要并发处理。相反,两个类(或者子系统)彼此间不存在交互(数据通信)或异步同时接收事件,则视它们为并发的。

当子系统存在并发行为时,且这种并发行为可以在不同的处理器(多处理器)上实现,即把每一个子系统分配到各自独立的处理器;也可以在同一个处理器,并利用多任务操作系统仿真实现。例如,采用多线程仿真多处理器。

img132

图7-15 教务信息管理系统人机界面示例

下面介绍任务管理子系统设计的步骤与策略。

1)识别任务的类型和特征

任务类型有事件驱动任务、时间驱动任务、优先任务、关键任务、协调任务(又称为任务协调器)。

(1)识别事件驱动任务。

事件驱动任务由中断激活,并且主要来自于某些外部源的中断,如处理器、传感器等。这类任务可能主要完成通信工作,如与设备、屏幕窗口、其他任务、子系统、另一个处理器或其他系统的通信。

在系统运行时,这类任务的工作过程是:任务处于休眠状态(不消耗处理器时间),等待来自数据线或其他数据源的中断,一旦接收到中断就唤醒该任务,接收数据并把数据存入缓冲区或其他地方,通知需要知道这项任务的对象,然后该任务又回到休眠状态。

(2)识别时间驱动任务。

时间驱动任务也是由中断激活,被系统时钟控制。某些任务每隔一定时间间隔就被触发,用于执行某些处理。

时钟驱动型任务的工作过程是:任务设置唤醒时间后进入休眠状态,等待来自系统的中断,一旦接收到这种中断,任务就被唤醒并做它该做的工作,通知有关的对象,然后该任务又回到休眠状态。

(3)识别优先任务。

任务的优先级别可以分成高优先级和低优先级。

高优先级任务必须能够立即访问系统资源,在严格限定的时间内完成这种服务;低优先级任务与高优先级相反,有些服务是低优先级的,如背景处理等。

识别和确定优先任务就是满足高优先级或低优先级的不同处理需求。设计时可以把高优先级任务的服务分离成独立的任务;把低优先级任务用额外的任务把这样的服务分离出来。

(4)识别关键任务。

关键任务是关系到系统成功或失败的关键,识别和确定关键任务,保证在资源可用性减少或系统在退化的状态下也能得到处理。

这类处理通常都有严格的可靠性要求,对高可靠性处理应该精心设计,严格测试。

(5)识别协调任务。

当系统中存在3个或3个以上任务时,就应该增加一个任务,即任务协调器。任务协调器负责任务之间的调度和协同。由于引入协调任务会增加系统的开销,所以它应该仅做协调工作。

2)任务定义

一旦确定任务特征,就应该对任务进行定义。任务定义的模板可以是任务名称、任务功能描述、优先级、服务、任务与其他任务的协调方式、通信方式等。任务模板定义如下:

img133

3)集成协调者和其他任务,尽量减少任务数量

通过分类、整合、提取等有效的方法,确定需要的任务,使系统包括的任务尽可能少。

4)确定资源需求

通常,使用多处理器或硬件可以满足高性能的需求。一些实时控制系统或时间性很强的系统,对硬件的要求要高一些。但是,应该综合考虑各种因素,决定哪些子系统用硬件实现,哪些子系统用软件实现。有两个因素可能是使用硬件实现某些子系统的主要原因:

(1)现有的硬件完全能满足某些方面的需求;

(2)专用硬件比通用的CPU性能更高。

5.数据管理子系统设计

数据管理子系统为面向对象设计模式提供了在特定的数据管理系统之上,存储或检索对象的基本结构。设计数据管理子系统的目的是,将目标软件系统中依赖开发平台的数据存取部分与其他功能分离,数据存取通过一般的数据存储管理模式(文件、关系数据库或面向对象数据库)来实现,但实现细节集中在数据管理子系统中。这样既有利于软件的扩充、移植和维护,又简化了软件设计、编码和测试的过程。

1)选择数据存储管理模式

选择数据存储管理模式是数据管理子系统设计的首要任务。可供选择的数据存储管理模式有三种:文件管理系统、关系数据库系统和面向对象管理系统。设计者应该根据应用系统的特点,选择一种合适的数据存储管理模式。

(1)文件管理系统。

文件管理系统提供了基本的文件处理和分类能力,它的特点是能长期保持数据,成本低而且简单。但文件操作烦琐,实现比较困难,必须编写大量的代码。此外,文件管理系统是操作系统的一个组成部分,不同操作系统的文件管理系统往往有明显的差异。

(2)关系数据库管理系统。

关系数据库管理系统建立在关系理论的基础上。它用若干个表来管理数据,表中的每一行表示表中的一组值,每一列有一个单一的(原子)值在其中。它具有以下优点。

①提供了各种最基本的数据管理功能,如中断恢复、多用户共享、多应用共享、完整性和事务支持等。

②为多种应用提供了一致的接口。

③支持标准化的SQL语言。

关系数据库管理系统为了做到通用性和一致性,实现起来相当复杂而且存在一定不足,以致限制了它的普遍使用。它具有以下缺点。

①运行开销大。即使只完成简单的事务(如只修改表中的一行),也需要较长的时间。

②不能满足高级应用的需求。关系数据库管理系统是为商务应用服务的,商务应用中数据量虽然大,但数据结构却比较简单。一般来说,在数据类型丰富或操作不标准的应用中,很难用关系数据库管理系统来实现。

③与程序设计语言的连接不自然。大多数程序设计语言本质上是过程性的,每次只能处理一个记录,而SQL语言支持面向集合的操作,是一种非过程性语言,两者之间存在差异,连接不方便。

(3)面向对象数据库管理系统。

面向对象数据库管理(Object Oriented Data Base,OODB)系统是一种新技术,它的扩展设计途径如下。

①在关系数据库基础上,增加了一些操作功能。例如,增加了抽象数据类型和继承性,以及创建及管理类和对象的通用服务。这种面向对象数据库管理系统称为扩充的关系数据库管理系统。

②面向对象程序设计语言中扩充了数据库的功能。例如,扩充了存储和管理对象的语法和功能。这种面向对象程序设计语言称为扩充OODB的面向对象程序设计语言。

③从面向对象方法本身出发设计数据库。开发人员可以用统一的面向对象观点进行设计,不再需要区分存储数据结构和程序数据结构(生存周期短暂的数据)。

首先保留对象值,然后在需要时创建该对象的一个副本。这是大多数对象管理模式都采用的“复制对象”的方法。扩充的面向对象程序设计语言支持“永久对象”方法:确切地存储同样的对象,包括对象的内部标识,而不是仅仅存储一个对象的副本。当从存储库检索到一个对象时,该对象与先前存在的那个对象是完全相同的。“永久对象”方法,为在多用户环境下的对象服务器中共享对象奠定了基础。

2)选择数据管理子系统

无论基于哪种数据管理模式,设计数据管理子系统都包括设计数据格式和设计相应的服务两部分。

(1)设计数据格式。

不同的数据存储管理模式,其设计数据格式的方法也不同。下面分别介绍几种数据存储管理模式的数据格式设计方法。

①文件系统。

文件系统设计数据格式的步骤如下:

· 列表给出每个类的属性(既包括类本身的定义属性,又包括继承的类的属性);

· 将所有属性表格规范为第一范式;

· 为每个第一范式表定义一个文件;

· 测量性能和需要的存储容量能否满足实际性能要求;

· 若文件太多时,则把一般-特殊结构的对象文件合并成一个文件,以减少文件数量。必要时把某些属性组合起来,并用某些编码值表示这些属性,而不再分别使用独立的域表示每个属性。这样做可以减少所需的存储空间,但是增加了处理时间。

②关系数据库管理系统。

关系数据库管理系统设计数据格式的步骤如下:

· 列出每个类的属性表;

· 将所有属性表格规范为第三范式;

· 为每个类定义一个数据库表;

· 测量性能和需要的存储容量能否满足实际性能要求;

· 若不满足再返回第二步设计规范,修改原来设计的第三范式,以满足性能和存储需求。

③面向对象数据库管理系统。

面向对象数据库管理系统设计数据格式的步骤如下:

· 对于在关系数据库上扩充的面向对象数据库管理系统,其处理步骤与基于关系数据库的处理步骤类似;

· 由面向对象程序设计语言扩充而来的面向对象数据库管理系统,不需要对属性进行规范化,因为数据库管理系统本身具有把对象值映射为存储值的功能。

(2)设计相应的服务。

如果某个类的对象需要存储起来,则在该类中应该增加一个属性和服务,用于完成存储对象自身的操作。通常把增加的属性和服务与对象中其他的属性和服务分离,作为“隐含”的属性和服务,在类对象的定义中描述,不在面向对象设计模式的属性和服务层中显示地表示出来。

“存储自己”的属性和服务形成了问题域子系统与数据管理子系统之间必要的桥梁。若系统支持多继承,那么用于“存储自己”的属性和服务应该专门定义在一个基类“Object Server”(对象服务器)中,通过继承关系使那些需要存储对象的类从基类中获得该属性和服务。

同设计数据格式一样,不同的数据存储管理模式,其设计相应服务的方法也不同。下面分别介绍每种数据存储管理模式的相应服务的设计方法。

①文件系统。

采用文件系统设计时,对象需要确定打开哪个文件,在文件中如何定位,如何检索出旧值(如果存在)及如何更新值。因此,需要定义一个“Object Server”类,该类应该提供两个服务:

· 告知对象如何存储自己;

· 检索已存储的对象(查找、取值、创建或初始化对象),以便把这些对象提供给其他子系统使用。

②关系数据库管理系统。

采用关系数据库管理系统设计时,对象需要确定访问哪些数据库表,如何检索到所需的行(元组),如何检索出旧值(如果存在)及如何更新值。因此,还应该专门定义一个“Object Server”类,并声明它的对象。该类应该提供下列服务:

· 告知对象如何存储自己;

· 检索已存储的对象(查找、取值、创建或初始化对象),以便由其他子系统使用这些对象。

③面向对象数据库管理系统。

· 在关系数据库上扩充的面向对象数据库管理系统,与使用关系数据库管理系统时的方法相同。

· 对于由面向对象程序设计语言扩充而来的面向对象数据库管理系统,没有必要定义专门的类,因为该系统已经提供了为每个对象“存储自己”的行为。只需给需要长期保存的对象加个标记,这类对象的存储和恢复由面向对象数据库管理系统负责完成即可。