mvc是一種軟件設計模式,最先由Trygve Reenskaug在1978年提出,他有效的解決了表示層,控制器層,邏輯層的代碼混合在一塊兒的問題,很好的作到了職責分離。可是在實際的編碼實踐過程當中,你會發現這個模式隨着業務的擴展,變的邏輯混亂,代碼重合度很高。這裏提出借鑑DDD思想的一種新的工程結構html
一般一個先後端分離的系統,後端工程系統結構圖一般下面這樣
前端
1. 四層 controller/service/manager/mapper 2. 不能夠同級調用 3. 上級能夠知曉下級,下級不可知曉上級,也就是bean的轉化放在上級
這個分層結構職責分離是按照縱向切分的程序員
1. 資源服務層repository是面向DB編程 2. service層是面向前端頁面編程。
也就是說,對於某一塊的業務,他沒有將邏輯抽象到一塊兒,他只是將一次request按照縱向切分了。沒有進行橫向的業務切分。
這樣將會致使的問題
職責分散,邏輯重複度高面試
沒有邊界算法
按照上述的說明,在一個單體服務中,隨着業務的不斷迭代,可能會發生什麼嚴重的問題。數據庫
舉幾個真實鮮活的例子編程
分庫分表的例子
實體A是咱們業務中的一個基礎的重要的實體,對應的數據表tableA,一開始業務很簡單,只有1個服務,在這個服務裏面調用。後來業務擴張了,有十幾個服務了,而後十幾個服務直接查這個tableA。tableA也擴張成爲了tableA,tableB,tableC。有些人以爲代碼重複度高了,將mapper/manager層拆成共通的部分打成一個jar包,而後各個微服務中引入這個jar。業務變得更加複雜了,服務擴展到幾十個了,tableA數據也有幾千萬了,這時候要作分庫分表了,怎麼整。後端
最後花了差很少1年,涉及十幾個團隊,才把這個mapper/manager調用改掉,而後作分庫分表。設計模式
有人可能以爲這個只要在服務拆分時,避免直接調用就能夠了,那再舉個其餘類型的例子。架構
用戶等級的例子
用戶的等級,用戶的分級是很複雜的,不一樣的業務階段有這個不一樣的定義。好比一開始定義一個字段叫grade的表明用戶等級。
而後各個業務都在查這個表的字段grade進行判斷,而後產品須要改了,增長了判斷必須同時要達到什麼條件才能稱做等級x。這時候你又得滿世界的改了。
那如何運用DDD的思想進行改造呢
核心思想:封裝領域內的邏輯,統一對外暴露的入口,防止業務邏輯泄露。
上面的只是一個草圖,咱們真實的結構圖比這要稍微複雜些。領域內會區分領域對象,領域服務,基礎設施層。這樣在領域內進行指責分離,不過從實際的執行過程當中領域內的比較細節,執行起來ROI比較低,推薦你們能夠先按這套執行。
畫外音:估計有些程序員看到這個工程結構變化呵呵一笑,以爲沒多大價值,沒什麼改變必要。
這種工程的結構劃分從提出來的到真正被咱們團隊成員接受的時間週期差很少是8個月。
緣由大概是這麼幾類
- 引入新的分層,太複雜了,增長了代碼複雜度
- 我這塊業務很簡單,CRUD就好了,沒涉及到服務之間的交互。直接mvc一條道走到黑就能夠。
若是你看這篇文章也是這種感覺,不妨花點時間看下大家業務的代碼,看看重複度有多高,看看邏輯有多散亂。你就會明白。
DDD工程的演進也就是服務的拆分了,放到下期講。
不少DDD的文章都在說傳統的編程方式是面試數據庫編程,致使對象中只有getter,setter,也就是貧血模型,貧血模型是沒有業務邏輯,面向過程設計,不符合面向對象設計原則。
對於這個結論我是贊成的,可是對於形成的緣由不是很贊成。我的認爲形成這個緣由的主要緣由仍是在於長期以來的MVC這種模式只有縱向切分致使。若是結合橫向切分,有沒有DDD也無所謂。這裏再引用一下驅動方法不能改變任何事情這段話,若是你能深刻理解職責、封裝。並隨着業務的迭代,不斷的重構你的代碼,那麼你不須要什麼DDD,或者其餘方法論。
使用職責、封裝和組合;
以接口的視角思考,即「人們如何使用個人組件?」;
使用相關技術寫好代碼,包括可讀性、信息性、簡潔、自描述,儘可能避免顯式地使用模式;
有能力回答特定業務的「本質」;「本質」是一個模型,但不意味着類和方法,它意味着回答問題「這個業務如何真正地工做?」
由於這些約束,都是強迫你去思考,去作職責的思考,去作模塊的封裝。若是你/你團隊成員已經領會其中的道理並很好的運用,還須要這些條條框框幹嘛呢?
下一篇領域與微服務劃分,欲知後事如何,請聽下回分解。
相關閱讀
http://www.javashuo.com/article/p-ogvnstav-md.html
關注【方丈的寺院】,第一時間收到文章的更新,與方丈一塊兒開始技術修行之路