海水正藍

          面朝大海,春暖花開
          posts - 145, comments - 29, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          [轉]貧血模型和充血模型

          Posted on 2012-07-26 14:03 小胡子 閱讀(173) 評論(0)  編輯  收藏

          這兩個概念是早些時候Martin Fowler總結出來的兩種常見模型設計類型,沒有說誰好誰不好,為不同的模型類別選擇合適的場景是設計者的工作。沒有工具本身的問題,只有工具使用者的問題。

           

           

          貧血模型是指領域對象里只有get和set方法(POJO),所有的業務邏輯都不包含在內而是放在Business Logic層。

           


           

          優點是系統的層次結構清楚,各層之間單向依賴,Client->(Business Facade)->Business Logic->Data Access Object。可見,領域對象幾乎只作傳輸介質之用,不會影響到層次的劃分。

           

          該模型的缺點是不夠面向對象,領域對象只是作為保存狀態或者傳遞狀態使用,它是沒有生命的,只有數據沒有行為的對象不是真正的對象,在Business Logic里面處理所有的業務邏輯,對于細粒度的邏輯處理,通過增加一層Facade達到門面包裝的效果。

           

          在使用Spring的時候,通常暗示著你使用了貧血模型,我們把Domain類用來單純地存儲數據,Spring管不著這些類的注入和管理,Spring關心的邏輯層(比如單例的被池化了的Business Logic層)可以被設計成singleton的bean。

           

          假使我們這里逆天而行,硬要在Domain類中提供業務邏輯方法,那么我們在使用Spring構造這樣的數據bean的時候就遇到許多麻煩,比如:bean之間的引用,可能引起大范圍的bean之間的嵌套構造器的調用。

           

          貧血模型實施的最大難度在于如何梳理好Business Logic層內部的劃分關系,由于該層會比較龐大,邊界不易控制,內部的各個模塊之間的依賴關系不易管理,可以考慮這樣這樣的實現思路:

          (1)鋪設扁平的原子業務邏輯層,即簡單的CRUD操作(含批量數據操作);

          (2)特定業務清晰的邏輯通過Facade層來組裝原子操作實現。

          (3)給業務邏輯層實施模塊劃分,保持模塊之間的松耦合的關系。

           

          舉例說明:

          原子業務邏輯層(Service)提供了用戶模型的條件查詢方法:

          List<User> queryUser(Condition con)

          Facade層則提供了一種特定的業務場景的分子接口,滿足18歲的中國公民,內部實現調用的正是上述的原子接口:

          List<User> queryAdultChinese()

          Facade、Service層縱向劃分為幾個大的領域包:用戶、內容和產品。

           

           

          充血模型層次結構和上面的差不多,不過大多業務邏輯和持久化放在 Domain Object里面,Business Logic只是簡單封裝部分業務邏輯以及控制事務、權限等,這樣層次結構就變成Client->(Business Facade)->Business Logic->Domain Object->Data Access Object。

           


           

          它的優點是面向對象,Business Logic符合單一職責,不像在貧血模型里面那樣包含所有的業務邏輯太過沉重。

           

          缺點是如何劃分業務邏輯,什么樣的邏輯應該放在Domain Object中,什么樣的業務邏輯應該放在Business Logic中,這是很含糊的。即使劃分好了業務邏輯,由于分散在Business Logic和Domain Object層中,不能更好的分模塊開發。熟悉業務邏輯的開發人員需要滲透到Domain Logic中去,而在Domian Logic又包含了持久化,對于開發者來說這十分混亂。  其次,如果Business Logic要控制事務并且為上層提供一個統一的服務調用入口點,它就必須把在Domain Logic里實現的業務邏輯全部重新包裝一遍,完全屬于重復勞動。

           

          使用RoR開發時, 每一個領域模型對象都可以具備自己的基礎業務方法,通常滿足充血模型的特征。充血模型更加適合較復雜業務邏輯的設計開發。

           

          充血模型的層次和模塊的劃分是一門學問,對開發人員要求亦較高,可以考慮定義這樣的一些規則:

          (1)事務控制不要放在領域模型的對象中實現,可以放在facade中完成。

          (2)領域模型對象中只保留該模型驅動的一般方法,對于業務特征明顯的特異場景方法調用放在facade中完成。

           

           

          萬事都不是絕對的,也有一些看起來不易解決的問題。例如,考慮到性能的需要,我需要一次查詢出滿足某種條件的用戶和某種條件的產品,他們二者之間通過訂購關系關聯起來,可能發現這種情形下,上述的模型層次劃分變得無解了……

           

          怎么辦呢?包括以上種種,歡迎大家討論。


          轉自:

          http://raychase.iteye.com/blog/1328224


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


          網站導航:
           
          主站蜘蛛池模板: 阿坝县| 甘洛县| 喀喇沁旗| 河东区| 富宁县| 科技| 桃园县| 河源市| 神木县| 新疆| 栖霞市| 乌兰察布市| 鲁山县| 那曲县| 梁平县| 启东市| 诏安县| 时尚| 湟源县| 芮城县| 苍南县| 青龙| 腾冲县| 松原市| 绥中县| 合作市| 高州市| 夏河县| 海林市| 铜山县| 中卫市| 湖口县| 木兰县| 华坪县| 清徐县| 大方县| 金川县| 康马县| 白山市| 霍邱县| 济阳县|