面向对象方法中的数据库设计
2011年03月01日
首先想说的是面向过程的的数据流分析方法不是不正确,只是它不符合对象分析方法。两者的出发点是不同的,就象向两个不同方向前进的队伍,是无法调合的。而现在很普遍的所谓面向对象设计时“先建立数据库表,然后将其封装,设计类”则是彻头彻尾的错误! 套上一个面向对象的马甲,干的是完全不面向对象的事情。面向过程方法下的表设计还有数据流为推导,而这种伪对象方法为了穿上面向对象的画皮而抛弃了数据流的马甲,却又不按照对象分析方法行事,就更不知道数据库表是如何推导出来的了。
运用最广的Hibernate在实际中有太多的误用,OR-mapping被仅仅当成数据库物理表和对象之间的简单一一对应,其本质还是先设计数据库再设计类。再强调一次“面向对象设计解决业务执行逻辑问题,数据库设计解决数据高效的问题”,它们本质上是两个领域的设计,只是由OR-mapping来连接它们。要采用面向对象方法,首先要忘记数据库的存在,采用对象分析方法,先把对象分析和定义出来,保证业务执行逻辑能够被这些对象很好的完成。达到这一点后,再来考虑对象持久化的问题。依据数据库的三大范式以及性能要求来把对象持久化。注意!!这时我们设计数据库要解决的问题是“对象数据高效持久化”,而不是业务逻辑!它不是从需求中推导出来的! 例如面向过程的设计中,一张申请表很可能被设计成一张物理表;而面向对象设计中,很可能没有申请表这么一张物理表,而只有“用户资料”、“申请流程”、“申请资质”等对象表,所谓的申请对象,是在运行期由这些对象聚合而成的。
每个对象都有自己的属性和状态,我们需要把这个对象的属性和状态保存在数据库中,那么最理想最最简单的情况,就是一个对象对应一张物理表,而对象之间的关联关系(一对一,一对多,多对多)也可以简单的映射成数据库的主-外键关系。 但还有很多非数据库关系需要考虑,如:继承、聚合、依赖等。一张表如何继承自另一张表呢?关系数据库显然没有这样的定义,这就需要用OR-mapping来完成这种语义的转换。例如,当实例化一个子对象时,OR-mapping负责从代表了“父”对象的表中读出父对象属性并将其赋值给子对象,并且当父对象变化时,OR-mapping需要把这一变化反映到所有子对象实例(这只是一种OR-mapping方案,也有在所有子表里冗余存贮父对象属性来实现的)。再比如聚合对象,一个公司对象由公司基本信息以及一个部门List构成,那么在持久化这个对象时显然需要把它分成公司表和部门表(一对多关系),在业务逻辑执行过程中操作公司对象时它们始终是一体的对象,但当CUDR这个对象时OR-mapping要负责将对对象的操作转化为对两张表的操作。而依赖表示了两个对象之间相互依存的关系,当一个变化时另一个相应的要变化。这在数据库中可以由Insert\update\delete 引发的trigger来实现,但更好的做法显然是由OR-mapping来实现这种关系的管理。
实际上我们所遇到的情况只会更加复杂,一个复杂的业务对象可能对应的数据库中的许多张表;一些简单的对象也可能只对应数据库中某张表的一部分。现在我们应该明白OR-mapping的作用了,它不是负责将数据表直接翻译成为对象那么简单,它负责的是将对象关系语义转化成数据关系语义。换言之,OR-mapping负责的是“数据”和“表现”的分离,数据如何存贮和查询是一回事(由三大范式和性能优化考虑决定),数据如何表现又是另一回事(由业务执行逻辑和高效面向对象设计决定)。如果一个or-mapping做得足够好,能完美支持对象关系和数据关系的转换的话,你就可以独立的更改对象和数据库,之后只需要重新配置一下mapping关系即可。
一个典型的例子,在面向对象的设计中,业务逻辑和控制逻辑通常是分离的。比如一个定单对象,在业务执行逻辑上,除了业务数据,它还需要一些状态属性来标识流程控制进程;但是流程控制进程通常都不是业务数据的一部分,它只是系统的控制逻辑。在好的面向对象设计中,这种控制逻辑是可以分离出来用另一组对象来标识,再通过对象的聚合或者对象之间的依赖注入来将两者动态绑定的。在以数据流为基础的数据库设计中,通常的做法是将状态控制字段与业务字段设计在同一张表里的。其结果是控制逻辑与业务逻辑被静态绑定,这意味着两者都不能独立变化。只要查看一下现在的很多系统中,当流程变化时导致要更改业务表,或当业务数据变化要改流程,就说明该设计不是一个面向对象的设计,或者至少是一个糟糕的面向对象设计。真正好的面向对象设计会分离业务逻辑和控制逻辑,在运行过程中业务对象与流程控制对象是独立加载并在流程控制框架下动态绑定的。这意味着两者都获得了独立变更的能力。在此基础下持久化业务对象和流程控制对象的结果是必然会形成一组流程控制表和一组业务数据表,它们两者之间是没有静态依赖关系的,某个流程实例的控制状态只会存在于流程控制表而不会存在于业务表中。因此,流程控制与业务得以解耦而独立变更。
如果将革命进行得更彻底一些,我们甚至可以仅仅将数据库视为保存数据的一种手段,而放弃数据库的约束,如主-外键关系。在笔者以前进行的一个项目中进行了这样的尝试,所有数据库表之间均没有主-外键关系,没有trigger,没有约束,每张表都是独立的,每张表都是直接对象的持久化的结果,数据库甚至不管理对象之间的关联关系,每张表仅由一个唯一的主键ID来标识对象实例。而对象之间的关系全部抽象出来用一组对象关系表来管理,一条关系表记录表示两个对象ID之前的一种关系,由一个对象关系管理框架来管理它们。对象关系管理框架管理对象之间的“关联”、“继承”、“依赖”等简单关系,同时经过扩展,这些关系可以扩展成为更复杂的对象关系,例如可以在关系当中加入时间因素,表示某两个对象在一定时间之内是“关联”的或“继承”的;也加入版本因素,表示某两个对象在某个版本当中是“关联”的;甚至可以加入条件因素,用一个正则表达式来表达在什么条件下两个对象产生“关联”关系。在这个管理框架下,对象理论上拥有无限的扩展能力,而这种能力却不依赖于数据库。一张数据库表的变化仅仅影响它对应的持久化的那个对象而已。我们完全可以在程序中动态的创造出对象关联(向关系管理框架中加入一个关系实例)从而动态的创造出一个全新的对象,我们也可以扩展关系管理框架中的关系而得到更加复杂的对象组合。
但是彻底的革命也并不是完美的,这种与数据库关系彻底的决裂意味着我们同时放弃了数据库的高效,完全由程序来管理对象关系不但引入了一个复杂的框架,同时整体性能也大受影响!例如,一个拥有子对象的对象在采用数据库关系管理时,我们可以用一条SQL语句来加载这个对象;在采用对象关系管理框架以后,我们必须先得到一个对象,然后向关系管理框架咨询它所关联的对象ID,然后再加载它,这个过程必然产生多条SQL调用。CURD所有操作都需要额外的向关系管理框架咨询和操作,得到扩展能的同时牺牲了性能。但现实就是这样,人生不如意十之八九,得到一些总是会失去一些的。好在在性能要求不太高的场合,这个框架是相当有效的!以致于在项目过程中我们从未对数据库修改头疼过,因为我们的程序逻辑、显示逻辑等与数据库是无耦合的,我们使用的是一种称为ValueObject的 POJO来作为业务实体对象和显示对象;而这个ValueObject是由关系管理框架根据对象关系将持久对象(Persistence Object)动态组合出来的。等效于我们解耦了实体对象和实体对象的持久化结果,自然的,数据库的修改就变得轻松很多了。
今天的文章里详细讨论了面向对象方法里数据库的设计方法。如果你是一个面向对象的革命者或愤青,那么你可以宣称面向对象不需要数据库设计(估计这是少数派)!如果你是一个面向过程的保守派,那么你可以宣称数据库设计是一切的核心(估计这是多数派)!然而我们还是现实一些,站在实用主义的角度,承认:
面向对象方法是非常行之有效的;数据库设计应当围绕着对象的高效持久化进行而不是以数据库设计为核心;
关系数据库的高效及方便不是对象数据库模式在短期内可以轻易达到的,我们不能因为倒脏水把婴儿也泼掉了;
最好的方法是根据实际项目对性能和扩展性的要求,在性能要求高的场合可以适当牺牲面向对象的特性来达到性能要求,在扩展性要求高的场合则可以适当牺牲数据库性能来满足扩展性。
发表评论
-
VisualTreeHelper知识点
2012-01-20 01:09 591VisualTreeHelper知识点 2010年08月16 ... -
加快RIA开发效率之Flex插件
2012-01-20 01:08 509加快RIA开发效率之Flex插 ... -
关于Java环境变量的学习
2012-01-20 01:08 627关于Java环境变量的学习 ... -
Wix使用笔记(七) 添加系统必备组件的安装程序
2012-01-20 01:08 1079Wix使用笔记(七) 添加系统必备组件的安装程序 2010年 ... -
如何配置Tomcat 5和IIS 5协同工作
2012-01-20 01:08 637如何配置Tomcat 5和IIS 5协同工作 2010年06 ... -
各种编程语言介绍
2012-01-19 08:58 622各种编程语言介绍 2011年07月09日 【IT168知 ... -
对比java和python
2012-01-19 08:57 908对比java和python 2011年04 ... -
Android开发之Android体系架构介绍
2012-01-19 08:57 996Android开发之Android体系架构介绍 15小时前 ... -
[强帖转载]C++、java、.net关系
2012-01-19 08:57 646[强帖转载]C++、java、.net关系 2011年03月 ... -
BusyBox 简化嵌入式 Linux 系统 (转载)
2012-01-19 08:57 559BusyBox 简化嵌入式 Linux 系统 (转载) 20 ... -
选择不对,努力白费。活着就要对得起父母和自己
2012-01-17 01:28 362选择不对,努力白费。活着就要对得起父母和自己 2011年10 ... -
转:“让大家两年不买房”,真有意思啊!!
2012-01-17 01:28 375转:“让大家两年不买房”,真有意思啊!! 2011年11月0 ... -
。。。
2012-01-17 01:27 549。。。 2011年11月19日 浣 -
经典人生哲理之成功法则
2012-01-17 01:27 534经典人生哲理之成功法则 2011年10月13日 澶辫触骞 ... -
第五卷《鏖战雁门(下)》第41章《良夜》
2012-01-15 20:08 577第五卷《鏖战雁门(下)》第41章《良夜》 2011年01月0 ... -
微小说。(5)
2012-01-15 20:08 469微小说。(5) 2011年12月21日 1、他鼓足勇气和 ... -
中华隋唐年间历史上真实的18条好汉(隋炀帝~唐高祖)
2012-01-15 20:08 772中华隋唐年间历史上真 ... -
隋书 卷四十七??列传第十二
2012-01-15 20:08 499隋书 卷四十七??列传第十二 2011年03月29日 韦 ... -
第六卷《霍邑争锋》第49章《谣言》
2012-01-15 20:08 690第六卷《霍邑争锋》第49章《谣言》 2011年01月17日 ... -
巧用hosts文件,解决急手问题
2012-01-11 12:18 532巧用hosts文件,解决急手问题 2011年03月01日 ...
相关推荐
面向对象的关系数据库设计 面向对象的关系数据库设计
面向对象的数据库设计方法.pdf 面向对象的数据库设计方法.pdf
面向对象数据库设计分析01.pdf
数据库原理、面向对象程序分析与设计pdf合集
最新面向对象数据库技术
内容面向对象的数据库设计对象关系模型实体对象关系模型应用总结下载参考资料简介: 面向对象(OO)和三范式(3NF)都是成熟的设计方法,本文基于面向对象设计思想和三范式数据库设计方法,提出一种实体对象分层...
文献检索课程设计报告(面向对象数据库研究).pdf文献检索课程设计报告(面向对象数据库研究).pdf文献检索课程设计报告(面向对象数据库研究).pdf文献检索课程设计报告(面向对象数据库研究).pdf文献检索课程设计报告...
基于Oracle9i中面向对象关系数据库程序设计.pdf
本书以面向对象的软件工程思想为主线,细致深入地讲解了C#语言面向对象程序设计的方法和技巧,内容涵盖面向对象的基本概念、基于接口的设计、泛型程序设计方法、Windows和Web应用开发,以及数据库访问技术。...
面向对象集成空间数据库管理系统的设计与实现
针对面向对象技术和关系数据库的特点,将两者相结合,建立了对象关系数据库管理系统,既支持已经被广泛使用的SQL,不仅具有良好的通用性,又具有面向对象特性,能支持复杂对象和复杂对象的复杂行为,是对象技术和...
Java面向对象程序设计 例子源代码 耿祥义 张跃平 清华大学出版社
教学大纲,同学们可以看看其中的重点。 1、讲解面向对象的基本概念、原理; 2、讲解面向对象方法的三种模型...6、面向对象设计方法的四个子系统:问题域子系统、人机交互子系统、任务管理子系统、数据库管理子系统。
使用UML进行面向对象分析与设计:第13章 数据库设计.pdf
介绍了西安交通大学CIMS研究中心, 近几年来所研制的面向对象数据库管理系统CIS-ODBMS的图形用户界面。它是一个交互式图形界面, 用户通过鼠标完成对教据库的各种操纵, 这种操纵十分直观和方便。
面向对象数据库把面向对象的方法和数据库技术结合起来,使得数据库的分析、设计最大程度地与人们对客观世界的认识相一致,是数据库技术中巨大的进步。概述了面向对象数据库的特征、优势及其重要技术,并对这一技术...
面向对象数据库设计(ODL语言定义)
面向对象的概念来自面向对象的程序设计语言,实际上,面向对象的概念和应用已经超越了程序设计语言,扩展到很宽的范围,如面向对象的数据库系统、面向对象的系统分析与设计、CAD技术、人工智能以及其他广泛的应用...