大話DDD — 傳統(tǒng)MVC思想轉(zhuǎn)變?yōu)榕cDDD的思維

1. DDD的架構(gòu)

image.png

1. 用戶接口層(Controller層)

用戶接口層負(fù)責(zé)向用戶顯示信息和解釋用戶指令。

2. 應(yīng)用層(Service層)

應(yīng)用層是很薄的一層动猬,理論上不應(yīng)該由業(yè)務(wù)規(guī)則或邏輯盟庞,主要面向用例和流程相關(guān)的操作舷蟀。也可以完成

  • 編排多個(gè)聚合服務(wù)和領(lǐng)域?qū)ο笸瓿蓸I(yè)務(wù)操作株汉;
  • 調(diào)用其他微服務(wù)的應(yīng)用服務(wù)冒版,完成微服務(wù)之間服務(wù)的組合和編排液茎;

應(yīng)用服務(wù)是在應(yīng)用層的,它負(fù)責(zé)服務(wù)的組合、編排和轉(zhuǎn)發(fā)捆等,負(fù)責(zé)處理業(yè)務(wù)用例的執(zhí)行順序以及結(jié)果的拼裝滞造,以粗粒度的服務(wù)通過 API 網(wǎng)關(guān)向前端發(fā)布。還有栋烤,應(yīng)用服務(wù)還可以進(jìn)行安全認(rèn)證谒养、權(quán)限校驗(yàn)、事務(wù)控制明郭、發(fā)送或訂閱領(lǐng)域事件等买窟。

3. 領(lǐng)域?qū)樱╠omain層)

領(lǐng)域?qū)拥淖饔檬菍?shí)現(xiàn)企業(yè)核心業(yè)務(wù)邏輯,通過各種校驗(yàn)手段保證業(yè)務(wù)的正確性薯定。領(lǐng)域?qū)又饕w現(xiàn)領(lǐng)域模型的業(yè)務(wù)能力始绍,它用來表達(dá)業(yè)務(wù)概念,業(yè)務(wù)狀態(tài)和業(yè)務(wù)規(guī)則话侄;

領(lǐng)域?qū)影酆细魍疲瑢?shí)體,值對象满葛。領(lǐng)域服務(wù)等領(lǐng)域模型中的領(lǐng)域?qū)ο螅?/p>

領(lǐng)域模型的業(yè)務(wù)邏輯主要是由實(shí)體和領(lǐng)域服務(wù)來實(shí)現(xiàn)的:

  • 實(shí)體會(huì)采用充血模型來實(shí)現(xiàn)所有與之相關(guān)的業(yè)務(wù)功能径簿。
  • 實(shí)體和領(lǐng)域?qū)ο笤趯?shí)現(xiàn)業(yè)務(wù)邏輯上是同級的,當(dāng)領(lǐng)域中的某些功能嘀韧,單一實(shí)體(或者值對象)不能實(shí)現(xiàn)時(shí)篇亭,領(lǐng)域服務(wù)就會(huì)出馬他可以組合聚合內(nèi)的多個(gè)實(shí)體(或者值對象),實(shí)現(xiàn)復(fù)雜的業(yè)務(wù)邏輯锄贷。

4. 基礎(chǔ)層(Repository)

基礎(chǔ)層是貫穿所有層的译蒂,它的作用就是為其它各層提供通用的技術(shù)和基礎(chǔ)服務(wù),包括第三方工具谊却、驅(qū)動(dòng)柔昼、消息中間件、網(wǎng)關(guān)炎辨、文件捕透、緩存以及數(shù)據(jù)庫等。比較常見的功能還是提供數(shù)據(jù)庫持久化碴萧。

