領域模型爲解決軟件的複雜性而生。架構
人月神話說:軟件的複雜性是軟件的本質屬性之一。框架
2004年,Eric Evans寫就了《領域驅動設計——軟件核心複雜性應對之道》(注意書的副標題)oop
若是你的軟件項目有如上問題,那麼是時候考慮DDD了,若是沒,不要XJB上DDD。(不要瞎引入複雜性,DDD自己比較耗費腦子)。好比寫個代碼幾年不增長需求,別想太多,擼完就算了。測試
怎麼解決複雜性問題?9年制義務數學教育告訴咱們,不外兩種方法:抽象、分治。spa
抽象:任何一個業務問題,均可以最終簡化爲一個或者幾個基本原理的問題,這些個基本原理問題,就叫作領域問題。線程
領域問題是某一類問題的高度抽象。它關注的不是某一筆業務,某一個請求,而是全部相似的,具備同類屬性的問題,是一個通用的解決方案。設計
是一個化繁爲簡的東西。他是真正簡化問題的關鍵。對象
領域模型能不能簡化問題,關鍵要看這個。開發
分治:任何一個業務問題,經常是幾個領域的綜合。如何去肯定,區分到底劃分爲幾個領域模型部署
(依據是什麼呢?其實就是內聚和耦合)
在DDD中,形式上,它講了一大堆層次模型和六邊形模型。這些既不重要,也很重要。
不重要的是,他對於你對具體某個業務領域的抽象和分治毫無做用——這隻能依賴於你對業務的理解,依賴你的思考方式和抽象——而這,纔是DDD的核心。
重要的是,他從代碼形式上抽象了幾乎全部代碼都一定符合的結構——而且研究了代碼如何寫才更科學——這對寫出漂亮的代碼頗有幫助
舉例LInux管道命令爲啥如何靈活,如此強大
這是由於
1,抽象全部東西都是文件
2,全部文件都有輸入 ,輸出,錯誤輸出,若是沒定義,走標準輸出入
3,管道是一個定義兩個文件的之間的文件,做用是前者的的stdout做爲後者的stdin
Netty也很強大,可是也很簡單核心概念只有三個EventLoop,Channel,Handler
EventLoop定義瞭如何去調度線程和Io的方法
Channel定義了各類IO類型,能夠實現各類狀況下Nio,Upd……等Io協議
Handler是業務(線程)的抽象
能夠看到,這裏強大的根源和精髓的地方實際上是LINUX的概念抽象,和概念之間的機制做用。而和用什麼語言,用什麼框架,3層模型仍是六邊形模型,代碼寫的好很差……等因素毫無關係
抽象是DDD的精髓。六邊形,層次模型對代碼實現比較有意義
用好DDD的關鍵是
1,深入瞭解業務領域知識,瞭解業務概念,
2,根據業務模型,合理抽象建模(高度簡化問題)
3,(操做實現層面)儘可能少的引入複雜性(儘可能少引入技術框架,用最簡單的方式去解決問題)
不要在討論業務的時候就考慮技術實現
因此這裏強調一下咱們的架構原則
1,業務和技術分離
2,技術和部署分離
3,變與不變分離
QA和回答紀要
1,老徐:DDD解決複雜性
2,翠翠:DDD關鍵是抽象
3,馮昌:TDD和DDD(跑題了)
TDD是測試驅動開發,要解決的問題和DDD(複雜性)沒有關係。共通點是兩個DD。
TDD的合理性和正確性成疑,不必定是一個好的方法。這個問題後續單獨討論。
4,徐康:DDD是一種最佳實踐。
好比業界如今都怎麼搞,你們都這麼搞。
A:DDD是一種理念,而不是一種實踐。理念是完美的,實踐不必定是(舉了某project2的例子)。
而且實踐是時時刻刻在變化的,某一時完美,不表明下一時完美。要作到完美,開發人員必須有評價完美的標準——DDD,抄襲和採納——那不可能鑄就完美,由於咱們本身的業務永遠有特性。
5,刀刀:DDD和充血模型
Q:充血模型是對的,比較好的代碼都會採用這種方式,他解決了什麼問題?什麼代碼和邏輯應該放到充血模型中?
A:充血模型是對代碼微觀結構複雜度的治理。
系統劃分、模塊劃分、對象設計、領域模型、充血模型……全部這些有一個想通之處:封裝——耦合和內聚。
咱們既然強調SOA是一種宏觀結構的良好治理,DDD是一種概念領域結構的良好治理,那麼就必然認爲充血模型之一種代碼微觀結構的良好治理
那麼哪些邏輯應該放到充血模型中?
1,本身的的數據的邏輯
2,兩個模型之間的邏輯
這種邏輯兩個模型中均可以放,看誰是少方。
好比人吃肉。通常eat放人裏合適。可是若是業務是人吃肉,狗吃肉,豬吃肉……那麼eat邏輯放肉裏比較 好。
6,京其:領域劃分的依據
內聚和耦合(本質是效率和複雜度)
以訂單支付系統爲例,什麼狀況下能夠是同一個系統,什麼狀況下不能夠。
創業的時候,不少創業公司訂單和支付單是同一個。
公司業務更豐富,更多,他們就必須分開了。
分開的依據是耦合和內聚。