我的空間,寫我所寫,禪我所藏

          與我一起遨游吧

           

          Hibernate影響設(shè)計思路

          總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年07月23日 08:09 回復(fù)
          玩hibernate有些日子了,但一直沒敢在大型項目里用,主要是有種感覺:hibernate對設(shè)計思路有很大的干擾。

          說個具體的例子:
          很多應(yīng)用都要求記錄某一個業(yè)務(wù)對象的變更的歷史,比如說,一個issue-tracking系統(tǒng)里,對issue的每一個處理步驟都要有紀(jì)錄。這時,數(shù)據(jù)庫通常設(shè)計為一個主表和若干個屬性表,主表中保存業(yè)務(wù)對象不會變的屬性,例如ID等等,屬性表中記錄經(jīng)常更新的屬性,兩個表用主表ID相關(guān)聯(lián)。若屬性發(fā)生的修改,主表中不會變化,而屬性表中會加入一個新的紀(jì)錄,紀(jì)錄中保存新的屬性值、創(chuàng)建時間、創(chuàng)建人等等。

          這樣的設(shè)計應(yīng)該是很常用的,但是若使用hibernate來實現(xiàn),總覺得相當(dāng)別扭。特別感覺OR-Mapping似乎對業(yè)務(wù)邏輯設(shè)計有很大的影響。比如:
          理想的方法,應(yīng)該是把整個業(yè)務(wù)對象表達(dá)成一個類(包括在主表中的屬性和在屬性表中的屬性)。可是使用hibernate,如何做這種mapping?
          如果把一些屬性單獨(dú)抽象成類,,這個屬性類的實例作為主類的一個屬性保存。這樣對hibernate實現(xiàn)倒是簡單了,只要一個one-to-many影射就好,但是這樣業(yè)務(wù)邏輯表達(dá)上就嚴(yán)重不爽了。

          不知道有沒有DX處理過這類問題?

          banq

          發(fā)表文章: 7538
          注冊時間: 2002年08月03日 17:08

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年07月24日 17:55 回復(fù)
          》hibernate對設(shè)計思路有很大的干擾
          非常正確的感受,這就是數(shù)據(jù)庫驅(qū)動設(shè)計和模型驅(qū)動設(shè)計不匹配引起的,因為你的習(xí)慣思路是數(shù)據(jù)庫驅(qū)動設(shè)計思路,而Hibernate則是模型驅(qū)動設(shè)計思路,所以,你覺得有干擾,對抗發(fā)生了。

          >應(yīng)該是把整個業(yè)務(wù)對象表達(dá)成一個類(包括在主表中的屬性和在屬性表中的屬性)??墒鞘褂胔ibernate,如何做這種mapping?
          這就需要使用到DDD領(lǐng)域驅(qū)動設(shè)計,首先設(shè)計出領(lǐng)域模型Model,然后再使用Hibernate等mapping工具將其持久化。

          在你腦海中去除數(shù)據(jù)庫設(shè)計影子,才能嫻熟使用Hibernate這些為OO服務(wù)的框架,如果你的思維不是OO,當(dāng)然干擾就會發(fā)生,問題出在你自身啊。

          參考:面向ο蠓治`^程

          strangecat2005

          發(fā)表文章: 8
          注冊時間: 2006年07月23日 07:57

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年07月25日 13:13 回復(fù)
          strangecat20056M1NVeQg5v.png

          我覺得不可能徹底的和數(shù)據(jù)庫特型剝離。說一個具體的例子吧。背景看上面的圖,基本上Issue類寫成下面這樣:


          class Issue{
          ...
          List issuePropPackList;

          public IssuePropPack getCurrentIssuePropPack(){
          }

          public IssuePropPack getHistoryIssuePropPack(){
          }


          public List getHistoryPropPackList(){
          }

          }


          那么,getCurrent/History IssuePropPack這兩個方法如何寫?標(biāo)準(zhǔn)OO應(yīng)該是從List里面找,因為這是它的屬性;但是實際上,估計多數(shù)人會用HQL直接查數(shù)據(jù)庫,找兩個PropPack--為了效率著想。


          strangecat2005

          發(fā)表文章: 8
          注冊時間: 2006年07月23日 07:57

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年07月25日 17:44 回復(fù)
          但是,使用HQL來找相應(yīng)的實例,明顯就是在設(shè)計實現(xiàn)中引入了數(shù)據(jù)庫的概念了...

          j10A

          發(fā)表文章: 32
          注冊時間: 2006年03月11日 09:13

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年07月25日 18:43 回復(fù)
          若你一定要勉強(qiáng)采用所謂OO,無疑是畫地為牢。過分的強(qiáng)調(diào)OO,只會讓你的設(shè)計變的呆板。怎么定義先進(jìn)?倒覺得你應(yīng)該仔細(xì)考慮這個問題。

          strangecat2005

          發(fā)表文章: 8
          注冊時間: 2006年07月23日 07:57

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年07月25日 20:24 回復(fù)
          > 若你一定要勉強(qiáng)采用所謂OO,無疑是畫地為牢。過分的強(qiáng)調(diào)OO
          > 換崛媚愕納杓票淶拇舭?。怎么定义先娇倒觉得拈?#937;米邢
          > 考慮這個問題。

          我正式覺得不能強(qiáng)往OO上靠,才會想討論這個問題的。

          把別人的方法論想透,或者理出屬于自己的方法論,把事情想透了,用起來才有章法。



          banq

          發(fā)表文章: 7538
          注冊時間: 2002年08月03日 17:08

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年07月26日 18:44 回復(fù)
          >我覺得不可能徹底的和數(shù)據(jù)庫特型剝離。說一個具體的例子吧。背景看上面的圖,基本上Issue類寫成下面這樣

          這是一個一對多的關(guān)聯(lián)關(guān)系,建立好這個模型后,當(dāng)我們從Hibernate持久層獲得Issue對象時(需要定義Hibernate的mapping的one-to-many關(guān)系),Issue的issuePropPackList集合已經(jīng)有數(shù)據(jù)(可采取Open session in view提高效率)。

          因此,業(yè)務(wù)層獲得的Issue是一個完整的與數(shù)據(jù)庫無關(guān)的完全OO對象;

          如果不使用Hibernate,則在業(yè)務(wù)層和持久層之間封裝一個工廠,專門來生產(chǎn)Issue對象,然后充實Issue的issuePropPackList集合屬性,如果因為效率,可以考慮使用DDD推薦的組合模式(Respository)又被翻譯成倉儲,主要用來返回一批對象,查詢組合常用來返回批量查詢結(jié)果。

          數(shù)據(jù)是從數(shù)據(jù)庫獲得,但是數(shù)據(jù)庫的影響完全從業(yè)務(wù)層杜絕了,排除了在業(yè)務(wù)核心代碼中隨時出現(xiàn)的數(shù)據(jù)庫訪問,這樣的代碼肯定不能重用性;也反映程序員是在寫流水帳,想到什么數(shù)據(jù)就從數(shù)據(jù)庫取,很隨意,這樣的流水帳系統(tǒng)是毫無設(shè)計的,這樣的系統(tǒng)有維護(hù)性和拓展性嗎?

          杜絕流水帳的編碼,使用領(lǐng)域模型好好規(guī)劃你的模型對象,將數(shù)據(jù)庫陰影從業(yè)務(wù)層趕出去,這是DDD試圖告訴我們的,這也是一個正確的OO系統(tǒng)應(yīng)該做到的。

          strangecat2005

          發(fā)表文章: 8
          注冊時間: 2006年07月23日 07:57

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年07月27日 22:37 回復(fù)
          banq:
          其實推而廣之,我用的這個例子可以看出不少常用場景的影子,一個例子就是大數(shù)據(jù)量的瀏覽分頁。

          而你的思路恰恰是我不敢在大型項目里使用hibernate的原因:
          系統(tǒng)構(gòu)架設(shè)計的時候一個重要的地方是考慮負(fù)載的分配,哪些東西在數(shù)據(jù)庫解決,哪些東西在應(yīng)用程序里解決。比如,從一個List中選取一個特定的值,當(dāng)然可以把數(shù)據(jù)都調(diào)進(jìn)來,然后iterate中一個一個的判斷查找,也可以直接用一個select語句,從數(shù)據(jù)庫里直接把制定的結(jié)果選出來。顯然,只有合理的分配負(fù)載,系統(tǒng)才能高效的完成功能。

          但從你的思路中,全OO的一個潛在的意思就是讓hibernate去處理負(fù)載的分配問題,自己的設(shè)計完全不進(jìn)行考慮。這種想法在理論上顯得漂亮,但實際用的時候,能保證效率嗎?

          banq

          發(fā)表文章: 7538
          注冊時間: 2002年08月03日 17:08

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年07月28日 17:38 回復(fù)
          >但從你的思路中,全OO的一個潛在的意思就是讓hibernate去處理負(fù)載的分配問題,自己的設(shè)計完全不進(jìn)行考慮。這種想法在理論上顯得漂亮,但實際用的時候,能保證效率嗎?

          你的擔(dān)憂是非常有道理的,其實使用Hibernate 的Open Session in View只有在真正遍歷集合數(shù)據(jù)時才會讀取數(shù)據(jù)庫或緩存(如果二次以上是緩存),所以,在編程時我們回避了數(shù)據(jù)庫,實現(xiàn)分層設(shè)計目的,而在運(yùn)行時,它們是混合在一起運(yùn)行的,這實際已經(jīng)成為我們目前一個設(shè)計主概念,例如AOP等等都是玩這樣的把戲。

          如果理解這樣的思路,我們來對付負(fù)載就有辦法,因為首先負(fù)載是運(yùn)行時的負(fù)載,根據(jù)上面運(yùn)行原理得知,負(fù)載還是集中在業(yè)務(wù)層的Service上,這時我們講這些Service使用集群性質(zhì)的Session Bean實現(xiàn),就解決了負(fù)載問題。

          總之一句話:分而治之!

          alexzhou

          發(fā)表文章: 3
          注冊時間: 2006年07月31日 11:03

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年07月31日 11:04 回復(fù)
          是設(shè)計要改變了,設(shè)計的過程不是一成不變的,和系統(tǒng)架構(gòu)很有關(guān)系

          banq

          發(fā)表文章: 7538
          注冊時間: 2002年08月03日 17:08

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年08月03日 16:03 回復(fù)
          在現(xiàn)代系統(tǒng)設(shè)計中,數(shù)據(jù)庫影子基本看不見了。

          大家可以查看開源軟件的appFuse,在其中你都無法尋找到數(shù)據(jù)庫SQL結(jié)構(gòu),甚至找不到Hibernate Mapping文件,它們都附屬在Domain Model 對象中了。
          https://appfuse.dev.java.net/

          如果這么極端的例子無法接受,學(xué)習(xí)學(xué)習(xí)JiveJdon3,它也是一個DDD設(shè)計的案例,只是數(shù)據(jù)庫使用了以前版本的,實現(xiàn)一個過渡銜接。

          recher

          發(fā)表文章: 25
          注冊時間: 2004年02月10日 14:06

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年08月03日 17:19 回復(fù)
          我是一個hibernate的反對者,我認(rèn)為hibernate是技術(shù)牛人,架構(gòu)笨蛋搞出來的東西(請寬恕我的無禮,我只想引起大家的重視).我曾經(jīng)在我的blog上都批評了hibernate了幾次。我現(xiàn)在總結(jié)一下我的觀點:hibernate有三個理由我們不能覺得它是O/R mapping的企業(yè)化工具。
          第一,它不符合人類的抽象思維,hibarnate是業(yè)務(wù)操作對象-->業(yè)務(wù)信息對象-->業(yè)務(wù)信息模型(xml的描述--實際上是DBMS邏輯數(shù)據(jù)模型)。本來從業(yè)務(wù)對象一下到了表關(guān)系就很大的問題,維護(hù)開發(fā)人員必須對相應(yīng)的數(shù)據(jù)模型有必須了解后才能維護(hù)。維護(hù)的風(fēng)險和成本都增加了。
          第二,它回到以前的的數(shù)據(jù)庫時代,如果不使用它的HSQL的話就完全否定了DBMS 的功能的時候是一個從業(yè)務(wù)代碼抽象到數(shù)據(jù)對象的過渡(他隱藏了數(shù)據(jù)層面的業(yè)務(wù)抽象實現(xiàn)),這樣的做法并不是說不好但是必須是你隱藏的如果能100%的滿足和實現(xiàn)倒也是一個不錯節(jié)省關(guān)注了一個層面,但是實踐證明并非事事如愿的,恰恰是很多時候存在了這個DB層面業(yè)務(wù)對象(SQL)有了更合理的過渡。然而學(xué)習(xí)HSQL又是一種成本。我覺得SQL是DBMS提供出來一種面向?qū)ο蟪橄笳Z言(準(zhǔn)確的說應(yīng)該是業(yè)務(wù)抽象語言)
          第三,性能,如果不使用HSQL的話,性能在維護(hù)負(fù)責(zé)的多表的時候是困難和性能是低下的。
          我覺得它和ibatis的比較,ibatis更像企業(yè)級東西。我blog上有我關(guān)于hibernate和ibatis的比較文章:http://recher.blogdriver.com/recher/1079673.html

          strangecat2005

          發(fā)表文章: 8
          注冊時間: 2006年07月23日 07:57

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年08月04日 13:21 回復(fù)
          這兩天也在繼續(xù)琢磨這個問題,思考出發(fā)點首先是懷疑:
          是我自己沒有學(xué)明白hibernate?還是hibernate本身有問題?

          首先說自己的確對hibernate所知有限,畢竟一直沒敢用它做大型項目,而只是玩了幾個小例子程序。

          但是有一點本質(zhì)性的懷疑:
          如果hibernate的引入真的能完全屏蔽數(shù)據(jù)庫層,讓開發(fā)人員完全從OO角度來構(gòu)建應(yīng)用,那么HQL拿來做什么用?

          HQL是一個query language,和SQL層面類似。HQL引入進(jìn)hibernate后,其實反而證明數(shù)據(jù)庫層的東西是不能被完全屏蔽掉的!

          recher

          發(fā)表文章: 25
          注冊時間: 2004年02月10日 14:06

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年08月04日 14:53 回復(fù)
          所以我說hibernate就是一個技術(shù)狂給我們展現(xiàn)了一個例子:因為沒有合理定位,沒有把握住架構(gòu)切入點,雖然有高超的技術(shù),弄出來的東西反而是哭笑不得的東西(說他不好嘛,他在技術(shù)實現(xiàn)上的確有很多值得我我們學(xué)習(xí),說它好嘛但企業(yè)級應(yīng)用上又有一些對系統(tǒng)生命周期有害的東西)。我覺得它根本沒有從O/R mapping在整個體系中正確定位(沒有系統(tǒng)思考問題).還有我以前接觸的項目有中型項目運(yùn)用了hibernate,后果是大力理解和觀看維護(hù)關(guān)系xml---也是一個很大的風(fēng)險和成本。

          totempole

          發(fā)表文章: 7
          注冊時間: 2006年09月11日 11:51

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年09月11日 11:58 回復(fù)
          HQL是object-oriented query language. Query是針對Domain object model的. 與你的relational model in DB毫無關(guān)系.
          另外, 數(shù)據(jù)庫的形式有許多種, relational, object-oriented, XML-native,berkeley database. 沒有必要局限自己在relational db的框架之中.

          strangecat2005

          發(fā)表文章: 8
          注冊時間: 2006年07月23日 07:57

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年09月15日 15:06 回復(fù)
          "HQL是object-oriented query language. Query是針對Domain object model的. 與你的relational model in DB毫無關(guān)系.
          另外, 數(shù)據(jù)庫的形式有許多種, relational, object-oriented, XML-native,berkeley database. 沒有必要局限自己在relational db的框架之中."

          Hibernate是ORM,跟“數(shù)據(jù)庫的形式有許多種”中其他形式的數(shù)據(jù)庫沒啥關(guān)系吧。

          HQL名義上是面對對象,實際使用中感覺就是把數(shù)據(jù)庫里面的列名換成了對象的property名,其他在概念上有什么區(qū)別嗎?

          totempole

          發(fā)表文章: 7
          注冊時間: 2006年09月11日 11:51

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年09月16日 11:01 回復(fù)
          使用DAO layer的目的是要分離出Data Access Code, 建立的Domain Object Model與database的類型沒有關(guān)系. 對于你的Business Tier和Presentation Tier, database的類型是完全屏蔽的.

          Domain object model in Java program與Relational model in DB可以相差很大. 你對于O/R Mapping的理解還有待提高.

          banq

          發(fā)表文章: 7538
          注冊時間: 2002年08月03日 17:08

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年09月18日 17:47 回復(fù)
          相關(guān)帖子:

          討論如何通過Hibernate提高訪問數(shù)據(jù)庫的速度
          http://www.jdon.com/jive/thread.jsp?forum=16&thread=28484

          strangecat2005

          發(fā)表文章: 8
          注冊時間: 2006年07月23日 07:57

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年09月18日 21:27 回復(fù)
          "使用DAO layer的目的是要分離出Data Access Code, 建立的Domain Object Model與database的類型沒有關(guān)系. 對于你的Business Tier和Presentation Tier, database的類型是完全屏蔽的.

          Domain object model in Java program與Relational model in DB可以相差很大. 你對于O/R Mapping的理解還有待提高. "

          像其他很多模式一樣,DAO也面臨很多爭議,到今天也非業(yè)界公認(rèn)的best practice.

          O/R Mapping及其代表hibernate更不一定非要和DAO扯上關(guān)系。使用O/R Mapping完全可以不使用DAO模式。

          O/R Mapping本身就是為了彌補(bǔ)OO和RDB之間的語義差距,做到數(shù)據(jù)庫層對OO層業(yè)務(wù)邏輯的屏蔽。最理想的O/R Mapping應(yīng)該是在RDB上,對OO各種方法論完全沒有影響。顯然,很遺憾,Hibernate沒能做到這一點。

          大家一起提高吧。

          recher

          發(fā)表文章: 25
          注冊時間: 2004年02月10日 14:06

          Re: 總覺得Hibernate影響設(shè)計思路 發(fā)表: 2006年09月21日 14:45 回復(fù)
          HSQL其實應(yīng)該是內(nèi)存數(shù)據(jù)庫HSQLDB的一個部分.其實hibernate 的tale關(guān)系和過濾等操作都是經(jīng)過內(nèi)存來匹配的(JVM中),不符合宏觀的三層架構(gòu)體系。

          posted on 2007-04-03 00:02 imcb 閱讀(562) 評論(0)  編輯  收藏 所屬分類: 技術(shù)討論


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 开江县| 焉耆| 常州市| 安龙县| 桃园县| 甘肃省| 梅河口市| 布尔津县| 临西县| 雅安市| 延川县| 康马县| 香港| 长沙县| 略阳县| 海原县| 克拉玛依市| 寿光市| 惠东县| 清涧县| 简阳市| 渑池县| 新沂市| 玛纳斯县| 辰溪县| 嵊泗县| 山阳县| 乾安县| 贞丰县| 临邑县| 邢台县| 信丰县| 武强县| 建始县| 隆尧县| 神农架林区| 上思县| 望谟县| 峨边| 靖安县| 浦东新区|