[轉]從三層架構邁向領域驅動設計 — 關於領域設計中描述相對簡要及明瞭的一篇文章

本文讀者基本要求:從事信息管理系統開發,略懂GOF設計模式及SOLID設計原則,對三層面向過程機械編碼厭倦,而且不知道出路在何方,若是還掌握代碼壞味和重構手法,那是極好的。前端

1. 三層架構

理論介紹-->實際經驗-->總結反思git

1.1 簡單介紹三層架構

嚴格分層架構模式的特色是上層只能訪問相鄰的下層,其餘層次間的調用都不容許。三層架構就是一種嚴格分層模式,它把職責劃分爲界面展現、業務邏輯、數據訪問三層,還有一個業務實體,前面三層都要依賴它,因此它並不構成一個層。結構如圖1。程序員

三層架構的特色是一種面向過程的編程思想,特色以下:github

a. 業務實體類中基本上只有屬性沒有方法。數據庫

b. 業務邏輯層的類基本上只有方法沒有屬性。編程

c. 將數據表結構映射爲業務實體類是一個慣用作法,以致於有人將其稱之爲「傳統」。這樣的好處是隻須要理解一套模型,可以經過自動化工具從數據表直接生成業務實體,還可以天然而然的經過自動化機制存儲與檢索業務實體。但對於複雜點的業務,這樣作就是絕大部分問題的根源。設計模式

d. 當業務膨脹起來,須要劃分模塊的時候,咱們有個經常使用的變形:提取一個服務層出來,用來組合模塊間的交互,還爲業務邏輯層提供了一個防腐層,能夠把記錄日誌、驗證權限、處理異常等職責分配給服務層。結構如圖2。緩存

上面介紹的就是咱們常說的三層架構,因爲採用了嚴格分層模式,用戶界面層是絕對不能跨過業務邏輯層調用數據訪問層的,同理服務層也是不能調用數據訪問層。可是圖2都有四層了,那它仍是三層嗎?這就須要見仁見智了,通常來講仍是的。其實三層架構還有個更準確的名字----分層貧血領域模型架構,這樣就無論多少層都能歸納了,可是這名字沒有三層那麼朗朗上口。前面名字中的領域模型指的是業務實體,貧血意思業務實體中沒有或不多方法。安全

1.2 實際應用中的三層架構

1.2.1 PetShop。網絡

三層架構比較著名的例子就是PetShop,其技術內容比較豐富,MemberShip,ProfileProvider,各類接口,各類Factory,可替換的數據訪問層,緩存機制,消息隊列等技術,看起來很牛的樣子。但它的領域模型卻比較簡單,連模塊都沒有劃分,只能算個玩具。不少年前,見識還比較少的時候,微軟就是我心中的神,只有微軟提供的技術纔是最正宗的,微軟說的都是對的,沒有用上微軟提供的技術,內心就各類不對勁。後來學習設計模式,知道有個模式癡迷症(若是在編碼中沒有用上模式,內心就各類不對勁),才明白原來本身以前患上了微軟癡迷症。在個人實際工做經歷中,微軟癡迷症患者不在少數。就PetShop而言,微軟只是展現一下他的技術而已,初學者們不明覺厲,盲目地奉它經典,以致於固步自封,不明白軟件開發的路還很長很長,每種技術都有它的適用場景,選擇權永遠都在本身的手上(或在團隊領導的手上)。

 

1.2.2 本人實際工做經歷。

參加工做的前幾年,都在小公司,經歷的都是一我的開發的小項目,有時有個Web前端或美工配合一下,信息系統嘛,主要功能固然就是存儲、檢索、展現數據,業務操做就是CRUD了,業務邏輯最多就是驗證一下業務實體填寫的正確性,數據表的數量也很是有限。那時的我,在三層架構的統治下,作着一個快(枯)樂(燥)的數據搬運工(從數據庫搬到界面或從界面搬到數據庫)。

 

