2DDD三駕馬車之架構(gòu)設(shè)計

DDD在解決什么問題

當(dāng)我們在談?wù)擃I(lǐng)域驅(qū)動設(shè)計的時候实撒,我們到底在談?wù)撌裁矗款I(lǐng)域驅(qū)動設(shè)計是在解決什么問題仍侥?

領(lǐng)域本質(zhì)是一種認(rèn)知,是我們對業(yè)務(wù)問題域的認(rèn)知鸳君,與其說我們是在用技術(shù)解決業(yè)務(wù)問題农渊,更不如說,我們是在不斷地提升對業(yè)務(wù)的認(rèn)知或颊,不斷地優(yōu)化業(yè)務(wù)領(lǐng)域模型砸紊,從而不斷地接近業(yè)務(wù)問題的本質(zhì)。代碼壞味道的背后反映的是對業(yè)務(wù)問題不清晰的認(rèn)知囱挑,最終落地了不優(yōu)雅的代碼實現(xiàn)醉顽。回歸到生活中平挑,工作中游添,我們會經(jīng)常遇到各種問題,大多數(shù)時候不是我們沒有習(xí)得解決問題的技能通熄,而是我們對問題的認(rèn)知不夠唆涝。

在上一篇文章《真的,DDD太好玩了》中我們說棠隐,DDD是一種業(yè)務(wù)設(shè)計思想石抡,用以將業(yè)務(wù)邏輯和技術(shù)實現(xiàn)分離,今天我們就是要討論一下DDD三駕馬車之中的架構(gòu)設(shè)計(三架馬車指的是架構(gòu)設(shè)計助泽,戰(zhàn)略設(shè)計和戰(zhàn)術(shù)設(shè)計),即如何將業(yè)務(wù)邏輯和技術(shù)實現(xiàn)分離嚎京。DDD中常見的架構(gòu)設(shè)計有:MVC三層架構(gòu)嗡贺,傳統(tǒng)四層架構(gòu),依賴倒置的四層架構(gòu)鞍帝,六邊形架構(gòu)(又稱端口適配器架構(gòu)诫睬,我更喜歡這個名字),洋蔥架構(gòu)帕涌,事件驅(qū)動架構(gòu)(EDA摄凡,Event-Driven Architecture?),命令與查詢分離(CQRS蚓曼,Command Query Responsibility Segregation)亲澡。

四個分層

首先我要介紹一下四層架構(gòu)的各個分層是做什么事情的,這對于理解后面各種架構(gòu)設(shè)計是有幫助的纫版,不管上述幾種架構(gòu)是如何命名的床绪,是如何定義和認(rèn)識業(yè)務(wù)邏輯和技術(shù)實現(xiàn)分離這個命題的,其內(nèi)核都是一樣的。四層架構(gòu)的四層分別指的是用戶接口層癞己、應(yīng)用層膀斋、領(lǐng)域?qū)雍突A(chǔ)設(shè)施層,其定義如下:

用戶接口層(User Interface):主要負(fù)責(zé)處理用戶請求痹雅,并將請求轉(zhuǎn)發(fā)給應(yīng)用層處理仰担。

應(yīng)用層(Application):主要負(fù)責(zé)協(xié)調(diào)上游的用戶接口層以及下游的領(lǐng)域?qū)樱⒁獾氖羌ㄉ纾搶舆壿嬕M可能簡單惰匙,否則會導(dǎo)致領(lǐng)域?qū)拥呢氀?/p>

領(lǐng)域?qū)樱―omain):主要包含了核心業(yè)務(wù)邏輯,包含實體铃将,值對象项鬼,領(lǐng)域服務(wù),領(lǐng)域事件等劲阎。

基礎(chǔ)設(shè)施層(Infrastructure):主要提供各種技術(shù)中間件绘盟,數(shù)據(jù)庫(MySQL,NoSql)和應(yīng)用配置等技術(shù)實現(xiàn)方面的能力悯仙。

架構(gòu)設(shè)計分析

在DDD架構(gòu)設(shè)計中龄毡,核心的目標(biāo)就是將業(yè)務(wù)邏輯和技術(shù)實現(xiàn)分離,這也正是MVC三層架構(gòu)留下來的問題锡垄。

