最近在研究DDD很有收穫,因此整理出來跟你們分享,共同進步!程序員
咱們在設計業務系統的時候都會存在一個很是棘手而又沒法迴避的問題「業務擴展性」、「業務靈活性、」面向對象化「,儘管咱們熟練掌握設計思想、設計模式、設計原則等等關於如何設計靈活性的系統設計理論,可是咱們彷佛都沒有將它們運用到真正業務系統設計、開發當中去,爲何?這樣的疑問若是對有心想設計好系統的朋友來講確定是很早就出現過,只是沒法解決,由於咱們目前使用的設計方法是與面向對象設計背道而馳的。面試
漫長的數據庫驅動開發歷史,致使咱們根本沒法脫離這個環境進行學習和實戰。從教科書再到真正的企業項目開發都是先設計數據庫而後進行邏輯的編寫,大部分的業務邏輯都是存在於UI和數據庫【存儲過程、自定義函數】中,所謂的三層架構中的BLL層實際上是形同虛設,根本沒有起到它應有的做用。數據庫
固然咱們不是大師,咱們只是普通的程序員,但願有一種方法論能引導咱們進行真確的系統設計。在未接觸DDD以前,我也同樣有着一樣的困擾,咱們編寫不少的開發框架、組件、插件、服務等等太多太多相似能提升開發效率的功能,夢想着本身的系統能想真正如書上所說的搭積木同樣搭建本身的系統,咱們捫心問本身真的能夠作到嗎?我嘆息,很難;編程
我一直感受複雜的系統設計對我來講真的沒有辦法應付,只能憑藉細心和對業務的熟悉程度,沒有正確的理論引導,那些所謂的大師們的設計思想的書真的對我幫助不大,看了不知道如何進行運用。時至今日我終於能夠感受到那種神祕的設計確實能夠帶領咱們穿越復發的系統設計。固然這條路對剛開始接觸DDD的朋友來講會存在不少問題,恰巧在下有幸接觸DDD有點心得,也經過分析了一個小的系統進行DDD的開發工做,因此在這裏把本身最近研究的心得和疑惑跟同行們分享,若有不對的地方請多指點。[王清培版權全部,轉載請給出署名]設計模式
在任何一項新技術被採納以前必需要解決幾個關鍵的問題,這也是咱們程序員考慮使用一項新技術的必須過程,它的出現能解決哪些問題和將會帶來哪些問題。DDD當然很好,可是要想把它運用到本身的項目當中去,是須要不少時間和精力來分析它的實施過程和對項目團隊的要求。固然人爲的因素和外在的環境問題咱們這裏不考慮,畢竟那些是咱們沒法改變的事情,這裏只討論和咱們密切相關的問題。架構
作程序開發的咱們都知道UML是幹什麼的,簡單的講它屬於一種標準的系統建模語言,便於咱們對系統進行分析和團隊之間的合做。既然是語言它的主要做用是溝通,技術人員和分析人間的橋樑。可是到目前爲止我沒有發現它真正幫助過我進行系統分析和設計,上面已經提過實際上是兩種開發方法論偏偏相反,因此致使根本沒法集成,就拿UML中的類圖來說,咱們都是先設計數據庫而後進行開發何來的對象?直接是表驅動,經過一些快速的代碼生成器進行界面和一些通用的單表的CDUS代碼的生成,程序中根本沒有對象的概念,業務邏輯遍及UI層[圖1.1]。UML畫的類圖沒法在程序中表現出來,因此它沒法在絕大部分的企業中普及。框架
1.1圖數據庫設計
上圖假設是一個簡單的模擬B2C的基本功能,經過它咱們能簡單的瞭解到咱們的系統開發的問題所在。ide
以上圖中的系統結構,咱們很難知道系統的具體業務邏輯,更別說對系統的擴展性能有保障。這樣的結構在開發初期沒有什麼問題,可是在後期的維護工做中將是費事費力的,最後的項目代碼沒法進行的很好的閱讀,也就沒法很好的進行穩定性維護。特別是業務系統,它的需求會變的不少甚至很變態,若是按照這種方式進行維護,那麼界面上的代碼會愈來愈多,而BLL、DAL中的重複性的功能方法也會急劇變多或者是服務層的相同功能不一樣方法參數的代碼會愈來愈多。其實到最後也就談不上什麼藝術了,更別說項目進行產品化後上市。函數
那麼UML真的起不到做用嗎?或者說咱們真的與UML無緣?固然不是,而是咱們沒有使用相關的軟件設計、開發方法論而已。按照DDD的思想,咱們是業務驅動開發,先進行領域模型的建立,而後纔是數據庫的設計。其實只有按照DDD的開發理論來才能最大的保證系統的擴展性和業務整潔性,才能保證項目的良性循環。[王清培版權全部,轉載請給出署名]
「領域建模」很抽象也很藝術的一個詞,它是軟件設計藝術中的一個境界。
咱們經常接觸面向對象編程、面向對象設計的書籍或者話題,你們都對它有獨特的看法,可是咱們始終沒有將它用做真正的系統性開發中去。可是在編寫框架的時候咱們都能駕輕就熟的進行面向對象設計,爲了保證框架的靈活性乃至最大的擴展性就要進行最細粒度的分解、抽象、提取,這些在非數據庫系統開發中都沒有問題。然而最大的問題出在對象須要與數據庫結合,對象的生命週期持久化在數據庫中,生也數據庫死也數據庫。因此這裏的問題就是如何在面向對象設計與關係型數據庫設計之間平滑的過分持久化。這是領域驅動開發的最大的問題,也是不少面向DDD框架的開發重點。
在上圖中咱們目擊了以數據庫驅動後系統的大體結構,假設咱們須要保證功能模塊的最大的擴展性咱們在編寫數據庫驅動代碼的時候,很難抽象出複雜的變化點,由於都是貧血型的業務模型或者說根本不知道變化點在什麼地方。並且並非普通的開發人員能發掘到的,固然數據庫驅動開發也同樣能夠進行靈活設計、開發,可是這樣畢竟對開發人員要求很高,他須要具有很強的面向對象設計能力,在不污染現有的代碼的狀況下進行擴展性重構。至少個人經驗告訴我很難,並且在需求階段並無一個完整的大局觀,很容易形成頭重腳輕。對後期的系統開發進度也很難控制,由於沒法肯定每一個功能模塊到底存在哪些接口。
因此咱們仍是朝着光明的道路前進,掌握DDD進行系統設計開發。
咱們下面試着用建模的方式對上圖中的功能點進行大體面向對象設計,儘可能提取變化點。
【簡單用例】
根據上圖的基本功能咱們肯定兩組用例,第一組是【客戶Custom】發起的全部動做,第二組是【後臺管理人員Admin】,好比配貨部門、訂單審覈部門等等。這裏純粹是爲了演示建模的功能不是特意的項目實踐,因此功能簡單明瞭。
1.2圖
客戶首次進去平臺以後確定是須要進行帳戶的【註冊】,有註冊就會有【註銷】,這裏的註銷不是退出系統的意思,而是註銷在當前平臺的使用,就跟銷戶是一個意思。
(固然有人會以爲註銷不妥,電子商務平臺是不該該有註銷的,這只是主觀的設計而已,每一個人的想法不一樣因此能夠取長補短 ,我以爲有一個正面的註銷功能很好,可讓用戶進行使用,到底如何使用咱們這裏就不分析了。)
成爲正式用戶以後就能夠挑選本身喜歡的商品進行【下訂單】,下訂單後就會進入平臺運行管理的流程的,客戶會隨時收到平臺發過來的流程信息反饋。因此這裏有一個【短信管理】用例,該用例固然會包含 【刪除信息】、【讀取信息】、【回覆信息】包含的子用例。
(固然可能我分析的不夠細緻或者有問題的地方,因爲我也是最近接觸UML建模因此可能有點不熟悉,對UML有興趣的朋友能夠參考相關專業書籍。)
1.3圖
後臺管理人員須要對客戶下的訂單進行【配送】處理,配送環節將牽扯到【客戶信息】、【更新訂單狀態】、【打印配送信息】用例,對【打印配送信息】
功能須要【發送收貨信息】給用戶,告知用戶貨物已經發出。這裏還包括一個泛化的用例【物品清單、配送地址】,在【打印配送信息】功能裏面須要具體的打印出跟配貨信息相關的信息。
(這裏提一下UML用例圖實際上是經過縱橫向的方式來尋找系統的全部功能點,縱向是系統的全部功能,橫向是系統的外部調用者。)
【領域模型】
根據上述用例咱們基本能捕獲到大體的系統功能,下面咱們經過建立UML類圖來描述領域模型。
模型的建立要根據上一步的用例圖來進行分析,只要建立的模型能知足用例的全部功能點就已經完成了一個大體輪廓。有些隱藏的模型是須要不斷的重構才能逐漸的浮現出來。
1.4圖
大體的模型已經建立出來,這隻能算是一個基本的草圖形式的建模,還有幾個過程沒有走完,好比:反覆的重構、與領域專家討論模型的準確性、與DBA進行溝通等等,這些都是DDD的整個範疇。
有了領域模型以後咱們基本算是有了一個大體的業務方向,剩下的就是精益求精的過程,不斷的去分析深層業務關係。
【場景序列】
得出了領域模型以後咱們須要對它進行一個基本的驗證,也就是看看模型是否能知足全部的功能需求。最經常使用的就是經過序列圖來走查場景,對咱們建立的領域模型進行逐步驗證。
因爲時間關係我這裏就不給出全部的序列圖了,只給出有表明性的序列【配送】。
1.5圖
因爲怕截圖片太大因此給出關鍵的序列流程,能表達其意思就好了。
這是經典DDD調用序列,對上面具體的對象不是很清楚的沒關係後面有專門的示例進行全面分析。[王清培版權全部,轉載請給出署名]
模式相比你們都知道是什麼意思,一些通用的思考問題的思路、解決方法、分析方法。固然在DDD領域也有不少模式供咱們學習和使用,在需求階段講解的是行爲模式在分析階段有分析模式,在設計階段有設計模式,在實現階段有實現模式,還有宏觀的架構模式。
那麼在進行領域建模的時候有些前人總結出來的分析模式能夠供咱們參考。
四色原型模式是我接觸的第一個分析模式,固然目前也是發現它確實很好用,因此給同志們分享一下。
四色原型模式是能幫助咱們找出業務當中的核心模型,也就是說核型模式應該具有幾個比較重要的特徵的。
基本上想要根據UML用例圖找出領域模型須要使用名\動詞法找出大概的模型,而後順着領域模型一點一點完善、發掘,從而找出相關的實體模型。可是有些實體模型是一眼就能看出來的,就好比上例中的【用戶】、【訂單】、【消息】均可以定義爲實體類型,也就是當前小示例中的核心領域模型。
看一下四色原型模式的結構圖:
1.6圖
對照四色原型模式咱們很容易發現模型中的核型實體模型,很明顯對照上面的領域模型咱們確實都是核心模型。
1.7圖
對照該模式咱們會發現這裏的商品其實也是核心實體纔對,可是咱們能很快發現咱們忽視它了,商品也存在狀態和一些值類型纔對,好比商品的使用狀態是否是沒貨、商品的詳細屬性是否是也存在獨立的值對象。固然這些要看當前項目需求而定。太範式的設計會帶來一些問題,有性能問題、有開發成本問題,這些都要進行詳細的討論才能最終肯定,因此反範式設計就出現了。[王清培版權全部,轉載請給出署名]