<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    我愛oo,我愛java

    交流blog QQ:421057986 oofrank@donews

    2006年1月23日 #

    DAO-持久層-領(lǐng)域?qū)ο?貧血模型

    原文


    關(guān)于"貧血模型"的討論幾乎沒有停止過,在openfans.org的開發(fā)過程中,我們也討論了很久,我覺的有很多東西應(yīng)該記下來:
    明確一下意思先:
    DAO:數(shù)據(jù)操作對(duì)象,會(huì)操作數(shù)據(jù)庫
    持久層:能提供對(duì)象持久化服務(wù)的一系列組件或服務(wù)
    領(lǐng)域?qū)ο?描述領(lǐng)域模型的對(duì)象,是通過業(yè)務(wù)分析進(jìn)行系統(tǒng)建模的產(chǎn)物
    貧 血模型:就是domain object只有屬性的getter/setter方法的純數(shù)據(jù)類,所有的業(yè)務(wù)邏輯完全由一個(gè)所謂的Manager來完成(又稱 TransactionScript),這種模型下的domain object被Martin Fowler稱之為“貧血的domain object”
    常見的類基本結(jié)構(gòu)如下:
    一個(gè)業(yè)務(wù)數(shù)據(jù)類叫做Item,
    一個(gè)DAO接口類叫做ItemDao
    一個(gè)DAO接口實(shí)現(xiàn)類叫做ItemDaoHibernateImpl
    一個(gè)業(yè)務(wù)邏輯類叫做ItemManager(或者叫做ItemService).

    觀察上面的幾個(gè)類很容易發(fā)現(xiàn)問題:
    1:Item和ItemManager實(shí)際是操作與數(shù)據(jù)的關(guān)系,實(shí)際完成的就是經(jīng)典OO中的一個(gè)對(duì)象的能力;
    2:當(dāng)有許多Item時(shí) 類組變得很龐大,產(chǎn)生很多 xxxDao xxxImpl xxxManager 其中包含大量重復(fù)代碼;
    按<<重構(gòu)>>的觀點(diǎn),上述代碼存在以下臭味:
    1:重復(fù)的代碼?? xxxDao xxxImpl xxxManager(通常)
    2:霰彈式修改,一個(gè)變化影響多個(gè)類,類之間不夠高內(nèi)聚 item變化-->Dao,Impl,Manager均要變動(dòng)
    3:依戀情結(jié),兩個(gè)類之間互相作用過多 item<->Manager
    4:平行繼承體系,當(dāng)增加一個(gè)新類時(shí)總是要增加另一個(gè)類
    5:夸夸其談未來性,在沒有任何暗示的情況下考慮擴(kuò)展? Dao,實(shí)際HibernateImpl可能n年內(nèi)是唯一的Dao實(shí)現(xiàn)
    6:純稚的數(shù)據(jù)類,只有數(shù)據(jù)的類? item

    我覺的 貧血模型 是系統(tǒng)分析設(shè)計(jì)方向性錯(cuò)誤的產(chǎn)物:
    1:沒有進(jìn)行領(lǐng)域建模---以數(shù)據(jù)表結(jié)構(gòu)為中心,而不是業(yè)務(wù)模型為中心的思考方式,使設(shè)計(jì)人員選擇Item為考慮問題的出發(fā)點(diǎn)
    2:將DAO與持久層混淆---我們需要的一種持久化服務(wù),DAO緊緊是提供數(shù)據(jù)操作能力而已,Hibernate是一種高級(jí)的服務(wù)(他已經(jīng)包含了DAO,而不是相反),已經(jīng)完成了所有的持久層服務(wù).
    3:過于強(qiáng)調(diào)低偶合---將一些本來一些提供單一職責(zé)的內(nèi)容分散在多個(gè)單元中使 客戶端 依賴更多的接口,而忘記了高內(nèi)聚原則.
    4:Spring的能力限制---由于Spring現(xiàn)階段不支持對(duì)于領(lǐng)域模型的服務(wù)注入,使設(shè)計(jì)人員將操作和數(shù)據(jù)分開,并將領(lǐng)域變?yōu)镈ataOnly的.
    ? (Spring2.0將在很大程度上解決這個(gè)問題)
    ?
    我認(rèn)為良好的解決方案:
    ? 首先領(lǐng)域建模,建立領(lǐng)域模型-->合并前面所說的Item和ItemManager成為 domainItem;對(duì)于數(shù)據(jù)庫服務(wù),
    ? 1:如果考慮領(lǐng)域?qū)影瑪?shù)據(jù)操作能力,則建立DAO并選擇其它好的DAO方案比如IBATIS或Hibernate之類的組件;
    ? 2:如果考慮將數(shù)據(jù)庫(或其他存儲(chǔ)界質(zhì))存儲(chǔ)考慮在領(lǐng)域之外成為持久層,
    ? ??? a:則或者對(duì)持久層框架同時(shí)建模,同時(shí)選擇合適的組件為持久層服務(wù)提供存儲(chǔ)服務(wù)(包括DAO--亦可選擇IBATIS/Hibernate組件),
    ? ??? b:或者直接使用Hibernate/JDO等框架實(shí)現(xiàn)持久化服務(wù),領(lǐng)域?qū)又苯邮褂贸志脤臃?wù),對(duì)領(lǐng)域?qū)ο筮M(jìn)行持久化和反持久化(從持久層獲取以持久化的對(duì)象).
    ?
    其他:
    ? 實(shí)際上,作為一種解決方案,所謂"貧血模型"的具體使用,并不會(huì)有太大的問題,尤其是使用一些代碼生成工具或已經(jīng)做好相應(yīng)的基本框架時(shí),很多軟件的核心價(jià) 值都在于對(duì)客戶提供的服務(wù),而其內(nèi)部則成為黑盒,我們只要合理的解決業(yè)務(wù)問題,就是"王道"了,對(duì)于代碼的臭味,可以慢慢重構(gòu)--這也需要成本呀.?
    ?
    再其他:
    有人說,我們的業(yè)務(wù)就是CRUD,領(lǐng)域模型只有數(shù)據(jù)類就足夠了.我覺的這是搞錯(cuò)了方向------只有CRUD時(shí),只有處理CRUD的那些類才有必要進(jìn)行建模(他們才是領(lǐng)域模型),而所謂的User\Item等數(shù)據(jù)類則完全沒有必要進(jìn)行建模,更不要談?lì)I(lǐng)域了.

    貧血之外:
    實(shí)際上,軟件\OO方法的外延大的很,更多問題與數(shù)據(jù)庫存儲(chǔ)無關(guān)(但也有貧血問題),所以建模才是根本,OO方法的原則才是我們必須掌握的.

    posted @ 2006-04-10 22:21 兼聽則明 閱讀(6560) | 評(píng)論 (4)編輯 收藏

    SQLServer的一個(gè)bug

    SQLServer一個(gè)bug終于被我碰上了

    我有一個(gè)表使用字符類型存儲(chǔ)數(shù)字值,想進(jìn)行匯總計(jì)算:

    sum(case when isnumeric(FieldName)=0 then 0 else cast  (FieldName as numeric) end)
    簡(jiǎn)單試了一下沒有問題,可是今天數(shù)據(jù)中有一個(gè) ’2.1234567E7‘  isnumeric返回1 cast 返回錯(cuò)誤

    嗚嗚。。。。
    怎么辦......

    posted @ 2006-02-05 22:37 兼聽則明 閱讀(350) | 評(píng)論 (0)編輯 收藏

    使用Quartz要注意的一個(gè)問題


    當(dāng)設(shè)置一個(gè)Schedule的startDate早于 new Date(),并且調(diào)度周期又觸發(fā)于startDate和new Date()之間時(shí),就會(huì)立即觸發(fā)當(dāng)前job。簡(jiǎn)單的解決方式是將startDate設(shè)為new Date().

    posted @ 2006-01-23 00:52 兼聽則明 閱讀(435) | 評(píng)論 (0)編輯 收藏

    主站蜘蛛池模板: 久久精品国产亚洲αv忘忧草| 性色av免费观看| 亚洲色欲色欲www在线播放| 亚洲黄色网址大全| 蜜芽亚洲av无码精品色午夜| 亚洲国产一区二区a毛片| 亚洲国产人成在线观看69网站| 草久免费在线观看网站| 久久久久亚洲国产AV麻豆| 无码亚洲成a人在线观看| 妞干网免费观看视频| 亚洲一卡2卡3卡4卡乱码 在线 | 一个人免费视频观看在线www| 国产一级淫片a免费播放口之 | 亚洲人片在线观看天堂无码| 亚洲人成电影在线观看网| 亚洲特级aaaaaa毛片| 亚洲kkk4444在线观看| 亚洲AV综合永久无码精品天堂| 亚洲国产日产无码精品| 国产婷婷成人久久Av免费高清 | 亚洲高清国产拍精品青青草原 | 国产成人精品免费视频动漫 | 亚欧免费一级毛片| 一级毛片免费播放| 久久亚洲AV午夜福利精品一区| 亚洲美女色在线欧洲美女| 日韩精品极品视频在线观看免费| 久久国产精品一区免费下载| 37pao成人国产永久免费视频| 四虎影视在线永久免费观看| 亚洲AV成人一区二区三区观看| 国产免费AV片在线播放唯爱网| 成人免费视频一区二区三区| 亚洲中久无码不卡永久在线观看| 在线亚洲精品自拍| 亚洲AV成人影视在线观看| 女性无套免费网站在线看| 苍井空亚洲精品AA片在线播放 | 成人福利在线观看免费视频| 久久99亚洲综合精品首页|