这倒是个提得比较好的问题。
OO设计同E-R设计有区别有联系,讨论清楚它们之间关系很有价值:)一,是静态的对应关系,实体对象以怎么对应成数据库物理表。
二,我想主要OOD的问题,怎么样设计业务对象与数据访问对象,以及它们关系。应该可以从一些实际的设计看到这方面的东西。
希望继续讨论。

解决方案 »

  1.   

    正是在OO设计与E-R设计上,往往大家可以用E-R图将数据库结构规划出来,但是在落实到代码上,就成了“面向对象语言”编写的“非面向对象软件”。
      

  2.   

    在我的印象中,候捷先生曾在东软讲课时提到过,在现有的基础上,使用面向对象的程序设计语言,结合关系数据库来进行面向对象的数据库管理系统编程。
    我想说的是,没有错,面向对象数据库能够和OOP语言很好地融合,但是正所谓
    “自求多福”,后台数据库没有的我们的程序为什么不能加上一层对象抽象层呢?我一直对这个问题很感受兴趣,也尝试过一些方法,可惜的总是找不到一个很好的全盘解决方法,为些特发此贴,看有无高人先行一步,较好地解决了这个问题。“路漫漫其修远矣,吾将上下而求索”
      

  3.   

    你想到的
    我想BORLAND的工程师也想到过:)但是,我认为,在前台将数据封装入对象里带来的最大问题,就是效率。
    如果把关系数据库中每一条记录作为一个对象来处理……你这个系统得有多少个对象?
    再说,数据库处理不光是对单条记录的(插入、修改)操作。更多、更复杂,也更有实用性的是(基于批量的)查询、搜索等操作。这些操作,对于你的前台程序来说,用大量对象来实现简直是不可思议的。你能够想象在上百万条记录中搜索一条记录的速度吗?当然,可以用索引。但即使这样,如果没有数据库端的支持,其速度也将是非常慢的。我对面向对象数据库并不是很了解。以上只是个人之见。
      

  4.   

    推荐一本书UML对象设计与编程第3章5节
    设计关系型数据库中最好能按照面向对象的方法。
    比如利用主从表模拟继承关系。
      

  5.   

    xixi!                     (一)实作企业物件
    封装企业规则的类别铺设了一个真正的OO应用系统的基础。这个月的专栏是我们探索实作一个真正的物件导向的应用系统的各个方面的系列的第一篇,在此系列中,我们将接触到应用系统设计的各个方面,并且挑战某些公认的撰写Delphi应用程序的方式。这种新的方法的基础的观念就是封装:设计一个具有良好设计接口(方法)的类集,可以通过通过属性操纵方法。这些观念将遍及整个应用系统并极大地影响着数据的存储和呈现方式。(好的类别设计的观念是无关于程序语言的)。如今撰写的大部分典型的Delphi应用系统都不是物件导向的。仅仅因为语言具有一个物件模型(如 Delphi整合发展环境),使用一些存在和(或)新的类别,并不意味着应用程式可以被认为就是一个真正的OO系统。**随着将第三方组件放置到From,代码重用已经结束了,并且Froms和units的相互依赖迅猛地增生扩散**。未来的改换应用系统的基础的机会(例如转换资料库或者将2层实作移到3层实作)被严格地束缚或者要代价高昂的预算。在一个真正的OO方式下书写的应用系统将推动,而非限制这种机会。然而,撰写这样的应用系统需要一个思维的转变,并陪伴有初期生产率的缺乏,这是大部分发展团队所不情愿或不能考虑的。在这些文章的课程中,我希望示范一些基本的原理,它们将帮助程序发展人员转换到书写更好的应用程式。结果的系统将具有更多的可靠性,可维护性,一致性,可扩展性,可重用性并且比之使用标准的方式书写的系统通常运行得更好(实际上,这点和UML常常是相通的)。特别地,对于大型系统,代码的清晰透明带来另一好处,就是使用真正的OO方式书写的系统比之传统的方式需要非常少的维护资源。我或许应该更进一步地证明一个OO系统的这些益处:我相信一个出售某样产品的IT追随者几乎是不应该逃脱问题争论中心的。OO系统所增强的可靠性来自于数据和操作被封装在良好设计的类别的事实。编译器自身鼓励通过强类型检查来纠正类别、方法和属性的使用,而且系统中只有唯一的而非多份代码意味着将来只需改变单个的程序(routine)就可以将影响遍及整个系统。正确地使用类别的带来的好处之一是类别之间的关系是不言而喻的,而且非常好的分摊代码书写实际上实现了应用程式的代码“肉”,不必担心细节(例如数据如何实际进行持续存储之类的)。这使得应用系统非常易于维护,更妙的是由于高度一致性加强了单一化。如同我们将看到的,使用类继承广泛地即增进了生产率和可靠性,同时也加强了一致性。这个一致性不仅明显地体现在代码的安排方式和类别的行为责任上,也包括数据的存储和UI界面的呈现的方式等。因为大部分的功能在基类中提供,使得有可能迅速地改变它们的表现来从根本上改变应用系统(例如将界面改变成为基于HTML的,而非窗体驱动的)。这些基类可以被设计成为应用无关的,因此使用这种方式书写的下一个应用系统可获得一个立即的生产率的提升,一个好的基类集在一个中型的应用系统中能提供多达50%的代码,还有其所占用的时间、代码和可靠性所带来的一个明显的好处。因此,转换到“真正的”OO发展模式并非是价值低微的;这个转换应该在极具经验的专家的辅助下进行,或者可试验在具有充足开发时间的小型项目上。我另外要强调的是,OO的解决方案并没有规定其它的类别一定能(或不能)包含在我们的应用系统当中。假如某家企业已经发展了他们自己的可视化元件,使用了那些第三方的元件,或者对于特定的资料库平台制定了自己的标准,那麽,没有任何理由废弃对这些元件的使用(但有一种例外情况,请先行思考,我将在后继文档中给出答案)。**发展一个OO应用系统更青睐于提供一个一致性的设计模式集合,而非指示你应该使用什麽样的组件。**聚焦类别发展任何物件导向的应用系统的第一步是考虑所需要的类别。这是绝对基础的关键性步骤,这同其他的发展技术是一样的(传统的发展技术也要考虑类别吧?),因为假如在这初期发生了错误,那麽其后纠正所花费的代价就太大了。在设计类别中,我们通常应当争取低耦合和高聚合--类别应该尽可能的独立于其它类别,但同时能组合得到强劲的功能。达到这个目标的一种方法是,以类别在应用系统中所扮演的角色来分类类别。对这些角色的明智的选择能够获得一个聚合的类别集合。**在类别角色的设计中重复着一个基本原则:即明确地分离负责表现,应用逻辑和存储的类别**。表现通常被描述成用户界面,而存储是储存数据的东西(典型的是存储在资料库当中)。虽然在三层开发中也具有同样的分离观念,但应注意的是,这只是一个概念设计上的分离,因而可以实作在许多方面:从单个集成电路系统直到完全的分布式多层应用系统。组成应用系统逻辑的类集是那些进行着实际大量的艰苦工作以操纵和处理用户激励所响应的数据的类别。在此层次上的一个类别子集被标识为描述真实世界实体的系统模型。它们通常被称为“企业”或“问题领域”类别。它们组成了任何OO系统的至关重要的部分,而大部分的其他类别将以某种方式来辅助它们,因而它们是所有相关发展人员所关注的中心。找出应用系统中的企业物件通常是一种经验上的意识,虽然在这过程中是有一套科学(或者说是艺术)。相较于传统技术例如SSADM,OO的漂亮之处是它的分析和设计都整个地维护了同一个实体。因此,我们有可能在OOA/OOD/OOP阶段看到对每个企业物件的描述。我们将在未来的专栏中探索一些识别企业物件的技术。暂时,我们假设此流程已经完成了。存在于不同层次上的类别之间的通讯是定义得很明确的并应被绝对地支持。一般地,我们这样定义三层关系:表现层(UI界面)能够访问应用层或是其它位于表现层的类别,应用层(企业物件)能够访问自身和存储层,而存储层只能响应应用层的请求(存储层之间不能相互通信)。企业物件为了示范企业物件是如何实现的,我们来看看一个已经完成的例子:一个小型的类集描述了典型的库存、客户和定单实体(一个公司有许多的待售的库存品,可让客户买入或下定单)。我们详细的分析已经明确了我们应该首先需要三个企业物件来描述每一个这样的实体。在我们的Delphi应用程式中我们拥有了三个类:TStockItem, TCustomer 和 TOrder。例示1显示了这些类别的一个删减的公共接口。值得注意的是类中的所有属性(attributes)都被描述为特性(properties):这是个简单而漂亮的类别设计,它利于控制对特性的访问(而这正是必需的)。还要注意特性是被描述在类别的published区域的(原因我们将在以后讨论),再者就是它们在适当时都有缺省值限定。虽然这个特性修饰仅仅是组件流机制作用的表面显示,但它实现了一个有用的功能,即标明每个特性的初始值,从而使代码能够进行自我描述。企业(问题领域)物件的基本原则之一是它们对于自己如何进行持续存储是不了解的。它们不知道被如何存储到资料库表中,事实上无论如何它们都绝对不能假设其任何存储机制。一个企业物件是一个仅仅恰好集中描述了最适当的特性和操纵它们的必需方法的类别。当设计类别的的公共接口时,在特性的类型上是不能对持续(资料库)存储作任何让步的。你应该总是给相关的特性选择最合适的类型,不必顾虑存在的资料库是否能无缝地支持它们。一个好的例子是这麽一个特性集:几乎没有哪个资料库直接地支持,但假如这是描述企业物件特性最自然的方式,那麽应该优先选择它而非另外的描述(可能是许多的Boolean体系的)。另外一个例子是将象地址的东西描述成TStringList。损害接口去迎合偏好的资料库存储不是企业物件的角色所在:这是持续存储层的任务。我们的第一个框架我们已经确定并实作了三个企业物件作为我们应用系统的初始基础。这三个物件共有着一个共同的角色:以某种方式描绘真实世界的实体。我们因此认为它们具有相似的特性**因而一个类层的存在是适当的**。我们将给这些物件一个共同的祖先,称为TPDObject(问题领域物件)。这个TPDObject类别将随着我们在类别中引入公共的方法和特性而被逐渐地扩充。应当注意TPDObject没有(并永远不会)包含任何应用特定的元素。作为一个应用无关的构造,它应该被放置在一个单独的单元且组成一个框架(一个可以被重用于许多应用系统的类集)的基础。随着时间的过去,我们的框架被极大的扩充以提供许多基础的类别,而这些类别提供了重要的应用无关的功能,以准备给特定的系统进行更深入地开发。我们的TStockItem, TCustomer 和 TOrder类别就是我们一般的TPDObject的进一步开发的版本的例子。列示1显示了一个稍近一些的例子,事实上,我们的三个问题领域类别均继承于另外一个类别,TMyAppPDObject,它自己是TPDObject的一个子孙类。虽然TMyAppPDObject的实作是空的,但这是另外一个好的类别设计的例子,假如我们想给我们所有的问题领域物件提供任何应用特定的元素,在我们的类层次结构中,这是个合适的地方。(未完,待续,文档更新/周)
      

  6.   

    我认为不错的一篇关于对象与关系数据库映射的文章.
    http://www-900.ibm.com/developerWorks/components/mapping-to-rdb/index.shtml
    这只是从静态的方面来看.
      

  7.   

    initora把我的想法更引早一层了,我的目标是首先使用面向对象技术编写资料管理系统,然后对某一通用的领域知识进行提取,成为这个领域通用的框架。谢谢指点,请继续关注本话题。
      

  8.   

    (二) 简单的物件关系呀呀!谁把我的文档全删了??TPDObject = class
    private
      FID: TObjectID;
    public
      property ID: TObjectID read FID;  // 
      ...... 
    end;上节说过,企业物件的关系可以经由详细地考虑它们的特性而实现,典型地,我们将其为描述企业类别的Property,因为实现的隐藏,我们获得了一个相当灵活的存取框架。那麽,如何来实现企业物件之间的关系呢?
      现在典型的数据持续是使用DBMS来实现的,我们稍稍降低我们的框架标准,使其更亲和SQL型资料库(当然,我们获得了更高效能的好处,嘻嘻!)。资料导向方式的典型的实现方式,是在Order类别中保存一个Customer的外键,因此,自然地,我们的发展人员会在Order 中放置一个CustomerID,这看起来非常合乎常理,而且非常地简单,(哦!不,天啊,怎麽会这样子--OO大师们一个个脸色发青--我再也不想和你呆在一块了)。我们看看究竟发生了葚麽?生成一个Order,找出它的CustomerID,再生成一个我们想要的Customer,之后,终于,我找到了下这个定单的CustomerName,他叫Smith.我相信绝大部分的程序员至少会皱眉,假如他们还没诅咒的话!从资料库管理的角度来说,假如要浏览100个Order的话,这个访问可真够受的,如果这样,我也要和 windindance(风舞轻扬) 一样大声说,“去死吧!OO”!
      幸运地是,假如换个角度,我们可以发现,Customer和Order的关系是如此的亲密,使得我们一劳永娱地解决这种类型的关系,“描述相关物件成为特性(Property)”,试试,Order.Customer.CustomerName,怎样?
      (网费太贵,整理后再发表)
      

  9.   

    热烈欢迎initora(伤心难过的时候,我学会了喝酒)的精彩文章,
    令人受益非浅!
    掌声鼓励!!!
      

  10.   

    呵.台湾的计算机用语听得真不是狠习惯:)我自己的体会,
    1,使用COM,CORBA等技术,从二进制上强制封装...
    2,把业务对象同数据访问对象分开,这一点,我认为在DELPHI这样的
    RAD进行OO开发相当重要,是否这样做,是一个开发思路的三叉路口.把业务对象独立出来,才容易在应用服务器端进行业务规则的实现,
    减小对数据库的依赖.
      

  11.   

    真对不起,小弟现在实在太忙,关于后续文档的整理要暂时终止啦,估计要一个月后方能有点空闲,如若不弃,请发mail至[email protected],我将在其后空闲将文档发出!
      

  12.   

    我的Email:[email protected]。谢谢!!!