<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 水煮三國 閱讀(497) 評論(0)  編輯  收藏 所屬分類: J2EEHibernate
    <2006年10月>
    24252627282930
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    常用鏈接

    留言簿(4)

    隨筆分類(85)

    隨筆檔案(89)

    文章分類(14)

    文章檔案(42)

    收藏夾(37)

    java

    oracle

    Sybase

    搜索

    •  

    積分與排名

    • 積分 - 210731
    • 排名 - 266

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 四虎国产精品免费久久| 久久久久久久99精品免费| 91在线视频免费播放| 在线观看亚洲一区二区| 99re在线免费视频| 亚洲成人黄色在线| 免费H网站在线观看的| 亚洲一级片在线播放| 成年私人影院免费视频网站| 亚洲综合在线一区二区三区| 成年女人永久免费观看片| 国产亚洲精品美女久久久久| 亚洲精品国产成人影院| 国产精品福利片免费看| 久久久亚洲欧洲日产国码农村| 免费播放一区二区三区| 亚洲娇小性xxxx| 国产精品国产免费无码专区不卡 | 欧美色欧美亚洲另类二区| 香蕉视频在线观看免费国产婷婷 | 无码 免费 国产在线观看91| 在线观看国产区亚洲一区成人| 免费91麻豆精品国产自产在线观看 | 国产精品成人免费观看| 久久久久亚洲av无码专区 | 久久久久久毛片免费看| 久久国产精品亚洲一区二区| 日本免费网站视频www区| 小说专区亚洲春色校园| 猫咪www免费人成网站| 一本久久a久久精品亚洲| 57pao国产成视频免费播放| 伊人久久五月丁香综合中文亚洲 | 久久精品国产亚洲AV大全| 成年人免费网站在线观看| 欧洲乱码伦视频免费国产| 4444亚洲国产成人精品| 免费看小12萝裸体视频国产| 久久久国产精品福利免费| 亚洲日韩国产一区二区三区在线| 国产无人区码卡二卡三卡免费 |