我們在MVC三層架構(gòu)中將業(yè)務(wù)邏輯和技術(shù)實現(xiàn)一股腦寫在了Service層沦零,技術(shù)實現(xiàn)中參雜了業(yè)務(wù)邏輯,業(yè)務(wù)邏輯中也揉合了技術(shù)實現(xiàn)货岭,從而將本來就復(fù)雜的業(yè)務(wù)邏輯變得更加復(fù)雜了路操。端口適配器架構(gòu)則簡化了這個問題,很直白地將架構(gòu)設(shè)計成了兩部分千贯,即內(nèi)部的業(yè)務(wù)邏輯和外部的基礎(chǔ)設(shè)施和用戶界面屯仗,當(dāng)然這也是一種分層架構(gòu),即內(nèi)部和外部兩層搔谴。如果將內(nèi)部業(yè)務(wù)邏輯對外部的依賴定義成接口魁袜,那么基礎(chǔ)設(shè)施表示的技術(shù)實現(xiàn)部分,用戶界面表示的是用戶請求就都算是適配器實現(xiàn)敦第。

圖1 端口適配器架構(gòu)

這種實現(xiàn)業(yè)務(wù)邏輯和技術(shù)實現(xiàn)分離的架構(gòu)真的是太優(yōu)雅了峰弹,很符合奧卡姆剃刀原理(“如無必要,勿增實體”芜果,即“簡單有效原理”)鞠呈,簡單就是美。但其實也會帶來另一個問題师幕,即如何去認(rèn)識業(yè)務(wù)邏輯粟按?難道業(yè)務(wù)邏輯就是一個大塊頭嗎诬滩?該如何下手設(shè)計這個大塊頭呢?

洋蔥架構(gòu)既在端口適配器架構(gòu)之上灭将,提出了一種劃分業(yè)務(wù)邏輯的方法疼鸟,將業(yè)務(wù)邏輯劃分為應(yīng)用服務(wù),領(lǐng)域服務(wù)和領(lǐng)域模型庙曙,并且依賴方向也是從外向內(nèi)空镜。這里其實也有了依賴倒置四層架構(gòu)的味道了。

圖2 洋蔥架構(gòu)

那么我們就順理成章地介紹一下四層架構(gòu)捌朴,在傳統(tǒng)的四層架構(gòu)中吴攒,我們可以發(fā)現(xiàn),所有的依賴都指向了基礎(chǔ)設(shè)施層砂蔽,這帶來了一個很大的問題洼怔,業(yè)務(wù)邏輯依賴了技術(shù)實現(xiàn),技術(shù)實現(xiàn)的變動會導(dǎo)致業(yè)務(wù)邏輯發(fā)生變化左驾,這不符合我們的認(rèn)知镣隶。在理想的架構(gòu)實現(xiàn)中,不管你技術(shù)如何變化诡右,我的業(yè)務(wù)邏輯是不應(yīng)該受到技術(shù)變化影響的安岂。這時候依賴倒置原則就可以發(fā)揮作用了,將技術(shù)實現(xiàn)的契約或者規(guī)范定義在領(lǐng)域?qū)臃牵A(chǔ)實施層只管實現(xiàn)就好了域那,從而實現(xiàn)了依賴方向的反轉(zhuǎn)。這種架構(gòu)設(shè)計維護(hù)了業(yè)務(wù)邏輯的穩(wěn)定猜煮,也更近一步地將技術(shù)實現(xiàn)對業(yè)務(wù)邏輯的影響降到了最低次员,從而實現(xiàn)了業(yè)務(wù)邏輯和技術(shù)實現(xiàn)的解耦,也使得領(lǐng)域?qū)犹幱诩軜?gòu)模型中的核心地位友瘤。

圖3 分層架構(gòu)

在上面的分析中翠肘,我們可以發(fā)現(xiàn),其實DDD的四層架構(gòu)是一種相對而言更便于理解和落地的架構(gòu)辫秧,它可以讓我們更輕松地從MVC三層架構(gòu)的認(rèn)知中遷移至DDD四層架構(gòu)。

