新聞中心
一、前言
領(lǐng)導(dǎo):為什么要使用DDD?

河北ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話(huà)聯(lián)系或者加微信:028-86922220(備注:SSL證書(shū)合作)期待與您的合作!
我也苦思冥想,怎么跟領(lǐng)導(dǎo)說(shuō)咱們從 MVC 升級(jí)到 DDD 吧,因?yàn)?DDD 代碼結(jié)構(gòu)更加清晰、領(lǐng)域驅(qū)動(dòng)比測(cè)試驅(qū)動(dòng)開(kāi)發(fā)更加先進(jìn)、研發(fā)的兄弟們也更想用用新框架等。
不過(guò)這么聊被噴一頓不說(shuō),還得說(shuō)你是過(guò)度設(shè)計(jì)瞎折騰,咋回事呢?因?yàn)闆](méi)聊到重點(diǎn)呀,你MVC升級(jí)DDD;給業(yè)務(wù)帶來(lái)了什么、提升了交付效率嗎、降低了公司研發(fā)成本嗎,都沒(méi)有?不僅沒(méi)有,你還說(shuō)為了后期的迭代維護(hù),前期會(huì)需要更多的設(shè)計(jì)和開(kāi)發(fā)時(shí)間。咋?你是想這一個(gè)Q就把我送走嗎,我剛來(lái)咱們部門(mén)KPI在那懸著,壓的我頭發(fā)都白了!別瞎搞,求穩(wěn)!
那就不搞了嗎?搞哇,不讓搞換領(lǐng)導(dǎo)!但搞之前,要考慮清楚,DDD 不是 Silver Bullet,你有一腔熱血雖好,可是也得知曉 DDD 的設(shè)計(jì)原則是什么、它更適合的場(chǎng)景是什么、與 MVC 對(duì)比有什么云泥之別。
二、開(kāi)發(fā)成本
使用 DDD 模式開(kāi)發(fā)代碼的成本到底在哪?是因?yàn)槭褂?DDD 四層分層結(jié)構(gòu)就比MVC 三層分層結(jié)構(gòu) 更浪費(fèi)時(shí)間嗎?其實(shí)并不是,因?yàn)樗膶咏Y(jié)構(gòu)相對(duì)于三層結(jié)構(gòu),反而更好的區(qū)分了代碼所屬職責(zé),在熟悉模塊功能職責(zé)后,開(kāi)發(fā)起來(lái)也會(huì)更加順暢。
那這里的 DDD 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)開(kāi)發(fā)的成本在哪呢?這個(gè)成本在于對(duì)于一個(gè)復(fù)雜系統(tǒng)又尚未在開(kāi)發(fā)前期就有非常充足的經(jīng)驗(yàn)來(lái)拆分職責(zé)邊界、劃分功能領(lǐng)域、明確編排邏輯和對(duì)未知流程擴(kuò)展的把控上,所帶來(lái)的風(fēng)暴模型設(shè)計(jì)成本。
而通常使用的 MVC 結(jié)構(gòu)基本不會(huì)出現(xiàn)這樣的問(wèn)題,因?yàn)樵趯?shí)際的代碼中,DAO、PO、VO等都是共用的,大家在開(kāi)發(fā)代碼的時(shí)候,像堆泥球一樣面向過(guò)程寫(xiě)代碼,直接串聯(lián)出產(chǎn)品的PRD功能節(jié)點(diǎn)即可,不用過(guò)多的思考解耦和內(nèi)聚。
那不是可以設(shè)計(jì)模式嗎,這就需要看你是站在哪個(gè)維度去思考問(wèn)題。設(shè)計(jì)模式在這里是戰(zhàn)術(shù)問(wèn)題的,DDD和MVC是確定戰(zhàn)略問(wèn)題的,有點(diǎn)像是說(shuō):“方向不對(duì),努力白費(fèi)一樣”
那么現(xiàn)在我們?cè)賮?lái)看這條開(kāi)發(fā)成本曲線(xiàn):
架構(gòu)模式,開(kāi)發(fā)成本曲線(xiàn)
- 與其他兩種分層結(jié)構(gòu)相對(duì)比,使用 DDD 的時(shí)候,需要在前期投入較多的時(shí)間成本來(lái)設(shè)計(jì)領(lǐng)域建模,所以前期成本會(huì)更高一些。
- 但隨著業(yè)務(wù)不斷迭代后的邏輯的復(fù)雜性增加,DDD 系統(tǒng)架構(gòu)所開(kāi)發(fā)的代碼穩(wěn)定性會(huì)更好,也就說(shuō)明 DDD 更容易擴(kuò)容和維護(hù)。
- 所以框架結(jié)構(gòu)的更換,不是最終增加開(kāi)發(fā)成本的地方,如果你不做領(lǐng)域建模也不做更多的設(shè)計(jì)思考,那么即使是 DDD 的四層架構(gòu),也能讓你寫(xiě)出 MVC 的效果。而那些對(duì)業(yè)務(wù)場(chǎng)景經(jīng)驗(yàn)豐富的架構(gòu)師或者研發(fā)人員,已經(jīng)非常明確了各個(gè)業(yè)務(wù)功能的職責(zé)邊界,要實(shí)現(xiàn)一個(gè)系統(tǒng)需求需要完成哪些核心領(lǐng)域服務(wù),在這樣的情況用 DDD 也不會(huì)帶來(lái)多少開(kāi)發(fā)成本,反而更加游刃有余了!這就是為什么說(shuō),需要領(lǐng)域?qū)<?,因?yàn)閷?zhuān)家已經(jīng)積累了很多的戰(zhàn)略設(shè)計(jì)經(jīng)驗(yàn)
- 此外使用 DDD 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的模式進(jìn)行開(kāi)發(fā),除了解決需求的迭代成本,更多的時(shí)候是要面對(duì)公司戰(zhàn)略調(diào)整后,系統(tǒng)的交接、人員的更替和新增,都要在原有的工程架構(gòu)下繼續(xù)迭代開(kāi)發(fā),否則就要推翻重新做,那樣所面臨的更替成本將更大,同時(shí)又是開(kāi)發(fā)了一個(gè)與人員綁定不易于交接維護(hù)的工程代碼。
三、架構(gòu)對(duì)比
在了解和掌握 DDD 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的路上,你一定會(huì)碰到兩個(gè)抽象的釘子 —— “貧血模型”、“充血模型”:
貧血模型:事務(wù)腳本模式,最早起源于 EJB2,到 Spring 進(jìn)入開(kāi)“春”盛世。
充血模型:領(lǐng)域模型模式,2003年提出,一直到《實(shí)現(xiàn)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)》的問(wèn)世,才開(kāi)啟了 DDD 的大門(mén)。但國(guó)內(nèi)直到微服務(wù)、低代碼的興起,才開(kāi)始 DDD 熱
1. MVC
MVC 分層結(jié)構(gòu)將:“狀態(tài)”(數(shù)據(jù),成員對(duì)象)、“行為“(邏輯、過(guò)程),分離到不同的對(duì)象中,只有狀態(tài)的對(duì)象(VO -> Value Object) 被稱(chēng)為貧血模型,只有行為的對(duì)象,就是框架分層中常見(jiàn)的Logic/Service/Manager層(對(duì)應(yīng)到EJB2中的Stateless Session Bean)
MVC 分層結(jié)構(gòu)
- 以應(yīng)用層 Service 使用 DAO、PO 基礎(chǔ)設(shè)施包裝業(yè)務(wù)邏輯的開(kāi)發(fā)方式,乍一看以為應(yīng)用層是在對(duì)領(lǐng)域建模的實(shí)現(xiàn),”領(lǐng)域?qū)印坝兄S富的對(duì)象鏈接,和真正的領(lǐng)域模型也非常類(lèi)似,但當(dāng)我們代碼隨著業(yè)務(wù)功能邏輯的逐步實(shí)現(xiàn)中會(huì)慢慢發(fā)現(xiàn),我們寫(xiě)了一堆的 get/set 對(duì)象,而他們被反復(fù)交叉使用,沒(méi)有與任何領(lǐng)域聚合,也就是不具有任何的行為動(dòng)作,只是一堆貧血模型對(duì)象。
- 這種反模式的設(shè)計(jì),其實(shí)完全與面向?qū)ο蟮脑O(shè)計(jì)是背道而馳的,面向?qū)ο蟮脑O(shè)計(jì)更希望行為和數(shù)據(jù)綁定在一起,與之對(duì)比的貧血模型更像是面向過(guò)程設(shè)計(jì)。
- 在 MVC 分層結(jié)構(gòu)下,所有的行為都被寫(xiě)入到 Service 對(duì)象中,最終你會(huì)得到一組事務(wù)處理的過(guò)程腳本,從而完美的避開(kāi)了領(lǐng)域模型設(shè)計(jì)所帶來(lái)的好處(清晰的職責(zé)邊界、聚合的功能服務(wù)、清晰的面向?qū)ο?。
2. DDD
DDD 的分層結(jié)構(gòu)也是面向?qū)ο缶幊痰谋举|(zhì):”一個(gè)對(duì)象擁有行為和數(shù)據(jù)“,在領(lǐng)域?qū)影耍簩?duì)象、聚合對(duì)象、倉(cāng)儲(chǔ)和Service實(shí)現(xiàn)。
DDD 分層結(jié)構(gòu)
- DDD 的分層結(jié)構(gòu)更注重 Domain 領(lǐng)域?qū)拥膶?shí)現(xiàn),由很薄的應(yīng)用層定義接口和編排接口,由領(lǐng)域?qū)幼鼍唧w的實(shí)現(xiàn)。
- 所有的業(yè)務(wù)邏輯都按照各自的職責(zé)邊界拆分成一塊塊的功能領(lǐng)域,每一個(gè)功能領(lǐng)域都是充血模型的結(jié)構(gòu)的具體實(shí)現(xiàn)。
- 那么這樣的代碼最終實(shí)現(xiàn)以后,無(wú)論在迭代、維護(hù)、人員更替,都能很好按照領(lǐng)域設(shè)計(jì)文檔找到對(duì)應(yīng)的代碼實(shí)現(xiàn)進(jìn)行開(kāi)發(fā)。
四、設(shè)計(jì)原則
首先 DDD 的設(shè)計(jì)分為戰(zhàn)略和戰(zhàn)術(shù);
- 戰(zhàn)略設(shè)計(jì):從業(yè)務(wù)視角出發(fā),建立業(yè)務(wù)領(lǐng)域模型、劃分職責(zé)邊界,建立通用語(yǔ)言的界限上下文。頂層戰(zhàn)略設(shè)計(jì)構(gòu)建的領(lǐng)域模型結(jié)構(gòu),是整個(gè)服務(wù)后期編排的重點(diǎn),它確定了功能的職責(zé)邊界、聚合、對(duì)象等,也就決定了后期服務(wù)戰(zhàn)術(shù)實(shí)現(xiàn)的開(kāi)發(fā)和交付質(zhì)量。重視戰(zhàn)略,才能落地好戰(zhàn)術(shù)!
- 戰(zhàn)術(shù)設(shè)計(jì):從技術(shù)視角出發(fā),側(cè)重于領(lǐng)域模型的技術(shù)實(shí)現(xiàn),完成功能開(kāi)發(fā)和交付落地。領(lǐng)域設(shè)計(jì)的重點(diǎn)包括:實(shí)體、聚合對(duì)象、值對(duì)象、領(lǐng)域服務(wù)、倉(cāng)儲(chǔ),還有一個(gè)非常重點(diǎn)的設(shè)計(jì)模式。任何一個(gè)較為復(fù)雜的領(lǐng)域模型實(shí)現(xiàn)都需要考慮設(shè)計(jì)模式的使用,否則即使戰(zhàn)略?xún)?yōu)秀,戰(zhàn)術(shù)也能干回 MVC 去。
在以DDD領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)落地的過(guò)程中,要依靠領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的設(shè)計(jì)思想,通過(guò)事件風(fēng)暴建立領(lǐng)域模型,合理劃分領(lǐng)域邏輯和物理邊界,建立領(lǐng)域?qū)ο蠹胺?wù)矩陣和服務(wù)架構(gòu)圖,定義符合DDD分層架構(gòu)思想的代碼結(jié)構(gòu)模型,保證業(yè)務(wù)模型與代碼模型的一致性。通過(guò)上述設(shè)計(jì)思想、方法和過(guò)程,指導(dǎo)團(tuán)隊(duì)按照DDD設(shè)計(jì)思想完成微服務(wù)設(shè)計(jì)和開(kāi)發(fā)。
拒絕泥球小單體、拒絕污染功能與服務(wù)、拒絕加功能排期一個(gè)月
架構(gòu)出高可用極易符合互聯(lián)網(wǎng)高速迭代的應(yīng)用服務(wù)
物料化、組裝化、可編排的服務(wù),提高人效
要領(lǐng)域驅(qū)動(dòng)設(shè)計(jì),而不是數(shù)據(jù)驅(qū)動(dòng)設(shè)計(jì),也不是界面驅(qū)動(dòng)設(shè)計(jì)
要職能清晰的分層,而不是什么都放的大籮筐
DDD 的領(lǐng)域模型設(shè)計(jì),界限內(nèi)的上下文,可以拆分為獨(dú)立的微服務(wù)。但不僅要從業(yè)務(wù)視角看問(wèn)題,也要考慮非業(yè)務(wù)的技術(shù)因素,包括:高性能、安全、團(tuán)隊(duì)、技術(shù)異構(gòu)等,這些非業(yè)務(wù)的技術(shù)因素,也會(huì)決定領(lǐng)域模型落地的具體落地。
五、舉個(gè)例子
你說(shuō)我 MVC 不好,你說(shuō)我 MVC 貧血模型,PO 類(lèi)不斷的膨脹,但讓我用 DDD 又都是理論,程序員更喜歡看的是已經(jīng)落地的代碼,告訴我怎么干。
為什么這么難落地呢?因?yàn)閺?MVC 過(guò)度到 DDD 描述對(duì)比只是積累了 MVC 失敗的教訓(xùn),但沒(méi)有 DDD 成功的經(jīng)驗(yàn),所以更多的時(shí)候想落地 DDD 除了有理論支撐,更需要一份案例擺在面前。
1. 工程結(jié)構(gòu)
所以為了讓更多的碼農(nóng)看到在 DDD 上一條能走的路,專(zhuān)門(mén)折騰了個(gè) DDD 分布式抽獎(jiǎng)系統(tǒng),來(lái)告訴大家怎么使用 DDD 開(kāi)發(fā)業(yè)務(wù)需求;
DDD 分布式抽獎(jiǎng)系統(tǒng),工程分布
整體系統(tǒng)架構(gòu)設(shè)計(jì)包含了6個(gè)工程:
- Lottery:分布式部署的抽獎(jiǎng)服務(wù)系統(tǒng),提供抽獎(jiǎng)業(yè)務(wù)領(lǐng)域功能,以分布式部署的方式提供 RPC 服務(wù)。
- Lottery-API:網(wǎng)關(guān)API服務(wù),提供;H5 頁(yè)面抽獎(jiǎng)、公眾號(hào)開(kāi)發(fā)回復(fù)消息抽獎(jiǎng)。
- Lottery-Front:C端用戶(hù)系統(tǒng),vue H5 lucky-canvas 大轉(zhuǎn)盤(pán)抽獎(jiǎng)界面,講解 vue 工程創(chuàng)建、引入模塊、開(kāi)發(fā)接口、跨域訪問(wèn)和功能實(shí)現(xiàn)
- Lottery-ERP:B端運(yùn)營(yíng)系統(tǒng),滿(mǎn)足運(yùn)營(yíng)人員對(duì)于活動(dòng)的查詢(xún)、配置、修改、審核等操作。
- DB-Router:分庫(kù)分表路由組件,開(kāi)發(fā)一個(gè)基于 HashMap 核心設(shè)計(jì)原理,使用哈希散列+擾動(dòng)函數(shù)的方式,把數(shù)據(jù)散列到多個(gè)庫(kù)表中的組件,并驗(yàn)證使用。
- Lottery-Test:測(cè)試驗(yàn)證系統(tǒng),用于測(cè)試驗(yàn)證RPC服務(wù)、系統(tǒng)功能調(diào)用的測(cè)試系統(tǒng)。
2. 流程拆解
當(dāng)我們拿到產(chǎn)品的 RPD 以后,并不是直接上手開(kāi)發(fā),而是需要從流程中拆解出一份面向?qū)ο笤O(shè)計(jì)的領(lǐng)域服務(wù),舉例;
DDD 分布式抽獎(jiǎng)系統(tǒng),流程拆解
- 拆解功能流程,提煉領(lǐng)域服務(wù),一步步教會(huì)你把一個(gè)業(yè)務(wù)功能流程如何拆解為各個(gè)職責(zé)邊界下的領(lǐng)域模塊,在通過(guò)把開(kāi)發(fā)好的領(lǐng)域服務(wù)在應(yīng)用層進(jìn)行串聯(lián),提供整個(gè)服務(wù)鏈路。
- 通過(guò)這樣的設(shè)計(jì)和落地思想,以及在把流程化的功能按照面向?qū)ο蟮乃悸肥褂迷O(shè)計(jì)模式進(jìn)行設(shè)計(jì),讓每一步代碼都變得清晰易懂,這樣實(shí)現(xiàn)出來(lái)的代碼也就更加易于維護(hù)和擴(kuò)展了。
- 所以,你在這個(gè)過(guò)程中學(xué)會(huì)的不只是代碼開(kāi)發(fā),還有更多的落地思想實(shí)踐在這里面體現(xiàn)出來(lái)。也能為你以后開(kāi)發(fā)這樣的一個(gè)項(xiàng)目或者在面試過(guò)程中,一些實(shí)際復(fù)雜場(chǎng)景問(wèn)題的設(shè)計(jì)思路,打下不錯(cuò)的基礎(chǔ)。
網(wǎng)站欄目:怎么說(shuō)服領(lǐng)導(dǎo),能讓我用DDD架構(gòu)?
網(wǎng)頁(yè)鏈接:http://m.5511xx.com/article/djcegeo.html


咨詢(xún)
建站咨詢(xún)