基礎(chǔ)層包含基礎(chǔ)服務(wù)乙嘀,它采用依賴倒置設(shè)計(jì),封裝基礎(chǔ)資源服務(wù)破喻,實(shí)現(xiàn)應(yīng)用層虎谢、領(lǐng)域?qū)优c基礎(chǔ)層的解耦,降低外部資源變化對應(yīng)用的影響曹质。

  1. 比如說婴噩,在傳統(tǒng)架構(gòu)設(shè)計(jì)中擎场,由于上層應(yīng)用對數(shù)據(jù)庫的強(qiáng)耦合,很多公司在架構(gòu)演進(jìn)中最擔(dān)憂的可能就是換數(shù)據(jù)庫了几莽,因?yàn)橐坏└鼡Q數(shù)據(jù)庫迅办,就可能需要重寫大部分的代碼,這對應(yīng)用來說是致命的章蚣。那采用依賴倒置的設(shè)計(jì)以后礼饱,應(yīng)用層就可以通過解耦來保持獨(dú)立的核心業(yè)務(wù)邏輯。當(dāng)數(shù)據(jù)庫變更時(shí)究驴,我們只需要更換數(shù)據(jù)庫基礎(chǔ)服務(wù)就可以了,這樣就將資源變更對應(yīng)用的影響降到了最低匀伏。

2. 傳統(tǒng)架構(gòu)遷移到DDD架構(gòu)

傳統(tǒng)企業(yè)應(yīng)用大多是單體架構(gòu)洒忧,而單體架構(gòu)大多是三層架構(gòu)。够颠。三層架構(gòu)解決了程序內(nèi)代碼間調(diào)用復(fù)雜熙侍、代碼職責(zé)不清的問題,但這種分層是邏輯概念履磨,在物理上它是中心化的集中式架構(gòu)蛉抓,并不適合分布式微服務(wù)架構(gòu)。

DDD 分層架構(gòu)中的要素其實(shí)和三層架構(gòu)類似剃诅,只是在 DDD 分層架構(gòu)中巷送,這些要素被重新歸類,重新劃分了層矛辕,確定了層與層之間的交互規(guī)則和職責(zé)邊界笑跛。

架構(gòu)遷移.png
  • DDD 分層架構(gòu)在用戶接口層引入了 DTO,給前端提供了更多的可使用數(shù)據(jù)和更高的展示靈活性聊品。

  • DDD 分層架構(gòu)將業(yè)務(wù)邏輯層的服務(wù)拆分到了應(yīng)用層和領(lǐng)域?qū)臃甚濉?yīng)用層快速響應(yīng)前端的變化,領(lǐng)域?qū)訉?shí)現(xiàn)領(lǐng)域模型的能力翻屈。

  • 另外一個(gè)重要的變化發(fā)生在數(shù)據(jù)訪問層和基礎(chǔ)層之間陈哑。三層架構(gòu)數(shù)據(jù)訪問采用 DAO 方式;DDD 分層架構(gòu)的數(shù)據(jù)庫等基礎(chǔ)資源訪問惊窖,采用了倉儲(chǔ)(Repository)設(shè)計(jì)模式,通過依賴倒置實(shí)現(xiàn)各層對基礎(chǔ)資源的解耦爬坑。

倉儲(chǔ)又分為兩部分:倉儲(chǔ)接口和倉儲(chǔ)實(shí)現(xiàn)涂臣。倉儲(chǔ)接口放在領(lǐng)域?qū)又卸芗疲瑐}儲(chǔ)實(shí)現(xiàn)放在基礎(chǔ)層售担。原來三層架構(gòu)通用的第三方工具包、驅(qū)動(dòng)族铆、Common、Utility哥攘、Config 等通用的公共的資源類統(tǒng)一放到了基礎(chǔ)層。

項(xiàng)目級微服務(wù).png

項(xiàng)目級微服務(wù)的內(nèi)部遵循分層架構(gòu)模型就可以了材鹦。領(lǐng)域模型的核心邏輯在領(lǐng)域?qū)訉?shí)現(xiàn)逝淹,服務(wù)的組合和編排在應(yīng)用層實(shí)現(xiàn),通過 API 網(wǎng)關(guān)為前臺應(yīng)用提供服務(wù)栅葡,實(shí)現(xiàn)前后端分離尤泽。但項(xiàng)目級的微服務(wù)可能會(huì)調(diào)用其它微服務(wù),你看在下面這張圖中坯约,比如某個(gè)項(xiàng)目級微服務(wù) B 調(diào)用認(rèn)證微服務(wù) A,完成登錄和權(quán)限認(rèn)證横殴。