長期重複枯燥的工做會讓人感受前途無亮,窮則思變,結果就是人員的流動。對於短時間小項目來講,人員流動根本不是個事,可是對於長期項目來講,可能就沒那麼簡單了,某些關鍵人物的離職,可能會引發很長期的震盪,接手的人加班、發脾氣絕對是正常的(這視乎接手人員的技術水平),甚至可能使項目停滯不前。

 

終於,我順從心裏的呼喚,離開那個簡單的環境,加入了一個比較複雜的長期項目。和之前同樣,採用三層架構,信息系統項目嘛,CRUD就是基石,項目中絕大部分的工做就是搬運數據。不一樣的是,開發人員有10個以上(人生中第一個團隊開發);數據表超過200個(這是之前不敢想象的)。更加不一樣的是,有些功能,它可能牽涉到了全部的數據表,作這樣一個功能,首先要把全部關聯到的數據表都找出來,理解清楚表與表之間的關係,比較痛苦的是別人寫的代碼你基本用不上,都要本身從頭搞。對於那些平時只是埋頭搞本身一塊功能的人來講,簡直是要命。還有更要命的,不知道何時需求又變動了,而處理這個功能的人離職了。開始,接手的新人兩眼淚汪汪求多給點時間,而領導不理解,之前誰誰不是很快就搞定了嗎?那些站着說話不腰疼的同事說,這功能簡單,這個、這個、還有這個表,那個、那個、還有那個表,這樣再那樣就解決了。我把這種協做方式成爲嘴炮協做,真正的協做應該是代碼層面的。新人無法辯駁通常最後會選擇默默地加班。人員繼續流動,這樣的情形發生屢次以後,領導開始意識到,狀況沒那麼容易了。特別是若是幾個關鍵開發者都離職了,那境況更是難上加難。就算沒有人離職,狀況同樣是愈來愈難,這我在後面的一個項目中有比較深入的體會,可是並非全部人都會把這種難歸結於架構不對或團隊開發水平還有待提高,他們會認爲這是需求的問題或者其餘同事的問題,還有人會認爲這是正常的必然的無解的事情。若是一段時間複雜的功能變動多起來,加班就會成爲常態,若是加班可以搞定,狀況還不算最糟糕。「水很深,水太深,水不知道有多深」開始成爲了團隊的口頭禪。比較幸運的是當時那個項目這樣的功能不算太多。最後有人總結出一句名言:「誰遇到誰倒黴 ,忍忍就過去了」。說到這裏,不少人可能會說,讓全部開發人員的熟讀全部數據表不就好了?實際狀況是,除了關鍵的幾我的,其餘開發人員每每沒有那個願意把有限的生命浪費在閱讀這些下個項目就毫無用處了的數據表上,並且表的數量可能會增加到沒有任何一我的可以總體掌控的程度。並且一個牽涉多個模塊的複雜功能,不能調動相關模塊來協助,反而都得直接與數據庫打交道,其餘模塊的邏輯也須要本身處理,這是單打獨鬥的套路,體現不了團隊的協做與效率;再有就是不能複用那些久經考驗的代碼,致使重複代碼慢慢積累,系統缺陷也比較多。並且由多人接手後,一旦有人理解出了誤差,需求變動致使致命缺陷的概率會很高。

 

雖然項目組的生活氛圍不錯,時不時有經費給同事們出去吃完玩樂一下,可是不能預料何時需求就會提出一些「險惡」的功能,對人的精神也是一種考驗。爲了應付隨時可能出現的各類險惡狀況,我學習掌握了一些重構手法,學會用了UML來分析問題,還在項目中成功地應用了兩個設計模式來解決一個棘手問題。可是在三層架構的大環境下,可以發揮的餘地也是很是有限,有種有技術沒地方用的感受,常有新建一個類不知道該往哪一個層放的狀況。

 

後來,我還在另一個採用三層架構的長期項目裏呆過,狀況與上一個項目基本同樣,除了人員比較上一個項目穩定不少。就三層架構實際遇到的問題,我諮詢了一些項目經理朋友,他們的意見以下:

經理A:代碼是不可能寫成書上介紹那樣規範好維護的。

