O/R M一個(gè)相當常見(jiàn)的概念,不過(guò)也是一個(gè)被很多人誤解的概念。O/R M據我所知是從Java社區產(chǎn)生的,而到了.Net社區它的意味就完全變了。首先讓我們來(lái)看看為什么是O/R M而不是R/O M?其實(shí)之所以很多人沒(méi)有理解O/R M的含義就是因為沒(méi)有充分的考慮上面這個(gè)問(wèn)題。
以O為主還是以R為主?你是從面向對象的角度分析考慮問(wèn)題還是從關(guān)系的角度分析考慮問(wèn)題。
從面向對象的角度考慮問(wèn)題,意味著(zhù)你可以使用封裝,集成,多態(tài)這些面向對象的特點(diǎn)來(lái)描述和理解你的應用域,因為對象的高度抽象和可理解性,通過(guò)它你可以構造出一個(gè)用對象來(lái)描述領(lǐng)域的模型,這也是領(lǐng)域模型的由來(lái)。而一個(gè)好的模型必然要考慮到的幾點(diǎn)包括對象所包含的責任是否合理,對象與對象之間的關(guān)系是否合理等,而高內聚,低耦合就是用來(lái)衡量它們的一個(gè)技術(shù)標準。
可以看出一個(gè)好的領(lǐng)域模型,可以讓你清楚的了解現實(shí)的應用領(lǐng)域,而一個(gè)好的領(lǐng)域對象也必然具有高內聚,低耦合的特點(diǎn),而絕對不是一個(gè)數據包。
當我們使用面向對象技術(shù)建立好了我們的領(lǐng)域模型,一個(gè)問(wèn)題隨之而來(lái),對象如何持久化?對象的生命周期包括多個(gè)階段其中包括第一次被創(chuàng )建出來(lái),被持久化,被從文件(通常是數據庫)中取出來(lái),被垃圾回收。顯然我們希望能夠更多的關(guān)注與領(lǐng)域模型而非這些對象生命周期的管理,此時(shí)O/R M的需求應運而生,而能夠透明的實(shí)現對象的持久化和反持久化則更為我們所追求,此時(shí)再來(lái)看看某些使用O/R M來(lái)為一個(gè)領(lǐng)域對象實(shí)現Save Load的做法是多么與我們的想法背道而馳,這些方法與領(lǐng)域何關(guān)?O/R M框架將對象持久化功能從領(lǐng)域對象中分離出來(lái),交由框架負責,而有人竟然反其道而行之,這種現象在.Net社區尤為常見(jiàn)。為什么會(huì )這樣?因為考慮問(wèn)題的思路不同??梢赃@么說(shuō)在.Net社區O/R M往往被當作R/O M來(lái)使用。
從關(guān)系型模型的角度來(lái)考慮問(wèn)題,在一接到問(wèn)題之后,先建立實(shí)體關(guān)系模型,然后考慮各種約束條件,并通過(guò)Server端一系列的存儲過(guò)程來(lái)描述業(yè)務(wù)邏輯。這種方法曾廣泛被采用,然而兩相比較孰優(yōu)孰劣?和大多數人(Martin Fowler等等)一樣我更喜歡OO的方式,用對象來(lái)描述世界,比起關(guān)系和一堆的SQL語(yǔ)言對我來(lái)說(shuō),顯然前者更美,而且沒(méi)有了繼承多態(tài),那樣程序將充滿(mǎn)了重復代碼,并且不利于擴展,可讀性就更不用說(shuō)了。就如Martin Fowler所說(shuō)要不是因為.Net提供了方便的界面綁定方法,這種純粹的數據包對象誰(shuí)會(huì )去使用呢?它們的優(yōu)勢就在于那些領(lǐng)域邏輯簡(jiǎn)單的應用,這也是.Net常見(jiàn)的應用領(lǐng)域。
所以當你不是用對象的方法(不是說(shuō)你僅僅使用了面向對象語(yǔ)言)來(lái)分析解決問(wèn)題時(shí)請離O/R M遠一點(diǎn),這樣對大家都好。你不會(huì )覺(jué)得它奇怪,它也不會(huì )被你用的郁悶。
在這里我也順便談?wù)勎覍Linq的看法。首先我不得不承認它很Cool,并且我之前對Linq也做過(guò)介紹,但是我并不是很喜歡它的方式,至少它存在一種可能被濫用的危險。查詢(xún)你所需要的數據,然后圍繞這些數據做處理,微軟仍然堅持它一慣的風(fēng)格,并且在Linq中,可以說(shuō)是做到了極致---用Linq查詢(xún)數據太方便了。如果每個(gè)對象都通過(guò)這樣的方式獲得,那么對象之間的關(guān)系(Association)將變的雜亂無(wú)章。你在設計對象的時(shí)候仔細考慮的對象之間的關(guān)聯(lián)關(guān)系將被輕易的打亂(領(lǐng)域對象的關(guān)聯(lián)關(guān)系是描述領(lǐng)域模型的關(guān)鍵組成部分之一),而且你查詢(xún)到的純粹是數據實(shí)體,它們并沒(méi)有行為,你又會(huì )靠一個(gè)個(gè)的xxxManager來(lái)管理它們,喔,天哪,又失去了面向對象的優(yōu)勢。所以DLinq本身絕對不是一套O/R M工具,不過(guò)利用它實(shí)現一套O/R M工具倒是不錯的選擇。
當面對面向對象和關(guān)系型數據庫的阻抗失衡時(shí),Java社區更多的考慮的是自動(dòng)透明的實(shí)現將O映射成R的方式,而MS更多的考慮的是將R方便的變成O(數據包類(lèi)型的O而已)的方式(這點(diǎn)可能跟MS也是數據庫廠(chǎng)商有關(guān))。兩個(gè)方向,你選哪個(gè)?
個(gè)人觀(guān)點(diǎn)僅供參考。
BTW 前陣子有個(gè)兄弟問(wèn)我O/R M的性能怎樣?呵呵,總是有很多人關(guān)注性能問(wèn)題。那么我先問(wèn)問(wèn)大家
你覺(jué)得OO性能怎么樣?泛型性能怎么樣?AOP的性能怎么樣?SOA的性能怎么樣?呵呵,另人失望的答案,它們的運行效率都比不使用它們的方案低。但是它們能大大加強我們的開(kāi)發(fā)效率,這是一個(gè)追求效率的年代 :)
(我可沒(méi)有鄙視性能的意思)
6.8看過(guò)評論后更新
本文的觀(guān)點(diǎn)可能有很多人有不同意見(jiàn),這很正常,如我標題所寫(xiě)本文也僅僅是亂談而已。不過(guò)對于使用Hibernate的用戶(hù)請盡可能的考慮我所說(shuō)的問(wèn)題,因為我的觀(guān)點(diǎn)和Gavin King(Hibernate的作者)的還是基本一致的。同樣對于大家所說(shuō)的表很多的問(wèn)題,請參考Gavin King的原話(huà)。
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.
另外雙魚(yú)座在評論中指出"數據規模對采用哪種技術(shù)框架沒(méi)有太大關(guān)系,有比較大關(guān)系的是業(yè)務(wù)復雜度", 對此個(gè)人深表贊同。
聯(lián)系客服