摘要:的演進按照上述的說明,在一個單體服務(wù)中,隨著業(yè)務(wù)的不斷迭代,可能會發(fā)生什么嚴重的問題。個人認為造成這個原因的主要原因還是在于長期以來的這種模式只有縱向切分導(dǎo)致。
摘要mvc是一種軟件設(shè)計模式,最早由Trygve Reenskaug在1978年提出,他有效的解決了表示層,控制器層,邏輯層的代碼混合在一起的問題,很好的做到了職責(zé)分離。但是在實際的編碼實踐過程中,你會發(fā)現(xiàn)這個模式隨著業(yè)務(wù)的擴展,變的邏輯混亂,代碼重合度很高。這里提出借鑒DDD思想的一種新的工程結(jié)構(gòu)
mvc的問題通常一個前后端分離的系統(tǒng),后端工程系統(tǒng)結(jié)構(gòu)圖通常下面這樣
1. 四層 controller/service/manager/mapper 2. 不可以同級調(diào)用 3. 上級可以知曉下級,下級不可知曉上級,也就是bean的轉(zhuǎn)化放在上級
這個分層結(jié)構(gòu)職責(zé)分離是按照縱向切分的
1. 資源服務(wù)層repository是面向DB編程 2. service層是面向前端頁面編程。
也就是說,對于某一塊的業(yè)務(wù),他沒有將邏輯抽象到一起,他只是將一次request按照縱向切分了。沒有進行橫向的業(yè)務(wù)切分。 這樣將會導(dǎo)致的問題 職責(zé)分散,邏輯重復(fù)度高
bean的創(chuàng)建太隨意,基本就是一個需求對應(yīng)一些dto, vo,query bean
不同開發(fā)者對于同一個領(lǐng)域的東西有不同的bean,同一個開發(fā)者對于相同邏輯的bean,過了幾個月,又定義出一個差不多的bean
沒有邊界
根本沒有上下文/邊界的概念,比如說店鋪會和用戶有交互,訂單會和用戶有交互,通常在DB存儲時只會存關(guān)聯(lián)id,然后需要去取對應(yīng)的名稱,其他屬性信息。這些信息的獲取,有些開發(fā)在manager層操作,然后將屬性定義到了店鋪相關(guān)的DTO中;有些放在了service層做。controller/service/manager各個層次都可以調(diào)用,沒有任何約束。
mvc的演進按照上述的說明,在一個單體服務(wù)中,隨著業(yè)務(wù)的不斷迭代,可能會發(fā)生什么嚴重的問題。
舉幾個真實鮮活的例子
分庫分表的例子 實體A是我們業(yè)務(wù)中的一個基礎(chǔ)的重要的實體,對應(yīng)的數(shù)據(jù)表tableA,一開始業(yè)務(wù)很簡單,只有1個服務(wù),在這個服務(wù)里面調(diào)用。后來業(yè)務(wù)擴張了,有十幾個服務(wù)了,然后十幾個服務(wù)直接查這個tableA。tableA也擴張成為了tableA,tableB,tableC。有些人覺得代碼重復(fù)度高了,將mapper/manager層拆成共通的部分打成一個jar包,然后各個微服務(wù)中引入這個jar。業(yè)務(wù)變得更加復(fù)雜了,服務(wù)擴展到幾十個了,tableA數(shù)據(jù)也有幾千萬了,這時候要做分庫分表了,怎么整。
最后花了差不多1年,涉及十幾個團隊,才把這個mapper/manager調(diào)用改掉,然后做分庫分表。
有人可能覺得這個只要在服務(wù)拆分時,避免直接調(diào)用就可以了,那再舉個其他類型的例子。
用戶等級的例子
用戶的等級,用戶的分級是很復(fù)雜的,不同的業(yè)務(wù)階段有這個不同的定義。比如一開始定義一個字段叫g(shù)rade的代表用戶等級。 然后各個業(yè)務(wù)都在查這個表的字段grade進行判斷,然后產(chǎn)品需要改了,增加了判斷必須同時要達到什么條件才能稱作等級x。這時候你又得滿世界的改了。
DDD的工程架構(gòu)那如何運用DDD的思想進行改造呢 核心思想:封裝領(lǐng)域內(nèi)的邏輯,統(tǒng)一對外暴露的入口,防止業(yè)務(wù)邏輯泄露。
在mvc縱向切分的基礎(chǔ)上,增加一層領(lǐng)域的橫向切分
同一個工程里面,領(lǐng)域之間的調(diào)用只能通過domainService,這樣可以屏蔽領(lǐng)域內(nèi)的數(shù)據(jù)庫是如何持久化的,業(yè)務(wù)邏輯是如何判斷的、算法是如何實現(xiàn)的。 service之間可以直接調(diào)用。
領(lǐng)域內(nèi)還是縱向切分,安裝mvc分層結(jié)構(gòu)。
上面的只是一個草圖,我們真實的結(jié)構(gòu)圖比這要稍微復(fù)雜些。領(lǐng)域內(nèi)會區(qū)分領(lǐng)域?qū)ο?,領(lǐng)域服務(wù),基礎(chǔ)設(shè)施層。這樣在領(lǐng)域內(nèi)進行指責(zé)分離,不過從實際的執(zhí)行過程中領(lǐng)域內(nèi)的比較細節(jié),執(zhí)行起來ROI比較低,推薦大家可以先按這套執(zhí)行。
畫外音:估計有些程序員看到這個工程結(jié)構(gòu)變化呵呵一笑,覺得沒多大價值,沒什么改變必要。
這種工程的結(jié)構(gòu)劃分從提出來的到真正被我們團隊成員接受的時間周期差不多是8個月。 原因大概是這么幾類
引入新的分層,太復(fù)雜了,增加了代碼復(fù)雜度
我這塊業(yè)務(wù)很簡單,CRUD就行了,沒涉及到服務(wù)之間的交互。直接mvc一條道走到黑就可以。
如果你看這篇文章也是這種感受,不妨花點時間看下你們業(yè)務(wù)的代碼,看看重復(fù)度有多高,看看邏輯有多散亂。你就會明白。
DDD工程的演進DDD工程的演進也就是服務(wù)的拆分了,放到下期講。
總結(jié)很多DDD的文章都在說傳統(tǒng)的編程方式是面試數(shù)據(jù)庫編程,導(dǎo)致對象中只有g(shù)etter,setter,也就是貧血模型,貧血模型是沒有業(yè)務(wù)邏輯,面向過程設(shè)計,不符合面向?qū)ο笤O(shè)計原則。
對于這個結(jié)論我是同意的,但是對于造成的原因不是很同意。個人認為造成這個原因的主要原因還是在于長期以來的MVC這種模式只有縱向切分導(dǎo)致。如果結(jié)合橫向切分,有沒有DDD也無所謂。這里再引用一下驅(qū)動方法不能改變?nèi)魏问虑檫@段話,如果你能深入理解職責(zé)、封裝。并隨著業(yè)務(wù)的迭代,不斷的重構(gòu)你的代碼,那么你不需要什么DDD,或者其他方法論。
使用職責(zé)、封裝和組合; 以接口的視角思考,即“人們?nèi)绾问褂梦业慕M件?”; 使用相關(guān)技術(shù)寫好代碼,包括可讀性、信息性、簡潔、自描述,盡量避免顯式地使用模式; 有能力回答特定業(yè)務(wù)的“本質(zhì)”;“本質(zhì)”是一個模型,但不意味著類和方法,它意味著回答問題“這個業(yè)務(wù)如何真正地工作?”
因為這些約束,都是強迫你去思考,去做職責(zé)的思考,去做模塊的封裝。如果你/你團隊成員已經(jīng)領(lǐng)會其中的道理并很好的運用,還需要這些條條框框干嗎呢?
下一篇領(lǐng)域與微服務(wù)劃分,欲知后事如何,請聽下回分解。
相關(guān)閱讀
可落地的DDD(1)-目標討論
關(guān)注【方丈的寺院】,第一時間收到文章的更新,與方丈一起開始技術(shù)修行之路
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/6882.html
摘要:中的事件的一個,我暫且理解為一個中的和這兩個屬性已經(jīng)在框架中直接掛載在了對象上,歸功于曾老師。 CQRS是啥?DDD又是啥? 這兩個概念其實沒什么神秘的,當然此文章中的這兩個概念以曾老師的課程為準(關(guān)于CQRS和DDD的標準概念,google上已經(jīng)很多了,不再贅述。) DDD(Domain Driven Design),領(lǐng)域驅(qū)動設(shè)計開發(fā)。 DDD和OOP有什么同嗎?其實就我個人經(jīng)驗來說...
摘要:最近發(fā)現(xiàn)文章老是被竊取,有些平臺舉報了還沒有用。最后不了了之,產(chǎn)品很配合,但是內(nèi)驅(qū)力不強。為什么內(nèi)驅(qū)力不強,因為給他帶來的收益不夠。所以在千個團隊中實行可能有千套不同的方案。最近發(fā)現(xiàn)文章老是被竊取,有些平臺舉報了還沒有用。請識別我的id方丈的寺院。 摘要 DDD領(lǐng)域驅(qū)動設(shè)計,起源于2004年著名建模專家Eric Evans發(fā)表的他最具影響力的著名書籍:Domain-Driven Design...
摘要:作者小傅哥博客沉淀分享成長,讓自己和他人都能有所收獲接下來還需要把我們創(chuàng)建的工程模板以及數(shù)據(jù)服務(wù)配置到中,這樣在插件啟動的時候就可以把我們自己插件啟動起來了。作者:小傅哥博客:https://bugstack.cn沉淀、分享、成長,讓自己和他人都能有所收獲!???? 接下來還需要把我們創(chuàng)建的工程模板以及數(shù)據(jù)服務(wù)配置到 plugin.xml 中,這樣在插件啟動的時候就可以...
摘要:問題來了,我們到底還在用嗎答案是,不全用。后者是初始化的配置,主要是的配置。啟動類測試啟動項目后,在瀏覽器里面輸入。通過查詢已裝載的,并且支持該而獲取的。按照前面對的描述,對于而言,這個必定是。的核心在的方法中。 之前已經(jīng)分析過了Spring的IOC(《零基礎(chǔ)帶你看Spring源碼——IOC控制反轉(zhuǎn)》)與AOP(《從源碼入手,一文帶你讀懂Spring AOP面向切面編程》)的源碼,本次...
摘要:而程序員和醫(yī)生律師的不同點在于持續(xù)學(xué)習(xí)上。兩個小問題是需要收費,一年大概刀圖書都是英文的。的視頻基本都有英文字幕,配合作者的,英語不好的同學(xué)學(xué)習(xí)也沒有問題。英文好的有技術(shù)功底的同學(xué)多發(fā)表一些觀點,其他的同學(xué)都 摘要: 行業(yè)發(fā)展得太快,你必須學(xué)習(xí),純靠經(jīng)驗積累行不通,技術(shù)淘汰的速度遠大于你經(jīng)驗積累的速度。 非雞湯:不要和程序員談自己的編程歷史,很多的經(jīng)驗在今天已經(jīng)不適用了。只要2-3年...
閱讀 2491·2021-10-09 09:59
閱讀 2271·2021-09-23 11:30
閱讀 2661·2019-08-30 15:56
閱讀 1204·2019-08-30 14:00
閱讀 3004·2019-08-29 12:37
閱讀 1327·2019-08-28 18:16
閱讀 1713·2019-08-27 10:56
閱讀 1085·2019-08-26 17:23