經理B:需求是不可能穩定下來的,代碼也是不可能穩定下來的。

經理C:項目到了後期代碼亂?難道不都是這樣嗎?

1.3 三層架構的反思

Linus Torvalds :Bad programmers worry about the code. Good programmers worry about data structures and their relationships. (差的程序員糾結代碼怎麼寫,好的程序員糾結數據結構和結構間的關係。)

 

三層架構的最大問題在於:實際應用中人們喜歡把內存模型和數據庫模型保持一致。三層架構的大部分問題都是從這裏衍生出來的。

數據庫模型的粒度若是很小,那麼大量的錶鏈接很快就會讓數據庫跑不動了。

若是數據庫模型的粒度若是很大(這是大部分項目的選擇),代碼的質量(重用性、穩定性、擴展性)就不好。因爲沒有從業務的角度去仔細定義每個對象,每一個人會根據本身的須要創建各類QueryModel或ViewModel,慢慢地類會多到想哭。或若是不創建各類Model,強行重用DataModel的話,那麼接口提供的內容每每絕大部分都不是你想要的。

內存模型與數據庫模型保持一致並不是天生的,這是有不少緣由形成的:

它建模的簡單性讓初學者沒法拒絕,因爲經驗主義,以致於多年之後已經沒有勇氣去擺脫了;

沒有專門論述三層與建模的書籍;

ORM工具誤導,與數據表結構一致內存結構方便創建映射關係;

示範代碼的誤導,錯誤把示範代碼當成產品代碼;

等等......

種種誤導致使不少人工做不少年後依然未能找到正確的路,忽略了一個重要的核心(業務建模)環節(業務模型要與代碼的數據結構保持一致),可是他卻坐上了項目領導的職位,這就是更大的誤導了。以致於讓人產生不管你去到那個公司都是同樣的錯覺(在不少人的經歷中,這的確是事實,包括我本身),但事實不該該是這樣的。

用戶界面,領域模型,數據庫它們應該具備同等的重要位置,領域模型在不少公司都是被忽略的角色。

咱們應該相信:優秀的軟件必定是由優秀的開發者製做的,團隊的協做方式應該在代碼層面,代碼複用能夠下降缺陷和提高效率。而這些都指向你應該離開「傳統」三層架構。

還有一些三層開發人員最終患上了數據庫癡迷症,他堅信程序就應該作個搬運工,其餘的事情都應該交給數據庫來完成,業務邏輯也應該寫進存儲過程裏面去。

2. 三層架構到DDD的轉變過程

優化層次關係-->重構到面向對象設計-->使用DDD相關模式深刻重構

上面講到,三層是「分層貧血領域模型架構」,那麼DDD則可稱爲「分層充血領域模型架構」。從名字上看,它們就有親戚關係,有親戚好辦事,嘿!

三層到DDD的過程大致是這樣的:首先推翻嚴格分層的理念,採用鬆散分層來從新定義服務層(鬆散分層的意思是上層能夠訪問下層,而不僅是相鄰的下層),把調用數據訪問層的職責交給服務層,接着把業務邏輯層移動到與業務實體在一塊兒,再接着融合業務邏輯與業務實體,使之成爲面向對象的設計,而後利用DDD的模式進行更深刻的重構。在DDD技術掌握的還不是那麼紮實的時候,三層技術基本仍然可以繼續使用。

 

2.1 重構到面向對象的設計

因爲目前的服務層職責是很是輕的,甚至有不少空殼的調用,因此平衡一下職責,把調用數據訪問層的職責從業務邏輯層提高到服務層,須要的數據經過參數傳遞給業務邏輯層。這樣,對於那些簡單到無業務邏輯的CRUD就不須要去訪問業務層了,直接調用數據訪問層。

結構如圖3,咱們看到業務邏輯與數據訪問層已經沒有依賴關係了。

而後咱們就能夠把業務邏輯與業務實體移到一塊。

而後把屬於業務實體的邏輯遷移到實體類中。

