.NET領域驅動設計—初嘗(二:疑問、模式、原則、工具、過程、框架、實踐)

 

  • 1.3.原則
    • 精簡聚合
    • 分離用例與接口功能(設計模式的使用之地)
  • 1.4.工具、框架
  • 1.5.過程
  • 1.3】原則

    原則對於任何一項技術實現來講都是相當重要的,在設計某一個系統功能的時候咱們講究的是設計原則:數據庫

  • 單一職責原則Single Responsibility Principle、里氏替換原則Liskov Substitution Principle、依賴倒置原則Dependence Inversion Principle、接口隔離原則Interface Segregation Principle、迪米特法則Law Of Demeter、開閉原則Open Close Principle】。設計模式

    在架構設計的時候咱們也講究架構原則:架構

  • 【分層原則、避免循環依賴】。框架

    不只僅在技術領域在作人作事都要講究原則,違背原則那麼等待你的將是無情的懲罰。ide

    對於DDD的設計咱們也有相應的原則須要遵照,固然若是不遵照在前期看不出什麼區別,可是到開發階段問題就會暴露出來。工具

    咱們來看兩個基本的設計原則問題。學習

    【精簡聚合】編碼

    精簡聚合的設計原則無疑是最重要的。一些軟件工程方法論書籍常常指導咱們進行UML業務建模,"在這個階段不須要考慮任何技術實現問題」,我按照這樣的指導原則進行了UML的設計而後順利的建立出ER關係圖,結果發現那樣的數據庫結構根本不能做爲最終的項目開發數據庫。哪裏出問題了?我反覆查詢指導書籍後來在專業的DDD書籍上看到了一句大概這樣的話:spa

    • 【「不以技術實現爲前提的設計都是紙上談兵」】架構設計

    我想這句話很真實的描述了方法論與企業應用之間的鴻溝,不少技術思想或者理論確實很好,可是要想用起來須要解決不少問題。DDD也避免不了這個問題,怎麼避免在設計UML模型的時候不會致使設計過分的問題,這裏咱們只須要遵照【精簡聚合】原則就不會致使設計過分問題。

    在前面的例子當中咱們設計一個完整的UML領域模型,可是咱們並無對它進行【精簡聚合】重構,因此它存在的問題就是沒法進行項目開發。

    1.1圖

    8

    咱們構建出來的領域模型初步版本應該是上圖這樣的,實體與實體之間是有強聯繫的,聚合之間的關聯太大,致使牽一髮而動全身。若是按照這種關係建立數據庫那麼數據庫之間的主\外鍵確定不少,對數據庫的設計形成了影響。這樣的關係若是在程序中使用也會存在不少問題,咱們沒法進行少數聚合的使用,當咱們使用某一個聚合的時候它會連續不斷的把相關聯的聚合都給拖出來,不只在查詢的時候妨礙並且在Factory建立聚合的時候也會存在沒法構造的問題,無論在對聚合Repository進行任何操做的時候都會影響程序邏輯,因此咱們須要對一個複雜的龐大的關係進行拆分。

    將紅線的部分所有斷開,聚合之間經過Id進行關聯,這樣就會變的很清晰。由於不多程序中會在某一個業務邏輯點上須要全部的業務模型參與,這樣既方便了程序的開發也方便了數據庫的設計,更方便了ORM的使用。ORM的延遲加載其實就是爲了聚合之間的依賴,能夠在須要的時候在去查詢須要的模型。可是這樣雖然程序能夠說的過去,那麼數據庫的設計就說不過去了。對於不一樣的ORM框架的映射原理不一樣,在構造模型的時候是須要稍微的調整的,好比在EntityFramework中,它能支持的映射方案你保證你的模型能順利的映射過去,這裏就不扯了後面有一個詳細的項目作全面實踐,到時候在具體問題具體分析。[王清培版權全部,轉載請給出署名]

    最後咱們看一下分解後的類圖:

    1.2圖

    9

    這樣一來一塊一塊很清晰,都能直接使用相關的核心領域模型,也不須要擔憂ORM框架的延遲加載的問題。

    【分離用例與功能接口(設計模式的使用之地)】

    分離用例與功能接口其實也是初次接觸DDD的朋友都會犯的職業病,由於咱們都熟悉面向對象設計。在進行UML建模的時候咱們都很是喜歡抽象,會很清楚的把具備泛化關係的用繼承來表示,好比【用戶類型】,不一樣的用戶具備不一樣的行爲權限,在初步設計的時候咱們通常都會創建關於用戶的一個繼承關係來表達泛化的業務模型。可是在編碼階段會發現很明顯的問題就是咱們把關於Repository的行爲包含到了發起用例的用戶聚合當中去了,這樣說可能有點抽象。咱們仍是用例子來分析;

    1.3圖

    10

    上圖中我將【Admin】和【配送】用例分開了,想表達是不能將關於配送的行爲放在【Admin】中。在咱們對有關權限進行建模的時候常常會潛意識的將各自的行爲放在了各自的角色當中,若是後期存在多角色共享行爲的就將寫在抽象的類中使用虛方法向下傳遞。問題就出在關於角色行爲裏,咱們知道若是有行爲那麼就有可能在該行爲裏面執行有關其餘聚合的IRepository操做,這樣一來將會把領域模型搞的很亂,沒法垂直分析。

    1.4圖

    11

    DDD講究領域驅動,在咱們看來【Dispatching】、【CheckOrders】都是繼承管理員角色,管理員屬於後臺管理人員,意味着企業的員工。對消費者來講他們就是管理人員。一樣消費者也會存在相同的狀況,消費者可能存在不少種類型,有VIP系列的(VIP1\VIP2\VIP3…),有鑽石會員之類的。若是這樣設計的話並不能說是錯的,這也徹底符合DDD的思想要求,可是實際狀況下倒是不理想的。

    這裏就用到了咱們長期使用的設計模式了,咱們能夠經過設計模式中的不少中模式來將用戶與行爲分離開來,再將使用的規則條件抽象出來就徹底獨立了用戶,用戶在使用的時候不會存在直接的行爲歸屬,可是事實上他們確實是有行爲。

    1.5圖

    12

    用專業的DDD術語講「規約模式」,將業務規則抽取出來對象化,甚至到最後均可以進行規則的配置化。最讓咱們興奮的是,咱們苦心學習的設計模式終於能夠在系統設計中大面積的使用了,難道不是一件很驚喜的事情嗎!

  • 1.4】工具、框架

    任何一種架構都是須要框架、工具的支撐才能變的完美。

    當咱們在某種架構下進行開發的時候,咱們必須須要不少工具、框架的支撐才能讓開發工做變的很便捷,這也和【敏捷開發】的思想同樣。在傳統的三層架構下開發咱們都須要 "對象映射"、"AOP\IOC」 等等相似的輔助框架,目的是爲了架構前行的可能性。在DDD中咱們也須要不少目前尚未出現的不少工具、框架,在.NET平臺中目前來看只有EntityFramework框架算是爲了DDD作了不少工做,若是咱們的領域模型沒法與數據庫進行映射,那麼領域模型開發所要付出的代價將是很大。

    在設計階段咱們缺少一個面向特定領域的建模工具,這種工具與UML不一樣,UML太技術化通用化。DDD中常常會提起【領域專家】一角,他是最具備權威性的領域領頭人,咱們所建立出來的UML他們未必能看得懂,經過技術人員技術化以後造成UML其實已經變味,【領域專家】是懂非懂的沒法作到確定的保證。若是能把領域模型語言化,那麼這個將是一大成就。【領域專家】對領域中的任何事物、人物、環節都很熟悉,可是他沒法表達清楚本身的想法,若是能有一個工具輔助他的設計,該工具能將設計後的模型進行平滑等價的技術化變成代碼模型或者數據庫模型,這一條鴻溝若是能跨越那麼對行業來講具備很大影響力。

    1.8圖

    13

    若是咱們能等價的將上圖中的真實模型進行技術化,那麼真的每一個人都會喜歡需求分析、分析設計。

    既然是模型驅動設計,咱們在給用戶分析相似這樣一套系統的時候,前提是咱們已經對裏面的全部細節進行了抽象封裝,每個過程都是能夠拆分的,最後能合併在一塊兒造成一個總體的業務模型。固然這裏只是一種技術展望,也是咱們奮鬥和理想的目標。

    推薦一本最新Martin Fowler的書:《領域特定語言》

     

  • 1.5】過程

    DDD不是一種純技術實現,而是一整套開發思想,它貫穿軟件開發的全部生命週期。從咱們開發接觸領域,對領域知識進行深刻的消化,這些都是DDD所強調的。那麼在咱們平常開發過程當中,咱們該如何處理這些過程,需求不會再像之前那樣是一份雜亂無章的草稿,而是一個內容豐富的領域模型草圖。這樣的要求對團隊對部門甚至對公司來講都是一個提高,要想作到徹底的DDD過程其實很難。

公司領導如何看待這樣的開發方式,咱們多數人都是在一些非專業研發類的公司工做,領導但願能儘早的看到東西,這很矛盾,須要好的東西可是不按照好的東西作法來作。若是有幸能有一個面向DDD、敏捷、XP的研發團隊工做,那麼能夠視項目爲一件終身的藝術品。[王清培版權全部,轉載請給出署名]

 

這兩篇文章主要是一些本人對DDD的感悟,分享給你們。

後面一篇文章將會詳細的使用一個DDD架構的小系統做爲案例給你們分享,裏面將包括從需求的分析建模、設計模式的使用、數據庫映射、EntityFramework的使用等等,能夠做爲真實項目開發的依據。

相關文章
相關標籤/搜索