領域驅動設計(Domain Driven Design)
前言
什麼是軟體
軟體是一種被建立用來幫助我們處理現代生活中複雜問題的工具,它只是到達目的的一種方法(不是一定要使用軟體)。
【手機、作業系統、IM、email】
軟體的特點
- 軟體必須是實際和有用的;
- 軟體設計是一門藝術(程式設計師是一位手藝人);【木匠、工藝品、刺繡】
- 完成軟體設計的方法多種多樣;(這裡單講ddd這種方法)
引出問題
在啟動一個軟體專案時,我們應該關注軟體涉及的領域。軟體的最終目的是增進一個特定的領域。為了達到這個目的,軟體需要和他服務的領域相得益彰。
為了建立一個好的軟體,你必須知道這個軟體究竟是什麼,主要解決什麼領域的問題。
什麼是領域(Domain)
一個領域本質上可以理解為一個問題域 。只要確定了軟體所屬的領域,那麼這個領域的核心業務(基本問題)就基本確定了。
最佳實踐
讓軟體成為該領域的對映。通過對領域進行建模(領域模型),對該領域模型進行實現。
領域通用語言(Ubiquitous Language)
為了讓領域專家,設計人員,開發人員搭建溝通的橋樑。使用一門通用的語言。【UML、SQL】
領域驅動設計(Domain-Driven Design)
領域驅動設計
領域驅動設計的核心是建立正確的領域模型。【怎麼建立領域模型】
步驟:
1. 以一種領域專家、設計人員、開發人員都能理解的通用語言作為相互交流的工具,在交流的過程中發現領域概念,然後將這些概念設計成一個領域模型; 2. 由領域模型驅動軟體設計,用程式碼來實現該領域模型;
領域模型(Domain Model)
特點:
- 對具有某個邊界的領域的一個抽象,反映了領域內使用者業務需求的本質 。它屬於『解決問題空間』。領域模型是有邊界的,只反應了我們在領域內所關注的部分,包括 實體概念(如:貨物,書本,應聘記錄,地址等),以及過程概念(如:資金轉賬等);
- 提高軟體的可維護性,業務可理解性以及可重用性。領域模型確保了我們的軟體的業務邏輯都在一個模型中,幫助開發人員相對平滑地將領域知識轉化為軟體構造;
- 貫穿軟體 分析、設計、開發 的整個過程。領域專家、設計人員、開發人員面向同一個模型進行交流,彼此共享知識與資訊,所以可以防止需求走樣,讓軟體開發人員做出來的軟體真正滿足需求;要建立正確的領域模型並不簡單,需要領域專家、設計、開發人員積極溝通共同努力,然後才能使大家對領域的認識不斷深入,從而不斷細化和完善領域模型;
- 為了讓領域模型看的見,使用的常用表達領域模型的方式:圖、程式碼或文字;
- 重要性:領域模型是整個軟體的核心,是軟體中最有價值和最具競爭力的部分;設計足夠精良且符合業務需求的領域模型能夠更快速的響應需求變化;
構成要素
- 實體(entity):在整個系統的生命週期中擁有唯一的識別符號的物件。(不應該給實體定義太多的屬性或行為,而應該尋找關聯,將屬性或行為轉移到其他關聯的實體或值物件上。)【使用者user擁有唯一標識,大學university擁有唯一的標識】
- 值物件(value objects):如果兩個物件所有屬性的值都相同,我們會認為它們是同一個物件,那麼就可以把這種物件設計為值物件。沒有識別符號的一個物件、不可變 的,即所有屬性都是隻讀的,所以可以被安全的共享。【使用者user的地址資訊address,大學專業】
- 領域服務(services): 領域中的一些概念不太適合建模為物件(實體物件或值物件),因為它們本質上就是一些操作、動作,而不是事物。這些操作往往需要 協調多個領域物件。如果強行將這些操作職責分配給任何一個物件,則被分配的物件就是承擔一些不該承擔的職責,從而會導致物件的職責不明確很混亂。DDD認為領域服務模式是一個很自然的正規化用來對應這種跨多個物件的操作。一般的領域物件都是有狀態和行為的,而領域服務沒有狀態只有行為。【操作的集合,比如加密操作】
- 模組(moudles):
對於一個大型的複雜應用而言,領域模型趨向于越來越大,模型到達了一個作為整體很難討論的點,理解不同部件之間的關係和互動變得很困難。基於此原因,很有必要將模型組織進模組。模組被用來作為 組織相關概念和任務以便降低複雜性的一種方法。而另一個原因則是模組可以提高程式碼質量和可維護性,比如我們常說的高內聚,低耦合就是要提倡將相關的類內聚在一起實現模組化。
模組應當有對外的統一介面供其他模組呼叫,比如有三個物件在模組a中,那麼模組b不應該直接操作這三個物件,而是操作暴露的介面。模組的命名也很有講究,最好能夠深層次反映領域模型。
- 聚合(aggregate):它通過定義物件之間清晰的所屬關係和邊界來實現領域模型的內聚,並避免了錯綜複雜的難以維護的物件關係網的形成。聚合定義了一組具有內聚關係的相關物件的集合,我們把聚合看作是一個修改資料的單元。一個聚合中可以包含多個實體和值物件,因此聚合也被稱為根實體。【聚合中的物件密不可分】
- 工廠(Factory):體現封裝思想的模式。用來封裝建立一個複雜物件尤其是聚合時所需的知識(變數),工廠的作用是將建立物件的細節隱藏起來。實體和聚合通常會很大很複雜,根實體的建構函式內的建立邏輯也會很複雜。實際上通過構造器努力構建一個複雜的聚合也與領域本身通常做的事情相沖突,在領域中,某些事物通常是由別的事物建立的(例如電器是在組裝線上被建立的)【所需即所得】
- 倉庫(Repository):資源庫用於儲存和獲取聚合物件。【為了資料落地】
- ...
領域驅動設計的經典分層架構
分層的初衷
專注於展現領域模型。
將一個複雜的程式切分成層開發每一個層中內聚的設計,讓每個層僅依賴於它底下的那層。遵照標準的架構模式以提供層之間的低耦合。【將領域模型相關的程式碼從介面層、應用層和基礎設施層分隔出來】
概念
-
使用者介面/展現層
負責向用戶展現資訊以及解釋使用者命令。(請求應用層以獲取使用者所需要展現的資料;傳送命令給應用層要求其執行某個使用者命令;)
-
應用層
很薄的一層,定義軟體要完成的所有任務。對外為展現層提供各種應用功能(包括查詢或命令),對內呼叫領域層(領域物件或領域服務)完成各種業務邏輯,應用層不包含業務邏輯。
-
領域層
負責表達業務概念,業務狀態資訊以及業務規則,領域模型處於這一層,是業務軟體的核心。
-
基礎設施層
本層為其他層提供通用的技術能力;提供了層間的通訊;為領域層實現持久化機制;總之,基礎設施層可以通過架構和框架來支援其他層的技術需求;
領域建模的方法
用例分析法、DDD的方法、四色建模法
四色建模法
某個人(Party)的角色(PartyRole)在某個地點(Place)的角色(PlaceRole)用某個東西(Thing)的角色(ThingRole)做了某件事情(MomentInterval)。
PartyPlaceThing:簡稱PPT,用淡綠色表示,常見的PPT有:部門、崗位、人員、地點、物品等。 Description:簡稱Des,用淡藍色表示,主要用來對PPT進行描述,常見的Des有:部門型別、崗位層級、人員型別、地點區域、物品分類等。 Role:用淡黃色表示,主要表示PPT在某個場景下扮演的角色,常見的角色有:財務類部門、管理類崗位、請假者、銷售點、產品等。 MomentInterval:簡稱MI,用淡紅色表示,主要表示在一刻或一段時間內發生的一件事情,常見的MI有:部門移動、崗位移動、員工離職、產品銷售等。 MomentIntervalDetail簡稱MIDetail,用淡紅色表示,主要表示MI的明細,常見的MIDetail有銷售明細、入庫明細、出庫明細等。
參考
- http://www.cnblogs.com/netfocus/archive/2011/10/10/2204949.html
- https://www.cnblogs.com/butterfly100/p/7827870.html
- http://www.fanyilun.me/2018/04/08/%E8%B0%88%E8%B0%88%E9%A2%86%E5%9F%9F%E5%BB%BA%E6%A8%A1/
- https://www.cnblogs.com/Leo_wl/p/3866629.html#_label8
- https://www.jianshu.com/p/b6ec06d6b594
- https://infoq.cn/article/xh-four-color-modeling
- https://www.cnblogs.com/happyframework/archive/2013/04/26/3043515.html
- https://www.imooc.com/learn/1101