<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都需要提供一個對應的封裝方法,這不但是非??菰锏模彩橇钊烁杏X非常不好的。

    第二類: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)  編輯  收藏 所屬分類: J2EE 、Hibernate
    <2006年10月>
    24252627282930
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    常用鏈接

    留言簿(4)

    隨筆分類(85)

    隨筆檔案(89)

    文章分類(14)

    文章檔案(42)

    收藏夾(37)

    java

    oracle

    Sybase

    搜索

    •  

    積分與排名

    • 積分 - 210750
    • 排名 - 266

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 婷婷久久久亚洲欧洲日产国码AV| 浮力影院第一页小视频国产在线观看免费 | 一进一出60分钟免费视频| 国产无遮挡又黄又爽免费网站| 人妻无码久久一区二区三区免费| 永久免费毛片手机版在线看| 456亚洲人成影院在线观| 拍拍拍无挡视频免费观看1000| 67194熟妇在线永久免费观看| 亚洲欧洲国产成人综合在线观看| 亚洲国产精品久久久久秋霞影院| 亚洲人xxx日本人18| 国产va精品免费观看| 亚洲AV综合色区无码一区| 亚洲一级毛片免费看| 中文字幕乱码系列免费| 亚洲欭美日韩颜射在线二| 精品亚洲成A人在线观看青青| 18pao国产成视频永久免费| 亚洲伊人成无码综合网| 久久精品国产亚洲AV电影网| 国产精品无码一区二区三区免费 | 男女猛烈无遮掩视频免费软件| 男女做羞羞的事视频免费观看无遮挡| 国产亚洲日韩在线三区| 国产成人精品亚洲一区| 日韩精品无码区免费专区| 亚洲avav天堂av在线不卡| 精品国产污污免费网站aⅴ| 亚洲成AV人片在线观看WWW| 亚洲精品国产日韩无码AV永久免费网| 卡1卡2卡3卡4卡5免费视频| 亚洲一区二区三区不卡在线播放 | gogo免费在线观看| 精品亚洲综合在线第一区| h视频在线观看免费网站| 极品色天使在线婷婷天堂亚洲| 国产成人亚洲精品狼色在线| 最近中文字幕免费mv在线视频| 久久精品亚洲中文字幕无码网站 | 国内自产拍自a免费毛片|