享受代码,享受人生

SOA is an integration solution. SOA is message oriented first.
The Key character of SOA is loosely coupled. SOA is enriched
by creating composite apps.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

O/R Mapping乱弹

Posted on 2006-06-07 21:32  idior  阅读(19943)  评论(57编辑  收藏  举报


O/R M一个相当常见的概念,不过也是一个被很多人误解的概念。O/R M据我所知是从Java社区产生的,而到了.Net社区它的意味就完全变了。首先让我们来看看为什么是O/R M而不是R/O M?其实之所以很多人没有理解O/R M的含义就是因为没有充分的考虑上面这个问题。
以O为主还是以R为主?你是从面向对象的角度分析考虑问题还是从关系的角度分析考虑问题。

从面向对象的角度考虑问题,意味着你可以使用封装,集成,多态这些面向对象的特点来描述和理解你的应用域,因为对象的高度抽象和可理解性,通过它你可以构造出一个用对象来描述领域的模型,这也是领域模型的由来。而一个好的模型必然要考虑到的几点包括对象所包含的责任是否合理,对象与对象之间的关系是否合理等,而高内聚,低耦合就是用来衡量它们的一个技术标准。
可以看出一个好的领域模型,可以让你清楚的了解现实的应用领域,而一个好的领域对象也必然具有高内聚,低耦合的特点,而绝对不是一个数据包。
当我们使用面向对象技术建立好了我们的领域模型,一个问题随之而来,对象如何持久化?对象的生命周期包括多个阶段其中包括第一次被创建出来,被持久化,被从文件(通常是数据库)中取出来,被垃圾回收。显然我们希望能够更多的关注与领域模型而非这些对象生命周期的管理,此时O/R M的需求应运而生,而能够透明的实现对象的持久化和反持久化则更为我们所追求,此时再来看看某些使用O/R M来为一个领域对象实现Save Load的做法是多么与我们的想法背道而驰,这些方法与领域何关?O/R M框架将对象持久化功能从领域对象中分离出来,交由框架负责,而有人竟然反其道而行之,这种现象在.Net社区尤为常见。为什么会这样?因为考虑问题的思路不同。可以这么说在.Net社区O/R M往往被当作R/O M来使用。

从关系型模型的角度来考虑问题,在一接到问题之后,先建立实体关系模型,然后考虑各种约束条件,并通过Server端一系列的存储过程来描述业务逻辑。这种方法曾广泛被采用,然而两相比较孰优孰劣?和大多数人(Martin Fowler等等)一样我更喜欢OO的方式,用对象来描述世界,比起关系和一堆的SQL语言对我来说,显然前者更美,而且没有了继承多态,那样程序将充满了重复代码,并且不利于扩展,可读性就更不用说了。就如Martin Fowler所说要不是因为.Net提供了方便的界面绑定方法,这种纯粹的数据包对象谁会去使用呢?它们的优势就在于那些领域逻辑简单的应用,这也是.Net常见的应用领域。

所以当你不是用对象的方法(不是说你仅仅使用了面向对象语言)来分析解决问题时请离O/R M远一点,这样对大家都好。你不会觉得它奇怪,它也不会被你用的郁闷。

在这里我也顺便谈谈我对DLinq的看法。首先我不得不承认它很Cool,并且我之前对Linq也做过介绍,但是我并不是很喜欢它的方式,至少它存在一种可能被滥用的危险。查询你所需要的数据,然后围绕这些数据做处理,微软仍然坚持它一惯的风格,并且在Linq中,可以说是做到了极致---用Linq查询数据太方便了。如果每个对象都通过这样的方式获得,那么对象之间的关系(Association)将变的杂乱无章。你在设计对象的时候仔细考虑的对象之间的关联关系将被轻易的打乱(领域对象的关联关系是描述领域模型的关键组成部分之一),而且你查询到的纯粹是数据实体,它们并没有行为,你又会靠一个个的xxxManager来管理它们,喔,天哪,又失去了面向对象的优势。所以DLinq本身绝对不是一套O/R M工具,不过利用它实现一套O/R M工具倒是不错的选择。

当面对面向对象和关系型数据库的阻抗失衡时,Java社区更多的考虑的是自动透明的实现将O映射成R的方式,而MS更多的考虑的是将R方便的变成O(数据包类型的O而已)的方式(这点可能跟MS也是数据库厂商有关)。两个方向,你选哪个?

个人观点仅供参考。

BTW 前阵子有个兄弟问我O/R M的性能怎样?呵呵,总是有很多人关注性能问题。那么我先问问大家
你觉得OO性能怎么样?泛型性能怎么样?AOP的性能怎么样?SOA的性能怎么样?呵呵,另人失望的答案,它们的运行效率都比不使用它们的方案低。但是它们能大大加强我们的开发效率,这是一个追求效率的年代 :)
(我可没有鄙视性能的意思)

6.8看过评论后更新

本文的观点可能有很多人有不同意见,这很正常,如我标题所写本文也仅仅是乱谈而已。不过对于使用Hibernate的用户请尽可能的考虑我所说的问题,因为我的观点和Gavin King(Hibernate的作者)的还是基本一致的。同样对于大家所说的表很多的问题,请参考Gavin King的原话。

You should use Hibernate if you have a nontrivial application (definition of nontrivial varies, but I usually think of Hibernate being less applicable to applications with only ten tables or so) that use an object-oriented domain model. Not every application needs a domain model, so not every application needs ORM. But if your application does a lot of business logic - rather than just displaying tabular data on a webpage - then a domain model is usually a good thing.

Hibernate really starts to shine in applications with very complex data models, with hundreds of tables and complex interrelationships. For this kind of application, Hibernate will take away a huge amount of coding effort (perhaps up to 25%, for some applications) and will result in an application that performs better than the alternative handcrafted JDBC. This is possible because some kinds of performance optimizations are very difficult to handcode: caching, outer-join fetching, transactional write-behind, etc.

另外双鱼座在评论中指出"数据规模对采用哪种技术框架没有太大关系,有比较大关系的是业务复杂度", 对此个人深表赞同。

如果你想深入理解O/R M,推荐以下三本书:
Patterns of Enterprise Application Architeture
Hibernate in Action
Domain-Driven Design

相关文章