領域邏輯組織能夠分爲三種主要的模式:事務腳本(Transaction Script)、領域模型(Domain Model)和表模塊(Table Module)java
咱們用得最多就是事務腳本方式(像微軟的Petshop4.0,不少國內的三層結構代碼生成工具生成的系統,並且這種方式不少公司,不少企業級的項目都在用,還有一些框架引導你用這種方式實現)。這種方式最大的特色就是:簡單實用。程序員
爲何叫事務腳本(Transaction scripts)呢?也就是實現一個功能,就直接寫一個過程(方法),系統的業務就是分散在一個個這樣的過程裏,像早期用ASP作的大部分系統,一些使用存儲過程系統等,尤爲是使用存儲過程系統,全部業務邏輯都寫在存儲過程裏,很明顯的事務腳本實現方式。想想,咱們在業務層實現一個業務時,通常就是這麼作的,要實現一個什麼功能,在腦子裏想想,而後找到那個對應的類,而後再定義一個方法,加上一堆參數。就開始寫這個方法的實現代碼,要是邏輯複雜點,這方法裏一堆ifesle,是否是?若是邏輯不復雜,這種實現到沒什麼問題,也很方便的。並且,有時候,發現一個類裏好多方法,並且大部分是public的。有時候仔細看看,這個類已經再也不是按面向對象方式來實現,雖然你用的是OO語言(java,C#,Ruby等),也用了類,接口,繼承、多態等技術手段,可是你是否發現系統中對象之間的協做是多麼難,甚至你都以爲系統都不存或不多有幾個對象協做完成一件事情的,有時你會迷惑不少業務層的類是否應該直接定義成靜態類就能夠了,根本不須要實例化成一個對象。你還發現,有些方法(功能職責)根本不屬於這個類或對象的。這樣一來一去,類的職責亂了,方法多了,代碼也沒重構,愈來愈亂,最後頭都大了。因此這就是事務腳本的特色,業務不復雜的系統用這樣方式很方便,對技術人員要求也不是很高,由於它的實現思惟仍是按過程方式,大部分程序員都習慣性這樣,可是一旦業務變化複雜,系統日益不斷的變化,這種方式就變得不堪重負了。數據庫
領域模型(Domain Model),你也可稱它爲業務模型,這種方式是現今在國內外不少大師級人物提倡的實現方式。這種方式最大的好處,它採用是面向對象方式來分析與設計業務邏輯,不少經驗不足的人就會反問,難道我用事務腳本方式就沒有用面向對象的方式還分析與設計,我係統裏面可全是類、繼承,接口等,那我請問你,你每一個類職責單一(SRP)麼?或者說你把每一個類的職責分配好了沒有,就像你會用C#、java、Ruby了,那爲什麼還會有《設計模式》呢?我想不少人都會沉默一下,其實要把職責分清楚是一件不容易的事,但也不是不可能,這須要豐富面向對象分析與設計及程序設計的經驗(不少人以爲不需太多編碼經驗,我我的是很反對的,由於只有對程序設計語言也很熟悉,才直正設計出優秀系統,特別是每種語言在不一樣平臺、框架仍是有細微的差異的),還要準確理解與把握系統的業務需求,再通過不斷迭代,精化才最終得出一個比穩定的業務模型。引伸《重構》的一句話:「任何傻瓜都能寫出計算機能夠理解的代碼,惟有寫出人能容易理解的代碼纔是優秀的程序員」 [Fowler 2002]。那是否是:任何瞭解OO語言的人都會使用類、接口、繼承等特性寫代碼,惟有能寫出職責分明,結構清晰的代碼纔是優秀的面向對象程序員呢?設計模式
「領域模型實現方式,再也不是由一個過程來控制用戶某一動做的邏輯,而是由每個對象都承擔一部分相關邏輯」[Fowler PoEAA,2003]。也就是說實現一個業務,是相關領域對象的一系列協做與交互的結果,再也不像事務腳本那樣直接在一個過程當中。這比如一我的要完成一個動做都是人體各個器官相互合做協調來完成的,何時你見過一個動做,如吃飯,我只要口張開就能夠了。緩存
所以,領域模型實現方式,它通常會先進行業務建模,有時候把業務模型也稱之爲概念模型,咱們在關係數據庫理論裏有E-R模型,因此有些人也稱之爲實體模型。其實,業務,概念模型與實體模型仍是有區別的業務模型實際上是現實問題域進行分析或抽象,這與實體差很少。可是業務模型最終要是用OO方式去試,實體模型要映射成關係模型。所以,業務模型在後期迭代與精化時,不得不採用一些OO手段,如對象職責(Responsibility),角色(Role),協做(Collaboration)等。並且實體模型則要考慮關係映射,查詢優化,數據冗餘的問題。若是你用面向對象方式來實現系統,業務層實現方式採用領域模型方式來實現是最好的,由於他直接與OO語言映射,思惟方式與實現方式統一,因此他能夠解決很複雜的業務系統,並且還能夠獲得很好擴展性,維護性與複用性。安全
我能夠具體說明:例如interactiong項目,那個消息發送策略,架構
以前的實現方式是寫了三個方法(SendMail,SendMSM,SendSMS)在一個類裏,這一看,顯然的事務腳本實現方式,根本沒有去抽象與分析當前的領域邏輯,沒有用OO方式去分析與設計當前問題,若是那天還要實現一個發送彩信或者去掉髮送手機短信的功能,那還修改原來的類,這顯示違背對擴展開放對修改關閉的原則(OCP)。這地方明顯就是一個策略模式。還有,像發送者,與接收者,消息這些對象都是能夠具備行爲,由於領域模型是合併了數據與行爲的對象模型。像Petshop的model層,就是一個貧血模型,一個實體對象沒有任何行爲(方法,操做)。現實中確實能夠有一個對象沒有行爲,可是那確定是少數。通常來講,一個對象確定有數據與行爲。框架
只有行爲沒有數據類,就叫無狀態類(stateless class)less
只有數據沒有行爲,通常用於DTO(數據傳輸對象[Data Transfer Object],這在遠程調用與分佈式調用中常見的一種設計模式)分佈式
所以,像這些發送者,接收者,消息這些類是應該具備行爲的,像消息解析器,發送器,這些應該是服務類。因此基於領域模型的系統通常系統分紅:表現層(Presentation,應用程序層(Application),領域層(Domain),基礎結構層(Infrastructure)。應用程序層其實比較弱,有時候也能夠叫作服務外觀(Service Facade),有時候能夠不須要這一層;領域層,就是業務邏輯層,它包括領域對象與領域業務的一些實現,還資源庫(Repository)對象,資源庫至關於數據訪問對象(DAO),主要用於數據訪問,增、刪、改、查(CRUD)等;基礎結構層,能夠包括在不少,數據持久化(Data Persistence)、ORM、安全機制(Security)、數據驗證(Data Validation)、異常處理(Exception Handle)、日誌跟蹤(Tracing),緩存機制(Caching)、IoC、AOP等,不少模切(Cross Cutting)組件均可以在這層提供。這種劃分,是一種經典的領域驅動設計劃分,不必定嚴格按此方式。
表模塊(Table Module),我我的認爲表模塊應該不算是一種業務邏輯實現方式,可是根據Martin Fowler 《PoEAA》一書,把其歸類到領域邏輯模式中,它是處理某一數據庫(其實只能是關係型數據庫)中表與視圖全部行的業務邏輯的一個實例。由於表模塊其實就一個數據集合(如:ado的RecordSet,ado.net的DataSet中的DataTable或類型化DataSet等之類),它能夠當作是一個數據容器,由於他用一個類(如Product)表示數據庫中對應表全部數據及行爲,咱們知道面向對象模型與關係模型存在差別,一般一個類與一個實體在概念上相對應,也就是一個類對應一個表,一個類的實例,即對象對應表中某一行記錄。類與表都是抽象的,集合的概念,像關係數據庫中表就一個二維(行、列)的集合,而表模塊用一個類直接表示表中全部數據及行爲,因此這個類能夠不須要實例化,它就至關於一個表(如.net 的DataTable),這樣全部業務操做都直接用表模塊方式進行,從這一律念上來講,它也能夠當作是業務邏輯的一種實現方式,其實你們確定能夠得出,這種方式在本質上仍是採用事務腳本方式來實現業務邏輯,只是事務腳本方式,常常要求處理一個業務邏輯(如:查找指定ID的Product)就須要用SQL語句從數據庫中獲取數據,而這種方式先把數據庫的全部行加載到表模塊(如:DataTable)中,以後處理全部業務都直接與表模塊有關(如:查找指定ID的行,CRUD之類的操做),這正是表模塊與事務腳本的細微區別以後。
以上幾種業務邏輯實現方式在如今企業級應用系統中都比較常見,其實歸根到底也就是兩種方式:過程化(事務腳本、表模塊)與面向對象(領域模型),這以正好體現兩種分析與設計問題方法,面向過程方法論與面向對象方法論。至於用那種方式比較好,這沒有絕對的答案,仍是那話老話:軟件開發中不變是變化;沒有最好的,只有最合適的。可是若是你是一個面向對象的忠實粉絲,那麼在不少狀況,你的第一選擇確定是領域模型,即使是業務邏輯簡單的系統,你也會選擇領域模型。
實現方式 |
優勢 |
缺點 |
備註 |
事務腳本 |
|
|
像Petshop4.0、國內不少三層架構代碼生成工具生成的系統以及現今國內絕大部分企業級系統(本人估計)都採用這種方式 |
領域模型 |
1. 採面向對象方法直接對系統的問題域進行分析或建模,領域模型直觀地反映現實世界,可以更好用面嚮對象語言模型轉換,是一種純OO模型 2. 可以解決很複雜的業務邏輯 3. 能夠有效地利用面向對象的特性(抽象,封裝,繼承、多態等)與相關技術(如設計模式,重構等),以提升系統的可擴展性與複用性。 |
|
如今不少企業級應用項目開始採用此方式,這主要得益於ORM框架不斷成熟,以及模式運動,同時一些設計原則也比較好解決相應問題。 請參看參考書目的: 十一、1三、1六、六、二、5
|
表模塊 |
1. 適合於系統業務較直觀,CRUD操做比較集中 2. 若是支持平臺中有比較好工具集支持(如:Ado.Net,數據控件之類),開發速度快,效率高 |
1.當業務並不是CRUD集中型操做,特別是領域模型和數據庫表模型差別較大時,難度很是大,所以不適合業務複雜的系統 |
在Microsoft .Net平臺有不少工具集支持,有時候你甚至不需寫一行代碼就能夠實現CRUD操做 |