DDD早在2004年就由埃里克·埃文斯提出,但一直處于不溫不火的狀態(tài),直到微服務(wù)盛行之后,DDD再次回到人們視野之中。京東、美團(tuán)、華為等巨頭也都在自家架構(gòu)中實(shí)踐了DDD。
DDD究竟有什么優(yōu)勢?它是如何落地的?實(shí)施難點(diǎn)又在哪里?結(jié)合惟客數(shù)據(jù)實(shí)踐DDD的經(jīng)驗(yàn),今天就來一起探討下。
咱們先從一個場景說起。
通常在研發(fā)流程中,需求評審?fù)戤吅缶徒挥赡硞€研發(fā)做設(shè)計(jì),方案的設(shè)計(jì)完全取決于某個人的經(jīng)驗(yàn)和對依賴模塊的熟悉程度,可能很難識別出模塊設(shè)計(jì)上的不合理。即使可以識別出,往往都會以技術(shù)的語言和產(chǎn)品經(jīng)理進(jìn)行溝通,產(chǎn)品經(jīng)理可能很難理解,最終難達(dá)到預(yù)期的目的。
以惟客服務(wù)過的某地產(chǎn)集團(tuán)案例為例??蛻舻脑V求是實(shí)現(xiàn)“轉(zhuǎn)贈功能”,比如用戶A下單5件商品,將其中2件轉(zhuǎn)贈給用戶B,此時用戶B的“我的訂單”欄會出現(xiàn)一筆含有2件商品的訂單,且不可退款的同時,用戶B還可以再次實(shí)行轉(zhuǎn)贈。
這意味著需要在訂單領(lǐng)域生成一種“特殊的訂單”和“特殊的拆單”,該訂單僅能使用且不能退款。
需求評審?fù)旰螅a(chǎn)品、研發(fā)一起開始做“領(lǐng)域建模”,由于涉及訂單領(lǐng)域,也對照之前的“訂單模型圖”做了方案的設(shè)計(jì),發(fā)現(xiàn)訂單域承載更多的是交易相關(guān),把轉(zhuǎn)贈業(yè)務(wù)耦合進(jìn)來,十分困難。
但研發(fā)在模型圖里發(fā)現(xiàn)了專門承載履約的“核銷聚合根”,只要核銷權(quán)限能轉(zhuǎn)出去,就可以滿足業(yè)務(wù)場景,產(chǎn)品經(jīng)理也十分認(rèn)可,最終將產(chǎn)品做了修改,將原先的訂單轉(zhuǎn)送,變?yōu)榱寺募s權(quán)限的轉(zhuǎn)贈。
在上面的案例中,無論從產(chǎn)品設(shè)計(jì)角度,還是轉(zhuǎn)贈場景和交易場景,劃分都更清晰;從代碼設(shè)計(jì)角度,減少沖擊到訂單域,避免現(xiàn)實(shí)中獨(dú)立的兩塊業(yè)務(wù)在系統(tǒng)中耦合成一個模塊,從而造成訂單的核心代碼被沖擊,后續(xù)難維護(hù)的后果。最終實(shí)現(xiàn)了“多贏”的局面。
這種“多贏”的局面,就取決于DDD過程中帶給我們的幾點(diǎn)改變:
1、領(lǐng)域模型設(shè)計(jì)一定程度上拉齊了團(tuán)隊(duì)的設(shè)計(jì)水平,不再取決于某幾個人的“經(jīng)驗(yàn)”。
2、產(chǎn)品、研發(fā)建模的過程中,深究業(yè)務(wù)場景,推導(dǎo)出技術(shù)設(shè)計(jì)的同時也回補(bǔ)了需求漏洞。
3、團(tuán)隊(duì)內(nèi)統(tǒng)一語言,尤其是產(chǎn)品和研發(fā)之間,溝通成本低,減少了由于理解差異導(dǎo)致的風(fēng)險(xiǎn)。
4、原先依賴的模塊,也采用了DDD的設(shè)計(jì),有完整的模型文檔,并且有效識別出來了“訂單聚合”、“核銷聚合”,才使得轉(zhuǎn)贈模塊在做設(shè)計(jì)有了很好的基礎(chǔ)。
基于對以上場景的了解,我們再回歸定義,從定義出發(fā),一步步拆解。
概念理解:DDD是什么?
DDD全稱是領(lǐng)域驅(qū)動設(shè)計(jì),這里的“領(lǐng)域”可以理解為業(yè)務(wù)邊界,以及指定范圍內(nèi)待解決的業(yè)務(wù)問題。因此DDD它不是一種架構(gòu),而是一套思想,是一種拆解業(yè)務(wù)、劃分業(yè)務(wù)、確定業(yè)務(wù)邊界的方法。
DDD可以通過合理運(yùn)用面向?qū)ο蟮姆庋b、繼承、多態(tài)等設(shè)計(jì)要素,降低或隱藏整個系統(tǒng)的業(yè)務(wù)復(fù)雜性,幫助我們設(shè)計(jì)出清晰的領(lǐng)域和邊界,并使得系統(tǒng)具有更好的擴(kuò)展性,很好的實(shí)現(xiàn)技術(shù)架構(gòu)的演進(jìn),應(yīng)對紛繁多變的現(xiàn)實(shí)業(yè)務(wù)問題。
DDD的優(yōu)勢在哪里?
程序員擅長從技術(shù)角度來解決項(xiàng)目問題。但一個軟件系統(tǒng)是否真正可用,需要通過其提供的業(yè)務(wù)價(jià)值來體現(xiàn)。因此在關(guān)注技術(shù)的同時,DDD更強(qiáng)調(diào)將關(guān)注點(diǎn)轉(zhuǎn)向軟件系統(tǒng)所提供的業(yè)務(wù)價(jià)值。
我們先回顧下產(chǎn)研團(tuán)隊(duì)的協(xié)作模式,通常是將一個產(chǎn)品開發(fā)上線的各個過程拆出來,由市場/運(yùn)營、產(chǎn)品、UI交互、前端、后端、測試等角色來做分工,每個過程專人負(fù)責(zé)。
這么做的好處是標(biāo)準(zhǔn)流水線作業(yè),個體生產(chǎn)效率比較高,但壞處是大家都盯著眼前的一畝三分地,自然很容易忽略整體,更難從整體業(yè)務(wù)價(jià)值出發(fā)。同時也容易出現(xiàn)信息不對稱的問題,比如產(chǎn)品在討論A時,前端以為是說B。
那么,根據(jù)惟客數(shù)據(jù)在核心產(chǎn)品“惟客云”中實(shí)踐DDD的經(jīng)驗(yàn)總結(jié),其優(yōu)勢可以包含以下幾點(diǎn):
統(tǒng)一語言:領(lǐng)域?qū)<摇a(chǎn)品、技術(shù)、測試等人員都在一起進(jìn)行事件風(fēng)暴(整理出相關(guān)聯(lián)的業(yè)務(wù)指令和事件),在同一個場景下使用統(tǒng)一語言進(jìn)行領(lǐng)域模型構(gòu)建,信息傳遞不會丟失。
提高效率:設(shè)計(jì)就是代碼、代碼就是設(shè)計(jì),可以根據(jù)領(lǐng)域模型圖對編輯進(jìn)行翻譯,即使是新人接手也能快速理解整個業(yè)務(wù)和代碼,上手就能寫。
邊界清晰:戰(zhàn)略設(shè)計(jì)幫助產(chǎn)品決策人理解哪些投入是最重要的、哪些既有軟件資產(chǎn)是可以重新拿來使用的、哪些人應(yīng)該被加入團(tuán)隊(duì)中?戰(zhàn)術(shù)設(shè)計(jì)則幫助產(chǎn)品研發(fā)人員具體實(shí)施。
降低成本:先劃分業(yè)務(wù)邊界,確認(rèn)核心業(yè)務(wù),避免伴隨功能迭代后的代碼不斷疊加,導(dǎo)致代碼耦合,降低維護(hù)成本。
以降低成本為例,假設(shè)我們要做一個電商訂單下單需求,涉及到用戶選定商品,下訂單、支付訂單、對用戶下單時的訂單發(fā)貨:
常見做法是在分析好業(yè)務(wù)需求之后,開始設(shè)計(jì)表結(jié)構(gòu),訂單表、支付表、商品表等等,然后編寫業(yè)務(wù)邏輯當(dāng)功能迭代,訂單支付后要支持取消,下單商品要支持退換貨,就又需要加表,并針對實(shí)現(xiàn)的邏輯不斷進(jìn)行修改。這也意味著當(dāng)功能不斷迭代,代碼也會層層上疊。
而DDD要求先劃分業(yè)務(wù)邊界。該場景下的核心是訂單,那么訂單就是業(yè)務(wù)領(lǐng)域里的聚合邏輯體現(xiàn)。支付、商品信息、地址等等都是圍繞訂單實(shí)體。訂單本身的屬性決定之后,類似于地址只是一個屬性的體現(xiàn)。當(dāng)你將訂單的領(lǐng)域模型構(gòu)建好之后,衍生了倉庫的上下文。
總結(jié)來說,DDD優(yōu)勢在質(zhì)量、效率、成本3方面都得到了體現(xiàn)。
惟客是如何實(shí)踐DDD的?
從時間線來說,可以分為3個階段:
2020年7月,引入DDD,在小項(xiàng)目和模塊進(jìn)行試點(diǎn);
2021年6月,完成在大會員模塊進(jìn)行實(shí)踐和應(yīng)用;
2022年3月,完成公司交易、營銷、會員、家裝產(chǎn)品線的改造和重構(gòu)。
重點(diǎn)以3月份的項(xiàng)目為例。惟客投入70人參與本次項(xiàng)目,目的是解決老舊項(xiàng)目之間耦合嚴(yán)重、業(yè)務(wù)邊界不清晰、代碼重復(fù)率高、維護(hù)成本高等問題。從落地步驟來拆,包括5個部分:
需求評審
1、過需求、了解相關(guān)聯(lián)業(yè)務(wù)的用戶故事
2、產(chǎn)品輸出用戶故事地圖、原型圖、流程圖,開發(fā)理解相關(guān)資料
拆用戶故事
1、對照用戶故事地圖將用戶故事進(jìn)行細(xì)分
2、整理出相關(guān)聯(lián)的業(yè)務(wù)指令和事件(事件風(fēng)暴)
3、用戶故事評審,確保需求沒遺漏、業(yè)務(wù)指令和事件劃分正確
領(lǐng)域模型圖設(shè)計(jì)
1、識別應(yīng)用上下文,劃分領(lǐng)域界限(核心、通用、支領(lǐng)域),拆分成多個子域
2、根據(jù)用戶故事及業(yè)務(wù)指令區(qū)分出查詢模型和命令模型
3、在領(lǐng)域內(nèi)繪制出相關(guān)聯(lián)業(yè)務(wù)的領(lǐng)域模型圖(包含查詢模型、聚合、聚合內(nèi)聚合根、實(shí)體、值對象的關(guān)系、實(shí)體具有的能力、領(lǐng)域服務(wù)、領(lǐng)域事件)
4、領(lǐng)域模型圖評審
代碼實(shí)現(xiàn)
1、對照領(lǐng)域模型圖建業(yè)務(wù)指令、事件、實(shí)體、值對象、實(shí)體能力及領(lǐng)域服務(wù)
2、完成領(lǐng)域模塊開發(fā),建db入庫
3、代碼評審,對照領(lǐng)域模型圖
4、完成所有業(yè)務(wù)開發(fā)
單元測試
1、對于聚合能力的單元測試
2、領(lǐng)域服務(wù),指令的單元測試
實(shí)踐過程中遇到哪些問題
為創(chuàng)建通用語言騰出來的時間和精力
通用語言是指非技術(shù)崗位也能很容易理解的語言,在目標(biāo)拉齊的基礎(chǔ)上,需要拉齊各個角色對術(shù)語都使用統(tǒng)一名詞,對業(yè)務(wù)價(jià)值以及規(guī)則的描述使用統(tǒng)一的描述方式和規(guī)則,并且需要使得每一個人都能聽的懂。
以商品條形碼為例:
領(lǐng)域?qū)<遥簭膱鼍敖嵌确治?,它主要是供小程序掃描這個條形碼進(jìn)行購買商品
產(chǎn)品:從規(guī)則角度分析,商品編碼,長度是多少位,組成規(guī)則是什么。
開發(fā):按照功能事項(xiàng)的角度去分析,barcode,商品的sku級別的唯一標(biāo)識,存儲方式是什么。
很明顯,大家分析問題的角度不一樣,給出的語言不同,但本質(zhì)上商品條形碼=商品編碼=barCode,因此需要花時間拉齊不同角色間的語言。
領(lǐng)域?qū)<覍τ趯?shí)踐DDD很重要,但這個角色通常是業(yè)務(wù)專家,他們工作繁忙、時間難約,較難持續(xù)在一個項(xiàng)目中消耗太多時間。
因此在落地中,建議盡可能一次性把業(yè)務(wù)相關(guān)的疑問和問題準(zhǔn)備好,減少對接次數(shù)、提高效率。
由過程編碼 -> 面向?qū)ο缶幋a
由數(shù)據(jù)模型 -> 領(lǐng)域模型
領(lǐng)域模型關(guān)注的是領(lǐng)域本身,是業(yè)務(wù)領(lǐng)域的核心實(shí)體,體現(xiàn)在問題域關(guān)鍵概念和之間的聯(lián)系。構(gòu)建領(lǐng)域模型的目標(biāo)是看模型能否清晰表達(dá)業(yè)務(wù)語義、模型能否顯性化,擴(kuò)展性是其次。
數(shù)據(jù)模型關(guān)注的是數(shù)據(jù)存儲,在我們所有的業(yè)務(wù)中都離不開數(shù)據(jù),離不開對數(shù)據(jù)的CRUD。構(gòu)建數(shù)據(jù)模型目標(biāo)是看擴(kuò)展性、性能等非功能屬性,業(yè)務(wù)語義的表達(dá)則是其次。
人最難轉(zhuǎn)變的是思維慣性,而不是技術(shù)和策略本身。因此在實(shí)踐前,對以上3點(diǎn)有心理預(yù)期,并提前做好應(yīng)對方案,可以更快地落地DDD。
總之,如果企業(yè)希望能更好地發(fā)揮軟件系統(tǒng)的業(yè)務(wù)價(jià)值,從長期價(jià)值主義出發(fā),提高代碼的可維護(hù)性、可擴(kuò)展性,那么DDD絕對是一套值得嘗試的方法
(免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請進(jìn)一步核實(shí),并對任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對有關(guān)資料所引致的錯誤、不確或遺漏,概不負(fù)任何法律責(zé)任。
任何單位或個人認(rèn)為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識產(chǎn)權(quán)或存在不實(shí)內(nèi)容時,應(yīng)及時向本網(wǎng)站提出書面權(quán)利通知或不實(shí)情況說明,并提供身份證明、權(quán)屬證明及詳細(xì)侵權(quán)或不實(shí)情況證明。本網(wǎng)站在收到上述法律文件后,將會依法盡快聯(lián)系相關(guān)文章源頭核實(shí),溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。 )