上面簡單單幾句話和兩張圖就把問題搞定了,可是實際遷移過程當中,風險是很是大的,若是沒有充分掌握重構知識,建議不要在正式產品代碼上嘗試。有些邏輯沒法歸類到任何一個業務實體上的,就讓它留在原地,成爲一個領域服務。有些邏輯連領域服務都沒法歸類的,就讓它留在服務層,在堅持大方向的前提下,細節靈活處理,由於每次重構都可以讓你對將來的路看到更清楚,極可能下一次重構後你就會爲這些流浪邏輯找到合適的家了。全部的建議都只是建議,最終決定權在你的手上,受苦的人始終都是你本身。

一個事實是:掌握的編程思想越多,那麼搬遷起來就越容易,假若編程功底太差,可能根本沒法搬動,不建議初學者進行這些危險的試驗,由於你必定會把事情搞砸的,若是你把事情搞砸了,請自我檢討一下是否是編程思想不太夠用。

上面的過程並不是要你一步到位,你能夠把代碼重構到任何一個時刻,等待後面知識跟上了,再進行下一步的重構。

到目前爲止,代碼仍是那些代碼,只是位置變了而已,因此若是嚴格按照重構手法進行,編譯、運行應該都是沒有問題的。就這樣,在現有生活沒有任何影響的狀況下,你已經爲你的職業生涯打開了另一扇門,不再怕編程技術拼不過那些年輕人了。

實際上,DDD只是讓你從新迴歸到面向對象編程,沒有什麼更加神奇的魔法,固然DDD超越面向對象的地方在於對類的設計提出了更多的指導方法。

 

2.2 使用DDD相關模式進行深刻重構

正式介紹一下DDD的分層架構,固然DDD的架構並不限於分層,如今還有六邊形架構、CQRS、EventSourcing等技術能夠選用,可是不要好高騖遠,先把分層架構掌握好。原版分層結構如圖5,改進版結構如圖4,圖4基本上就是圖3的各個層換了名字,而且UI能夠訪問基礎設施層。而圖4與圖5的區別在於,圖4是基礎設施依賴領域層,圖5是領域層依賴基礎設施層,這兩層的關係倒置了。這樣的倒置會更凸顯領域層的核心地位,也有人認爲這樣已經算是六邊形架構了。

 

2.2.1 DDD各層次職責解析

 

用戶界面層:

原版----負責向用戶展示信息以及解釋用戶命令。

補充---- MVC中V和C都屬於UI層,V展示信息,C解析用戶命令UI像地圖同樣把各個控制器關聯了起來

 

應用層:

原版----很薄的一層,用來協調應用的活動。它不包含業務邏輯。它不保留業務對象的狀態,但它保有應用任務的進度狀態。

補充----協調應用的活動這句話太抽象了,我充實一下它:從數據訪問中獲取領域對象,調用領域對象的方法完成任務,而後再調用數據訪問代碼把領域對象的改變持久化。事務、權限檢查、記錄日誌、處理異常的職責也歸它管。這點和前面三層的服務層的職責實際上是同樣的。

 

領域層:

原版----本層包含關於領域的信息。這是業務軟件的核心所在。在這裏保留業務對象的狀態,對業務對象和它們狀態的持久化被委託給了基礎設施層。

補充----業務對象的持久化工做咱們已經提高到應用層了,通常狀況下,這層最好不要涉及資源庫的調用,可是並不絕對。資源庫的抽象要麼在領域層中,要麼提高到了「應用程序框架」,領域層是不會依賴基礎設施的。

 

基礎設施層:

原版----本層做爲其餘層的支撐庫存在。它提供了層間的通訊,實現對業務對象的持久化,包含對用戶界面層的支撐庫等做用。

補充----這層的職責包含了三層的數據訪問,可是並不表明UI層就能夠調用數據訪問的代碼,並且職責範圍擴充了,有人可能會把它看成存放公用代碼的地方,可是建議這裏只存放本項目公用的東西,若是可以跨項目公用的代碼應該放在一個叫作「應用程序框架」的項目來完成,每一個公司都應該有本身的應用程序框架。

 