至此被丧,四層架構(gòu)模型似乎已經(jīng)解決了業(yè)務(wù)邏輯和技術(shù)實現(xiàn)分離的問題盟戏,事實上也確實如此。CQRS架構(gòu)模型和EDA架構(gòu)模型在我眼中更像是對四層架構(gòu)的優(yōu)化甥桂。其中CQRS模型類似于讀寫分離柿究,其中命令是客戶端讓服務(wù)器做事情,是從客戶端向服務(wù)器后端發(fā)出寫入操作命令黄选,通常會改變后端模型的狀態(tài)蝇摸;而查詢是服務(wù)器后端向客戶端返回結(jié)果婶肩。在前面幾種架構(gòu)模型中,查詢和變更操作都是經(jīng)過完整的四層處理貌夕,并且實現(xiàn)邏輯都耦合在一起了律歼,即實現(xiàn)在相同的類中。其實對于查詢操作來說啡专,這是一種很輕量級的業(yè)務(wù)邏輯险毁,核心就是獲取數(shù)據(jù)并進(jìn)行轉(zhuǎn)化,最終展示給用戶们童,將其與命令分離開使得讀寫邏輯可以獨立建模畔况,邏輯更清晰,也可以專門優(yōu)化查詢操作慧库。

圖4 CQRS模型

而EDA架構(gòu)的核心目的是提供一個業(yè)務(wù)認(rèn)知和業(yè)務(wù)解耦的方法跷跪,通過事件的流轉(zhuǎn)來認(rèn)識業(yè)務(wù)邏輯,并且也可以通過業(yè)務(wù)事件來解耦業(yè)務(wù)齐板。因為不斷是什么業(yè)務(wù)場景吵瞻,其本質(zhì)都是事件導(dǎo)致結(jié)果發(fā)生,每個結(jié)果也有可能是一個事件覆积,從而通過事件來串聯(lián)整個業(yè)務(wù)流程听皿,但也會帶來事務(wù)問題。

最后

上面分析了這么多架構(gòu)模式宽档,但仿佛是個屠龍之術(shù)尉姨,學(xué)了很多又似乎無用武之地。但回過頭看吗冤,正是因為領(lǐng)域設(shè)計的目標(biāo)又厉,才有了形形色色的架構(gòu)模式,每個架構(gòu)架構(gòu)模式都在提出自己對問題的認(rèn)知和解決方案椎瘟,即如何將業(yè)務(wù)邏輯和技術(shù)實現(xiàn)分離覆致,從而使得領(lǐng)域設(shè)計回歸本質(zhì),關(guān)注于業(yè)務(wù)認(rèn)知肺蔚,而不是技術(shù)實現(xiàn)煌妈。

注:本文圖片均來源于網(wǎng)絡(luò)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宣羊,一起剝皮案震驚了整個濱河市璧诵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌仇冯,老刑警劉巖之宿,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異苛坚,居然都是意外死亡比被,警方通過查閱死者的電腦和手機(jī)色难,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來等缀,“玉大人枷莉,你說我怎么就攤上這事∠罨” “怎么了依沮?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長枪狂。 經(jīng)常有香客問我危喉,道長,這世上最難降的妖魔是什么州疾? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任辜限,我火速辦了婚禮,結(jié)果婚禮上严蓖,老公的妹妹穿的比我還像新娘薄嫡。我一直安慰自己,他們只是感情好颗胡,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布毫深。 她就那樣靜靜地躺著,像睡著了一般毒姨。 火紅的嫁衣襯著肌膚如雪哑蔫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天弧呐,我揣著相機(jī)與錄音闸迷,去河邊找鬼。 笑死俘枫,一個胖子當(dāng)著我的面吹牛腥沽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸠蚪,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼今阳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了茅信?” 一聲冷哼從身側(cè)響起酣栈,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎汹押,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體起便,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡棚贾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年窖维,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妙痹。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡铸史,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出怯伊,到底是詐尸還是另有隱情琳轿,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布耿芹,位于F島的核電站崭篡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吧秕。R本人自食惡果不足惜琉闪,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望砸彬。 院中可真熱鬧颠毙,春花似錦、人聲如沸砂碉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽增蹭。三九已至滴某,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沪铭,已是汗流浹背壮池。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留杀怠,地道東北人椰憋。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像赔退,于是被迫代替她去往敵國和親橙依。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

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