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

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

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

    posts - 89,  comments - 98,  trackbacks - 0

    既然大家都統一了觀點,那么就有了一個很好的討論問題的基礎了。Martin Fowler的Domain Model,或者說我們的第二種模型難道是完美無缺的嗎?當然不是,接下來我就要分析一下它的不足,以及可能的解決辦法,而這些都來源于我個人的實踐探索。

    在第二種模型中,我們可以清楚的把這4個類分為三層:

    1、實體類層,即Item,帶有domain logic的domain object
    2、DAO層,即ItemDao和ItemDaoHibernateImpl,抽象持久化操作的接口和實現類
    3、業務邏輯層,即ItemManager,接受容器事務控制,向Web層提供統一的服務調用

    在這三層中我們大家可以看到,domain object和DAO都是非常穩定的層,其實原因也很簡單,因為domain object是映射數據庫字段的,數據庫字段不會頻繁變動,所以domain object也相對穩定,而面向數據庫持久化編程的DAO層也不過就是CRUD而已,不會有更多的花樣,所以也很穩定。

    問題就在于這個充當business workflow facade的業務邏輯對象,它的變動是相當頻繁的。業務邏輯對象通常都是無狀態的、受事務控制的、Singleton類,我們可以考察一下業務邏輯對象都有哪幾類業務邏輯方法:

    第一類:DAO接口方法的代理,就是上面例子中的loadItemById方法和findAll方法。

    ItemManager之所以要代理這種類,目的有兩個:向Web層提供統一的服務調用入口點和給持久化方法增加事務控制功能。這兩點都很容易理解,你不能既給Web層程序員提供xxxManager,也給他提供xxxDao,所以你需要用xxxManager封裝xxxDao,在這里,充當了一個簡單代理功能;而事務控制也是持久化方法必須的,事務可能需要跨越多個DAO方法調用,所以必須放在業務邏輯層,而不能放在DAO層。

    但是必須看到,對于一個典型的web應用來說,絕大多數的業務邏輯都是簡單的CRUD邏輯,所以這種情況下,針對每個DAO方法,xxxManager都需要提供一個對應的封裝方法,這不但是非??菰锏?,也是令人感覺非常不好的。

    第二類:domain logic的方法代理。就是上面例子中placeBid方法。雖然Item已經有了placeBid方法,但是ItemManager仍然需要封裝一下Item的placeBid,然后再提供一個簡單封裝之后的代理方法。

    這和第一種情況類似,其原因也一樣,也是為了給Web層提供一個統一的服務調用入口點和給隱式的持久化動作提供事務控制。

    同樣,和第一種情況一樣,針對每個domain logic方法,xxxManager都需要提供一個對應的封裝方法,同樣是枯燥的,令人不爽的。

    第三類:需要多個domain object和DAO參與協作的business workflow。這種情況是業務邏輯對象真正應該完成的職責。

    在這個簡單的例子中,沒有涉及到這種情況,不過大家都可以想像的出來這種應用場景,因此不必舉例說明了。

    通過上面的分析可以看出,只有第三類業務邏輯方法才是業務邏輯對象真正應該承擔的職責,而前兩類業務邏輯方法都是“無奈之舉”,不得不為之的事情,不但枯燥,而且令人沮喪。

    分析完了業務邏輯對象,我們再回頭看一下domain object,我們要仔細考察一下domain logic的話,會發現domain logic也分為兩類:

    第一類:需要持久層框架隱式的實現透明持久化的domain logic,例如Item的placeBid方法中的這一句:

    代碼
    						this
    						.
    						getBids
    						().
    						add
    						(
    						newBid
    						);
    				

    上面已經著重提到,雖然這僅僅只是一個Java集合的添加新元素的操作,但是實際上通過事務的控制,會潛在的觸發兩條SQL:一條是insert一條記錄到bid表,一條是更新item表相應的記錄。如果我們讓Item脫離Hibernate進行單元測試,它就是一個單純的Java集合操作,如果我們把他加入到Hibernate框架中,他就會潛在的觸發兩條SQL,這就是隱式的依賴于持久化的domain logic
    特別請注意的一點是:在沒有Hibernate/JDO這類可以實現“透明的持久化”工具出現之前,這類domain logic是無法實現的。

    對于這一類domain logic,業務邏輯對象必須提供相應的封裝方法,以實現事務控制。

    第二類:完全不依賴持久化的domain logic,例如readonly例子中的Topic,如下:

    java代碼
    class Topic{
    booleanisAllowReply(){
    CalendardueDate=Calendar.getInstance();
    dueDate.setTime(lastUpdatedTime);
    dueDate.add(Calendar.DATE,forum.timeToLive);

    Datenow=newDate();
    returnnow.after(dueDate.getTime());
    }
    }

    注意這個isAllowReply方法,他和持久化完全不發生一丁點關系。在實際的開發中,我們同樣會遇到很多這種不需要持久化的業務邏輯(主要發生在日期運算、數值運算和枚舉運算方面),這種domain logic不管脫離不脫離所在的框架,它的行為都是一致的。對于這種domain logic,業務邏輯層并不需要提供封裝方法,它可以適用于任何場合。

    posted on 2006-10-19 10:01 水煮三國 閱讀(507) 評論(0)  編輯  收藏 所屬分類: J2EE 、Hibernate
    <2006年10月>
    24252627282930
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    常用鏈接

    留言簿(4)

    隨筆分類(85)

    隨筆檔案(89)

    文章分類(14)

    文章檔案(42)

    收藏夾(37)

    java

    oracle

    Sybase

    搜索

    •  

    積分與排名

    • 積分 - 211659
    • 排名 - 266

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲欧洲日产国码在线观看| 亚洲国产区男人本色在线观看| 亚洲人AV在线无码影院观看| 99久久久国产精品免费牛牛四川 | 亚洲精品视频在线免费| 亚洲男人的天堂www| 曰批免费视频播放在线看片二| 精品久久久久久久免费人妻 | 国产AV无码专区亚洲精品| 国产精品成人69XXX免费视频| 免费亚洲视频在线观看| 风间由美在线亚洲一区| 日韩一级视频免费观看| 亚洲精品宾馆在线精品酒店| 免费观看理论片毛片| 亚洲成AV人片在WWW| www亚洲精品少妇裸乳一区二区| 免费视频成人国产精品网站| 久久久无码精品亚洲日韩软件| 亚洲成人高清在线观看| 亚洲精品视频免费在线观看| 亚洲 暴爽 AV人人爽日日碰| 我想看一级毛片免费的| 国产精品亚洲综合| 亚洲综合国产一区二区三区| 最近中文字幕大全免费版在线| 亚洲精品欧洲精品| 最近中文字幕免费mv视频7| 亚洲码和欧洲码一码二码三码| 国产精品极品美女免费观看| sss在线观看免费高清| 亚洲国产成人高清在线观看 | 三年片在线观看免费观看高清电影| 亚洲成a人片在线看| 国产成人免费ā片在线观看| 含羞草国产亚洲精品岁国产精品 | 91在线视频免费看| 久久久久亚洲av无码专区| 69天堂人成无码麻豆免费视频| 亚洲a∨无码一区二区| 久久精品国产精品亚洲|