回顧一下三層架構DDD分層的區別:

a. UI層技術基本同樣,一些比較智能的綁定可能沒法進行了。

b. 服務層基本同樣。

d. 業務實體+業務邏輯 = 領域層

e. 若是三層架構不採用業務實體與數據表一致的作法,這層也是同樣。

 

2.2.2 DDD模式簡單介紹

DDD的模式有:聚合,實體,值對象,工廠,資源庫,模塊。若是徹底沒有DDD經驗,建議首先閱讀《領域驅動設計精簡版》一書,可快速掌握DDD的理念。

聚合:這是個難點,通常建議是要設計小聚合,聚合與聚合之間用ID關聯,不要直接引用。聚合包含實體,值對象。表達聚合的對象叫作聚合根。聚合內部全部對象的變動必須經過聚合根。聚合根的本質是一個實體。若是聚合要傳遞給其餘模塊(系統),通常不要直接傳遞聚合根,新建一個粗粒度的值對象來進行傳遞,即DTO對象,DTO也可由接收方創建,由接收方決定須要什麼數據,這樣就解耦了模塊間的關聯,至於數據庫中是否須要把這個DTO冗餘存儲,則看實際狀況。聚合的數據表設計原則:大表小類。即數據表採用粗粒度,聚合根內部使用細粒度對象,有可能的話,儘可能每一條數據表記錄就是一個聚合。

實體:特色是必需要有一個ID來標識本身,可包含值對象和其餘實體。

值對象:特色是個只讀對象,沒有ID標識。

工廠:因爲聚合的建立多是個很是麻煩的事情,用工廠來封裝這個複雜麻煩的過程。

資源庫:資源庫就是持久化聚合的地方,就是說數據存儲的最小粒度是聚合。可是數據查詢的需求可能很是靈活,實踐中這條規則有點僵化,通常使用是讀寫分離方案,就是寫的時候使用聚合對象,可是讀的時候能夠根據業務仔細創建一些查詢模型(QueryModel)進行讀取。至於數據庫是否須要分紅讀寫兩個模型,仍是要看實際狀況,在系統更復雜和須要更高性能的時候,數據庫的模型也要分紅兩個,不過它們之間的同步就比較麻煩了。領域事件、CQRS、Event Sourcing等技術就是用來解決這個麻煩的。

領域服務:總有一些須要多個聚合進行合做才能完成的業務,它們不能簡單地劃歸參與的其中一個聚合,要用一個領域服務來表達,注意領域服務不是應用層的服務。

模塊:如何劃分模塊,通常有橫向劃分和縱向劃分兩種,橫向劃分例如:實體模塊,工廠模塊,資源庫模塊。縱向劃分例如:商品模塊,訂單模塊,支付模塊,每一個模塊內部都會具有聚合,資源庫,值對象等元素。通常的經驗是橫向劃分對項目沒有什麼幫助,縱向劃分能夠減小系統的複雜度。模塊間的交互在應用層進行。

 

2.2.3 重構

掌握了DDD的知識以後,剩下的工做就是按照DDD的指導進行重構了。重構有風險,掌握成熟的重構手法能最大程度規避這種風險。在團隊中進行改變架構級的重構,必須先要在整個團隊中取得共識,不然你認爲的改進在別人看來多是在改退。

在重構的過程當中,用各類代碼壞味做爲切入點,DDD模式、設計模式等做爲方向,利用成熟的重構手法掌控重構過程,而後用SOLID設計原則評估你的重構成果。

最好團隊中有比較精通須要掌握重構和DDD的人在旁指導和增強代碼走查,確保一直走在正確的道路上。若是可以造成團隊學習的氛圍,那麼一切都不重要了,如今沒有掌握的思想技術,相信很快就能擁有。

再次強調,重構,是不少人的口頭禪,可是他們不必定真的懂得什麼是重構,沒有掌握成熟的重構手法而進行重構跟盲目自信是一個道理,特別是對整個系統架構改進的重構,是個高風險的大工程,必須在團隊中取得共識,並有明確的目的地和到達目的地的安全路徑。