通常項(xiàng)目級微服務(wù)之間的集成卿拴,發(fā)生在微服務(wù)的應(yīng)用層,由應(yīng)用服務(wù)調(diào)用其它微服務(wù)發(fā)布在 API 網(wǎng)關(guān)上的應(yīng)用服務(wù)巍棱。你看下圖中微服務(wù) B 中紅色框內(nèi)的應(yīng)用服務(wù) B,它除了可以組合和編排自己的領(lǐng)域服務(wù)外如贷,還可以組合和編排外部微服務(wù)的應(yīng)用服務(wù)到踏。它只要將編排后的服務(wù)發(fā)布到 API 網(wǎng)關(guān)供前端調(diào)用,這樣前端就可以直接訪問自己的微服務(wù)了窝稿。

3. 雜談

ddd領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)用人話怎么講。

別犟纹蝴,無論是傳統(tǒng)mvc的先設(shè)計(jì)表結(jié)構(gòu)還是ddd的先設(shè)計(jì)領(lǐng)域?qū)釉谠O(shè)計(jì)表結(jié)構(gòu)。歸根到底最終還是要設(shè)計(jì)表結(jié)構(gòu)的糠涛。只不過ddd一直給人一種感覺設(shè)計(jì)領(lǐng)域?qū)ο髨D更厲害的樣子——“你看我可是畫了領(lǐng)域圖,可不是er圖喲”

那么透過現(xiàn)象看本質(zhì)兼犯,所有業(yè)務(wù)目的不就是為了curd嗎?一般來說數(shù)據(jù)庫會(huì)有一張基表砸脊,n個(gè)輔表纬霞。甚至在數(shù)據(jù)中臺,只有一張打平表险领。那么什么樣的數(shù)據(jù)要抽取成為輔表秒紧。什么樣的數(shù)據(jù)配置是表屬性?是開發(fā)自己定還是根據(jù)領(lǐng)域劃分定的區(qū)別脐湾。

一般來說叙淌,有些數(shù)據(jù)會(huì)高并發(fā)寫操作,我們新開一個(gè)輔表闻鉴,有些數(shù)據(jù)不會(huì)變更茂洒。我們可能會(huì)違反數(shù)據(jù)庫范式將其作為冗余屬性配置到表記錄中。

