日期:2014-05-16 浏览次数:20730 次
在公司文档库中发现一篇关于数据库系统在面向对象分析设计中的应用,感觉蛮有意思的,给大家分享下。(篇幅有点长)
?
前言:
本人一直想真正用面向对象的方法分析一个系统,并带着问题学习过几本面向对象系统分析的书(大多为老外所写),可能是本人太笨,总是看到一半就看不下去。
大部分的面向对象方法,给我的感觉就如老外的厨房用刀与中国人厨房用刀,老外有很多种刀,剁肉有剁肉刀,砍骨有砍骨刀,可中国人只有一把刀,干什么都用它。同样,在面向对象领域,很多方法为解决某一问题(或为精确描述某一问题)而引进或创造了新的概念,这些新的概念令我很是困惑,总是与实际联系不起来。我想找一把中国人用的刀,因为最简单的就是最好的。
有幸学习了邵维忠、杨芙清所著《面向对象的系统分析》,该书仅用最基本的面向对象概念,解决了大部分的问题,因该书的可操作性极强,因此尝试应用该书的理论编写一个系统。
刚巧父亲的橡胶厂因业务扩大,考虑采用计算机管理,于是,决定用该书的理论尝试我的第一个面向对象系统分析。
在分析过程中,大多数的问题都可依据该书的理论得到解决,但也有该书中没有描述到的问题,其中之一,就是怎样将数据库的优势应用在面向对象分析领域。
在本版各位网友的热情帮助下,经过不断的实践,不断地在理论上提升,我探索出了一种将数据库系统应用在面向对象分析设计领域的方法,并利用此方法成功地实现了一个管理系统。
下面我将我的一些体会与想法写出来,请大家指正,由于我想将文章最终整理成册,大家可以自由转载本文,但在转载时,请注明作者,也请注明出自本论坛。
本文除本人自定义的概念外,其余概念均引出《面向对象的系统分析》。
一、 理解类与对象实体集合的关系
这一点,是必须在建模时首先要搞清楚的。
类的定义通常是这样的:类是具有相同属性的服务的一组对象的集合,它为属于该类的全部对象提供了统一的抽象和描述,其内部包括属性和服务两个部分可见,类仅是个对象属性的描述,它给出了属于该类的全部对象的抽象定义,而对象则是符合这种定义的实体。
类描述了全部的对象,类不能用来枚举已经实体化的实体集合,这些实体仅是全部对象的其中一部分,类不是一个系统中已有对象实体的集合。
这里提到已有对象实体,是指在一个系统中,从类实体化出来的有限的实体集合。
少量的对象实体,可以在程序中实例化。当系统中已有对象实体的数量很多(但永远不可能是全部)时,怎样管理(增加、修改、删除、查询)这些实体就是系统必须解决的问题了。
所以,在系统建模时,必须为管理这些已有对象实体而建模。这个模型是用于增加、修改、删除、查询已有对象实体的,我们且把这个模型叫做实体管理模型。实体管理模型在面向对象的分析设计中,也是一个类。
而数据的增加、修改、删除、查询功能正是数据库的强项,因此,实体管理模型对应着数据库。
举例来说,系统中有一“联系人”类,其模型为:
属性:姓名、性别、电话
服务:报价
当系统中需管理的联系人的数量较少时,可实例化出这些数量的对象,分别对它们赋值,形成有意义的对象。
当系统运行到某一时刻(或预计到某一时刻),系统中将出现大量的联系人实体时,在系统初始化时,对每个实体实例化并赋值,这样的实现方法显然是不切实际的。
而“联系人”类并不能描述这些已经实例化的实体,必须为管理这些实体另行建模。
在日常生活中,我们会将这些联系人记在本子上以实现保存、增加、修改、查找等功能。同样,在面向对象的系统中,我们也应该建立“联系人通讯录”这样的一个模型(类),这个类应该是这样的:
属性:联系人
服务:增加、删除、修改、查找、取出。
“联系人通讯录”类与“联系人”类是整体-部份关系,我们可以充分利用数据库系统提供的各种便利来实现“联系人通讯录”的服务。这个类,往往在建模时是容易忽略的。
值得指出的是,“联系人通讯录”类中的“取出”服务,是从通讯录中取出某联系人。在设计上,它应该是一个返回联系人实体的函数。这个函数,是连接数据库概念与面向对象设计的关键函数之一。
?
二、数据库可以是对象属性的永久保留形式
数据库显然是可以用来保存系统中已实例化的一些对象特征的,如属性。但是,数据库不能直接将整个对象存贮起来(至少数据库不能直接存贮对象的服务),也就是说,数据库不能直接作为永久对象的保留媒介。
这是因为:对象是包括了属性与服务的整体,属性与服务是对象不可分割的两部份。而永久对象是生存期可以跨越程序的执行时间而长期存在的对象。
怎样处理那些不能直接永久化的部份呢(主要是服务),解决这个问题有两个思路:
1、 以数据库作出发点考虑
就是说,把对象、类的那些不能直接保留在数据库中的部份(如服务),以数据库的概念及方法间接地保留在数据库中,从数据库中取出后再还原出来。
比如:我们可以这样考虑:“联系人”的属性是一个数据库,在这个数据库中增加一个字段“类名”(或类编号),记录属性所属的类,再新建一个数据库,叫“服务库”,将每一个类的服务记录下来,
这样,就建立了属性-方法的对应关系,每一个独立的联合记录也就构成了一个完整的对象。
2、 以面向对象的眼光考虑
数据库仅记录对象的属性,仅完成属性的增加、修改、查找、删除功能,至于对象中的“服务”等,不放入数据库中,而在面向对象的分析及设计以至最终的实现中解决。从这个意义上来说,数据库仅是永久
对象属性的保留,而不是整个永久对象的保留。
在仔细考虑了这两个出发点,并作了一定量的模型试验后,得出的结论是:第二种思路是比较现实,也比较可操作的。这是因为:
1、 第一种思路破坏了面向对象概念的完整性,那些保留在数据库中间接部份及其转换的过程在面向对象的分析及设计时又如何建模呢?
而第二种思路不仅保留了面向对象概念的完整,而且非常清晰。
2、 第一种思路无论是在设计上还是在实现上,都存在很大的复杂性,而第二种思路实现起来非常容易,目前绝大多数的OO语言都支持。
3、 从充分发挥数据库与面向对象语言的长处来看,第二种思路显然是最合适的。
基于第二种思路,将数据库与对象的属性联系起来必须解决从对象到数据库的存贮,及从数据库到对象的恢复两个方法,这两个方法可以这样解决:
1、 从对象到数据库的存贮。
对象属性的改变方式可以划分为种,一是录入性的改变,如增加、修改一个联系人,二是程序触发性的,如开关的“开”“关”状态,无论哪种方式,都必须把这个改变永久性地记录到数据库中。
对于录入性的改变,直接设计一个录入画面并将录入的属性存盘即可。
对于程序触发性的属性改变,在这些属性所在的类模型(类)中设计改变这些属性的服务。如记录开关状态的State属性,可在开关的模型中设计ChangeState 的服务,调用 ChangeState服务时,除立即修改内
存中State 属性的状态外,还要查找这一开关对象在数据库中的记录,更新该记录。
2、 从数据库到对象的恢复。
这就要用到前面所提出的“取出”函数。在永久属性所在的模型中设计“取出”服务,该服务首先根据属性所在的类,实例化出一个空对象(所有属性值均为初始值的对象),再根据取出的条件,从数据库中取出符合条件的对象的属性值,将这些具体的属性值赋予该实例的对应属性,最终返回这一具有实际意义的对象实体。
注意,当“取出”服务根据属性所在的类,实例化出一个对象时,这个空对象已经具有了该类所有的一切服务。
?
三、 在数据库中体现类属性的相互关系
如前所述,数据库中应该只记录对象的属性值,数据库不处理对象的服务,对象的服务是交给面向对象的分析、设计以至最终实现中解决的问题。因此类的关系中,数据库只需解决它们之间属性的关系。
数据库是对象属性的永久保留,而对象所在的类可能存在继承关系,属性可能是从其它类继承而来的,因此,类的继承关系必须在数据库中得到体现。(根据本文的方法,类的继承关系的体现是必须解决的。一些面向对象的数据库理论,从各自的理论出发,有的避开了这个问题;有的纯从数据库的概念出发,另类解释继承的概念;有的只是其中的字段可以面向不同的对象而已)
类之间不仅仅存在继承关系,还有其它的关系。同样,所有的这些关系,在数据库设计中都是必须得到体现的。避开这些关系、另类解释这些关系的概念,都将破坏面向对象分析设计或数据库理论的完整性、统一性,都不能正确将面向对象的分析设计与数据库理论真正地结合起来。
所以,在讨论解决数据库体现类属性的相互关系前,我们必须先讨论一下类与类之间的关系。
按邵维忠教授的理论:类与类之间的关系,可以分为四种:整体-部分结构、一般-特殊结构、实例连接关系、消息连接关系。其中消息连接关系与属性的关系不大,在此不予讨论。
1、 整体-部分结构
整体-部分结构的定义如下:如果对象A是对象B的一个组成部分,则称B为A的整体对象,A为B的部分对象,并把B和A之间的关系称作整体-部分关系。
整体-部分结构表现的是"has a "的关系,如:客户与联系人、电脑与CPU、电话与按键等。
2、 一般-特殊结构
一般-特殊结构的定义如下:如果类A具有类B的全部属性和