至此,三層到DDD的轉換基本完成了,咱們主要完成了一個思想上的轉變,今後咱們的技術之路踏上了新的征程。這是三層的終結,也是DDD的開端。路,還很長。

3. DDD技術支撐

3.1 面嚮對象語言

DDD的核心是要創建一個通用語言。何謂通用?首先項目全部關係人(需求、開發、測試、其餘管理者、客戶、甚至能夠寫到宣傳海報上)都可以用通用語言來交流,人們要大聲地建模,就是說領域模型應該可以容易地用天然語言表述,而後開發人員與計算機也要用通用語言交流,就是說盡可能把通用語言寫進代碼裏面去,這就是所謂DDD的戰略層面。通用意味着最接近事實,越貼近現實的結構就越穩定,而面向對象的特色就是要下降代碼與現實世界的表示差別,這點和DDD是一致的,所以實現DDD的首選技術就是面嚮對象語言,固然Eric Evans最新研究認爲用函數式編程也可以進行DDD。

面向對象的繼承是一個最容易被誤用的特性,通常認爲組合優先於繼承。更進一步,我認爲基本上不該該經過繼承來擴展對象的結構(屬性),只應該用繼承來區別行爲(方法),這樣作是符合里氏替換原則的。

創建對象結構是個很是複雜的工程,後面章節再介紹一點本人的經驗。

3.2 領域對象存儲

延遲數據庫實現

DDD讓咱們把編程的核心從如何創建信息的存儲結構,轉移到如何讓創建信息的事實結構上來了,這樣,在陌生領域裏一開始每每很難把握正確的結構,經過與領域專家持續地對業務的討論,經過單元測試的反饋,經過重構慢慢將數據結構推向事實,到了項目後期,基本上不管需求發生什麼變動,結構都是穩定的。在這個過程當中,對象結構的變化是至關激烈的,若是每次變化都要去修改數據表結構,也是一件很是麻煩的事情,所以若是在開發中可以把數據存儲在內存中,而不須要去考慮數據庫,將會大大提高開發的效率。可是要保持內存和持久化的查詢接口一致是個麻煩事,每種ORM都有本身的查詢語言,一旦你使用了某種ORM的查詢語言,那麼你就跟它綁定在一塊兒了,若是想要換個ORM就難了,所以咱們或許應該考慮實現一個本身的不依賴任何ORM框架的查詢語言。

 

取回只讀屬性

面向對象的重要特色之一是封裝,這樣會保護對象不被亂用,可是同時爲重建數據結構帶來了麻煩,不過如今的ORM基本都可以經過反射來取回只讀屬性了,還有個方法就是經過一個特殊的構造方法來取回數據結構。

 

對象屬性遞歸引用

對象屬性包含對象,這樣無限的遞歸下去的狀況,該如何存儲?例如存儲一個樹的節點。這個時候必需要製造一個DTO來隔絕這種傳遞關係。

3.3 規則驗證

單個對象自己正確性驗證

這種驗證最簡單,就是把三層裏的驗證方法搬進相關類裏面就好了,可是若是客戶忘記調用驗證方法了,怎麼辦呢?咱們能夠給全部須要驗證的對象都實現一個驗證接口(IValidatable),而後在保存入口自動調用此接口。

 

同類對象關鍵屬性不能重複驗證

因爲咱們已經約定,領域對象儘可能不要跟數據存儲打交道,因此要驗證這個邏輯得放在服務層進行,可是這樣的話驗證方法的業務完整性就出問題了,所以把一個Repository傳進檢查方法也是一個辦法,固然選擇權在你團隊的手上。

 

不一樣類對象之間關係驗證

此類驗證參看上一條驗證。

3.4 Repository模式的實現參考

Talk is cheap. Show me the code. [Linus Torvalds]

 

說了那麼多,不給些代碼,小夥伴們都不一樣意了,所以這個地址是本人的一個Repository的參考實現【僅供參考,責任自負】。