那么ddd中領(lǐng)域?qū)泳秃芎媒忉屚ǘ缴祝覀儗?strong>聚合根作為基表,將其他實(shí)體看作輔表次询,將值對象看著表記錄的屬性瓷叫。其實(shí)就是ddd中實(shí)體的變與值對象的不變送巡。分析領(lǐng)域行為的目的其實(shí)就是有依據(jù)的建立表…不像mvc上來開發(fā)根據(jù)產(chǎn)品需求自己去建表雌芽。

  • 說下聚合這回事。就是整體與部分的關(guān)系淮腾。訂單明細(xì)不能獨(dú)立于訂單屉佳,它們就是聚合關(guān)系。用戶可以獨(dú)立于訂單 武花,它們就不是聚合關(guān)系。

  • 說下值對象和實(shí)體专钉,按理說沒必要糾結(jié)累铅。重點(diǎn)考慮目前這個(gè)字段是否經(jīng)常變化。實(shí)體也不一定會(huì)有自己單獨(dú)的表菇民,(掛在表上其實(shí)本質(zhì)就和值對象一樣)只是概念區(qū)分投储,沒必要太較真。

  • 說下聚合根和實(shí)體玛荞,本質(zhì)都是實(shí)體,只不過聚合根是基表驹碍,實(shí)體是輔表凡恍。比如我創(chuàng)建訂單一定會(huì)創(chuàng)建訂單明細(xì),我刪除訂單一會(huì)會(huì)刪除訂單明細(xì)浮还。且對領(lǐng)域的增刪改一般是通過聚合根實(shí)現(xiàn)的闽巩。不能直接去操作實(shí)體担汤。

  • 說下充血對象的事情 洼冻,其實(shí)我一直以來有疑問。不過大致現(xiàn)在想明白些撞牢,校驗(yàn)分為三種:參數(shù)格式校驗(yàn)交給充血對象屋彪、借助其他領(lǐng)域服務(wù)校驗(yàn)交由應(yīng)用層、領(lǐng)域內(nèi)其他實(shí)體的校驗(yàn)交由領(lǐng)域服務(wù)畜挥。

  • 說下充血對象和貧血對象,貧血對象簡單粗暴躯泰,充血對象昂貴而優(yōu)雅华糖。一般來說領(lǐng)域模型中出現(xiàn)類似繼承、多態(tài)的情況,則應(yīng)該繼承與多態(tài)的部分以充血對象的形式進(jìn)行實(shí)現(xiàn)景描。

  • 說下ddd工廠,首先不是設(shè)計(jì)模式的工廠模式向族,你可以理解就是創(chuàng)建一個(gè)領(lǐng)域?qū)ο蟮姆椒希╯pring bean)一般由應(yīng)用層調(diào)用將dto轉(zhuǎn)化成do 棠绘、基礎(chǔ)設(shè)施層調(diào)用將多個(gè)po填充為do。

  • 說下ddd對齊語言的事情夜矗。業(yè)務(wù)不會(huì)關(guān)心你的幾表和n個(gè)輔表让虐。他們就知道訂單對象里面有一個(gè)訂單明細(xì)的集合。而我們的domain object或者領(lǐng)域代碼就是這樣表現(xiàn)的赡突。其訂單表和訂單明細(xì)的詳細(xì)操作邏輯封裝在倉庫(基礎(chǔ)設(shè)施層)

  • 再說下ddd解決的是增刪改的問題。查詢操作直接走基層設(shè)施層封裝的方法即可浪南。

  • 最后說下軟件就是校驗(yàn)+入庫。ddd說入庫操作應(yīng)該解耦骡送,于是交給了倉庫喷众。還剩下校驗(yàn),說應(yīng)該充實(shí)對象到千。不要做貧血對象憔四。于是一部分交給了do、又說編排工作應(yīng)該交給應(yīng)用層了赵,于是跨領(lǐng)域服務(wù)的校驗(yàn)交給了應(yīng)用層 (但是應(yīng)用層說:我是你x嗎?)于是交給了工廠冗酿,應(yīng)用層不需要關(guān)注領(lǐng)域?qū)ο髣?chuàng)建的細(xì)節(jié)络断、那么領(lǐng)域?qū)右膊荒苌兑膊蛔觯谑穷I(lǐng)域?qū)油瓿傻氖蔷酆蠈?shí)體間的校驗(yàn)弱判。

  • 最后說下:ddd不會(huì)落地的人講概念锥惋。會(huì)落地的人還是講概念。這就是生活吧膀跌。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市株婴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌困介,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件徒扶,死亡現(xiàn)場離奇詭異根穷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)圈澈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門康栈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來喷橙,“玉大人,你說我怎么就攤上這事贰逾。” “怎么了氯迂?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵言缤,是天一觀的道長。 經(jīng)常有香客問我驰坊,道長哮独,這世上最難降的妖魔是什么察藐? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任分飞,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘羡疗。我一直安慰自己别洪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布痒钝。 她就那樣靜靜地躺著痢毒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪栋荸。 梳的紋絲不亂的頭發(fā)上夷家,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機(jī)與錄音摸袁,去河邊找鬼义屏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛闽铐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播踢星,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼沐悦,長吁一口氣:“原來是場噩夢啊……” “哼五督!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起充包,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎淆储,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體慈鸠,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡青团,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年咖楣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娃肿。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡珠十,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晒杈,到底是詐尸還是另有隱情孔厉,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布粪般,位于F島的核電站污桦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏凡橱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一躲惰、第九天 我趴在偏房一處隱蔽的房頂上張望变抽。 院中可真熱鬧,春花似錦诡宗、人聲如沸击儡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽矫夯。三九已至,卻和暖如春训貌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背豺鼻。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工款慨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人约素。 一個(gè)月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓笆凌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親送悔。 傳聞我的和親對象是個(gè)殘疾皇子爪模,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容