https://github.com/MurrayMol/MAF/tree/master/src/Repo

本實現的主要思想是以類型做爲存儲單位,用泛型減小Repository的接口,統一存儲的入口方便規則驗證,統一內存與持久化存儲接口方便在不一樣的存儲結構中切換。

 

工欲善其事,必先利其器。思想再先進,最終還得以落地爲準。爲了實現上面介紹的思想,在本實現中用了三個開源軟件,簡單介紹一下:

ORMDapper,地址:https://github.com/StackExchange/dapper-dot-net

Dapper是個ORM框架,特色是須要寫Sql語句,可能不少人會不喜歡這個。上面咱們提到了要推遲數據庫的實現,可是不表明數據庫的重要性也下降了,其實DDD強調的是提高曾經被忽略的數據結構(領域建模)的重要性,而不是貶低數據庫的地位,數據庫依然是第一序列的重要事物。對待如此重要的東西,我以爲仍是寫Sql語句才能表明咱們對它的尊重,並且面對一些查詢模型,寫Sql語句可以提供最強靈活性和最強的效率。至於Sql語句會變得很是複雜的問題,這絕對是你的數據模型沒有建好,後面章節將會介紹一些數據建模的經驗。

快速反射框架:Fasterflecthttp://fasterflect.codeplex.com/

反射在框架設計是個不可缺乏的東西,可是它的效率是個不得不考慮的問題,Fasterflect是個使用Emit方式進行反射調用的框架,還有緩存、委託等方式提高性能。

OOMValueInjecter http://valueinjecter.codeplex.com/

相似於AutoMapper,EmitMapper等框架,不過這個框架的特色是提供了一個可容易擴展的轉換接口(契約),它自己的轉換類功能倒不是那麼強大,不過配合Fasterflect使用將如虎添翼。

3.4 開發過程回顧

 

典型的三層架構開發過程:

三層架構以數據庫爲核心,首先根據需求創建數據模型,而後根據數據模型創建數據庫,再根據數據表結構自動生成業務實體,而後能夠同時進行業務邏輯及用戶界面的開發。

一旦開發中業務有所變更,那麼首先要修改數據庫,從新生成實體,而後其餘開發小朋友才能繼續工做,網絡鏈接很差、數據庫掛機、數據庫管理員未能及時更新數據庫等等緣由都會致使開發過程被打斷,好處是終於能夠休息一會,壞處是因爲要趕進度晚上可能得加班。

常常變動數據庫結構總不是一件愉快的事情,爲了不數據庫結構變更,要求編碼階段以前儘可能要把需求固定下來,中後期越少變更越好。因爲業務邏輯與數據庫綁定緊密,因此單元測試困難重重。當性能出現問題的時候,究竟是代碼邏輯沒有寫好,仍是Sql語句沒有寫好,診斷有點困難。因爲類的粒度太大,設計模式罕有用武之地,設計原則跟本身沒有關係,長此以往可能會以爲編程思想都是騙人的。

 

DDD開發過程:

DDD以領域模型爲核心,首先根據需求創建領域模型,而後根據領域模型創建代碼模型,而後就能夠同時開發業務邏輯和用戶界面了。

咱們有一個模擬數據庫存儲接口的內存數據庫,所以這時候不須要考慮數據庫,若是這時業務發生變化,直接修改對象結構是很是簡單的事情。直到開發後期,全部功能都已經開發完成,業務結構也穩定下來了,咱們再根據領域模型創建數據庫,進行一個簡單的與業務邏輯集成就完工了。

免除了開發過程當中數據庫常常變更的煩惱,開發過程不會被打斷,隨時能夠進行單元測試,隨意能夠與用戶界面集成把系統跑起來,開發邏輯的時候不考慮數據庫,開發數據庫的時候不考慮業務,關注點更加集中了。出現性能問題能夠單獨測試數據庫組件和業務邏輯組件,更容易定位問題。類的粒度很小,各類重用,各類設計思想都紛紛派上用場,感受終於跟國際接軌了。

相關文章
相關標籤/搜索