剛剛結(jié)束的2019年領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)峰會(huì)(DDD China Conference 2019),已經(jīng)是DDD-China的第三年了,也是我參加的第二年,還記得去年分享的是《當(dāng)我們談中臺(tái)時(shí)我們?cè)谡勑┦裁础?/a>,講的更多是中臺(tái)的Why和What,轉(zhuǎn)眼間一年就過(guò)去了,彈指一揮間。
幸運(yùn)的是,這一年個(gè)人的主旋律仍然還是圍繞著中臺(tái)這個(gè)既火熱又充滿(mǎn)爭(zhēng)議的主題,只不過(guò)關(guān)注點(diǎn)逐漸從Why和What逐漸過(guò)渡到How,也就是對(duì)于如何構(gòu)建中臺(tái)的通用方法論思考、研究與應(yīng)用上。所以今年分享的主題是《中臺(tái)規(guī)劃的七種武器》,就當(dāng)是再給大家做一個(gè)年終總結(jié)匯報(bào),分享這一年的所思所得。
提到中臺(tái)(尤其是業(yè)務(wù)中臺(tái))的構(gòu)建方法論,就不得不提另兩個(gè)同樣伴隨著微服務(wù)和中臺(tái)概念興起的工具:Domain-Driven Design(DDD,領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))和EventStorming(事件風(fēng)暴)。
在各種講中臺(tái)落地規(guī)劃,尤其是業(yè)務(wù)中臺(tái)的共性能力識(shí)別和微服務(wù)劃分的時(shí)候,總是能看到這兩位的身影。不過(guò)相信好多朋友對(duì)于這兩個(gè)相對(duì)陌生的面孔還是感覺(jué)云里霧里,搞不清楚到底是什么,以及與中臺(tái)的關(guān)系。
本篇就以我個(gè)人的經(jīng)歷和視角,為大家講述一下我對(duì)這二位的理解。
DDD(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))
回想一下,第一次接觸DDD應(yīng)該還是十多年前,那還是每天刷著JavaEye,看一群神仙打架的年代。
依稀記得那時(shí)候社區(qū)里討論的最熱的也還是Hibernate和OR-Mapping,RoR也還在蓄勢(shì)待發(fā),記憶中那也是我最開(kāi)始接觸DDD的時(shí)候。
所以,現(xiàn)在很多人以為DDD是個(gè)新冒出來(lái)的東西,其實(shí)并不是,這東西已經(jīng)有了10多年的歷史了,豆瓣上還有第一版領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的藍(lán)色版本的封面(不知道誰(shuí)還有這個(gè)版本,反正我的是早就丟了)。而第一版的出版年份被定格在2006年3月1日,距今已經(jīng)過(guò)去了13年。
DDD雖然誕生的早,但直到現(xiàn)在,和我們?nèi)粘9ぷ鞯木嚯x也并不遠(yuǎn),例如我們代碼中經(jīng)常出現(xiàn)的XxxEntity,XxxRepository ,XxxService,XxxFactory……這些類(lèi),這里的Entity、Repository、Service和Factory,以及我們現(xiàn)在大家早已習(xí)以為常的分層架構(gòu),都是出自DDD之手,只不過(guò)很多人已經(jīng)不知道這些都是拜DDD所賜而已。
我們中的大多數(shù)人就像“猴子定律”里后來(lái)的猴子們一樣,習(xí)慣了約定俗成,日復(fù)一日重復(fù)著(Controller-Service-Repository-Entity => CRUD)這些看似枯燥的操作,而早已忘了為什么一開(kāi)始架構(gòu)和這些所謂的最佳實(shí)踐被設(shè)計(jì)成這個(gè)樣子,少了一份溯本求源的精神。
以致于我經(jīng)常在面試的時(shí)候,問(wèn)候選人,你這里為什么要一個(gè)Service呀?大多數(shù)的回復(fù)都是:這是規(guī)范呀!這不是基本常識(shí)么?我們公司規(guī)定都得這么寫(xiě)的……
那說(shuō)來(lái)說(shuō)去,DDD到底是什么呢?
在我看來(lái),DDD其實(shí)就是面向?qū)ο蟮囊惶住胺窖浴?,提供了一種基于業(yè)務(wù)領(lǐng)域的對(duì)象劃分和分類(lèi)方法,其最大的價(jià)值就在于對(duì)于軟件開(kāi)發(fā)過(guò)程全生命周期使用語(yǔ)言的統(tǒng)一!
怎么講呢?
在面向?qū)ο蟮氖澜?,只告訴了我們?nèi)f事萬(wàn)物皆是對(duì)象。但并沒(méi)有告訴我們對(duì)象究竟應(yīng)該怎么組織,該以什么角度進(jìn)行劃分。
而作為技術(shù)人員的我們,早已習(xí)慣了從技術(shù)的角度出發(fā)思考,自然就出現(xiàn)了“用技術(shù)的語(yǔ)言”定義對(duì)象的習(xí)慣,例如最常見(jiàn)的DAO(Data Access Objects),DTO(Data Transfer Object)這類(lèi)對(duì)象的劃分方式就是使用技術(shù)視角看待和分類(lèi)對(duì)象的典型案例。
這樣從技術(shù)視角分類(lèi)對(duì)象的問(wèn)題,就在于在軟件的開(kāi)發(fā)過(guò)程中,會(huì)涉及到多“語(yǔ)言”間的對(duì)應(yīng)和翻譯,例如最常見(jiàn)的就是業(yè)務(wù)語(yǔ)言和技術(shù)語(yǔ)言的相互翻譯。想想周?chē)?jīng)常出現(xiàn)的研發(fā)和產(chǎn)品之間各種痛苦的溝(吵)通(架)場(chǎng)景,應(yīng)該就知道我說(shuō)的意思了。
這個(gè)過(guò)程其實(shí)和兩種不同語(yǔ)言(例如中文和英文)的人之間的溝通是一樣的,而且更加隱蔽,因?yàn)檎f(shuō)的明明都是中文,但是彼此就是聽(tīng)不懂彼此說(shuō)的到底是什么意思,而且都覺(jué)得對(duì)方像個(gè)傻子,聽(tīng)不懂人話(huà),殊不知其實(shí)兩個(gè)人說(shuō)的本身就不是同一種語(yǔ)言。
而DDD的出現(xiàn),就是為了解決這個(gè)問(wèn)題。它通過(guò)一套面向?qū)ο蟮姆诸?lèi)方法或是方言體系,從領(lǐng)域出發(fā),實(shí)現(xiàn)軟件開(kāi)發(fā)過(guò)程中各個(gè)角色和環(huán)境的“統(tǒng)一語(yǔ)言”(UBIQUITOUS LANGUAGE)。例如使用“倉(cāng)庫(kù)(Repository)”替代“數(shù)據(jù)訪(fǎng)問(wèn)對(duì)象(DAO)”,就更能讓業(yè)務(wù)和技術(shù)同時(shí)理解這個(gè)對(duì)象的作用。
就像車(chē)同軌,書(shū)同文一樣。
好了,了解了DDD的來(lái)歷和價(jià)值,那你肯定還有疑問(wèn),既然DDD這個(gè)概念已經(jīng)快被人們淡忘了10多年了(雖然我們一直還在不知不覺(jué)中僵硬地應(yīng)用著),那為什么最近一兩年又突然重出江湖,重新被大家關(guān)注了呢?
答案其實(shí)就兩個(gè):微服務(wù)和中臺(tái)。
說(shuō)到這里還有個(gè)段子:
其實(shí)DDD一開(kāi)始的時(shí)候,就把領(lǐng)域分析設(shè)計(jì)分為了戰(zhàn)略(Domain、Bounded Context)和戰(zhàn)術(shù)(Entity、VO、Repository、Service……)兩個(gè)部分。按道理應(yīng)該從戰(zhàn)略入手,再下沉到戰(zhàn)術(shù)部分。但是Eric Evans在寫(xiě)《Domain-Driven Design》這本書(shū)時(shí),可能是基于當(dāng)時(shí)的環(huán)境,卻是先寫(xiě)的戰(zhàn)術(shù)部分,書(shū)的后半部分才開(kāi)始展開(kāi)DDD的戰(zhàn)略部分。
而又因?yàn)閼?zhàn)術(shù)部分本身就很復(fù)雜很枯燥(各種圖各種代碼),所以很多人并沒(méi)有堅(jiān)持到讀后邊的戰(zhàn)略部分,就讀不下去(比如我)。導(dǎo)致的結(jié)果就是這么多年戰(zhàn)術(shù)部分被大家充分的討論和應(yīng)用,而戰(zhàn)略部分的影響則相較之下非常有限,討論和應(yīng)用的也不多。
直到微服務(wù)的橫空出世……
隨著微服務(wù)架構(gòu)的興起,微服務(wù)到底如何拆分就成了人們最最關(guān)注的問(wèn)題。這時(shí)候一些“老人兒”們突然想起來(lái),這不是正是應(yīng)用DDD中戰(zhàn)略部分(問(wèn)題域,限界上下文)應(yīng)用和施展拳腳的場(chǎng)合么?!
所以隨著微服務(wù)的爆炸式發(fā)展,DDD這位退隱已久的老江湖,又再次被請(qǐng)出了山,站到了大家的面前。
而此時(shí),他身邊還多了一個(gè)年輕的新搭檔,他正是:事件風(fēng)暴。
EventStorming(事件風(fēng)暴)
現(xiàn)在,當(dāng)很多人談到DDD都會(huì)同時(shí)談到EventStorming,甚至有人誤認(rèn)為這兩個(gè)名詞本身指代的就是同一個(gè)概念。
但其實(shí)這是兩個(gè)完全獨(dú)立的工具。
DDD是一套基于領(lǐng)域的分析和建模方法,而EventStorming則是一套Workshop(可以理解成一個(gè)類(lèi)似于頭腦風(fēng)暴的工作坊)方法。DDD出現(xiàn)要比EventStorming早了10多年,而EventStorming的設(shè)計(jì)雖然參考了DDD的部分內(nèi)容,但是并不是只為了DDD而設(shè)計(jì)的,是一套獨(dú)立的通過(guò)協(xié)作基于事件還原系統(tǒng)全貌,從而快速分析復(fù)雜業(yè)務(wù)領(lǐng)域,完成領(lǐng)域建模的方法。
EventStorming最初由Alberto Brandolini(曾受邀參加了DDD-China 2017)開(kāi)發(fā),經(jīng)過(guò)DDD社區(qū)和ThoughtWorks的很多團(tuán)隊(duì)實(shí)踐驗(yàn)證后,于2015年11月進(jìn)入ThoughtWorks技術(shù)雷達(dá),開(kāi)始被更多人知曉和應(yīng)用,從此成為DDD的最佳拍檔。
關(guān)于EventStorming的具體內(nèi)容和細(xì)節(jié),已經(jīng)有很多文章都介紹了,不過(guò)還是強(qiáng)烈建議先看一下eventstorming.com 官網(wǎng)的那本作者Alberto Brandolini自己寫(xiě)的《Introducing EventStorming》,應(yīng)該是最官方最正宗的對(duì)于EventStorming的介紹。
而書(shū)中的下面這個(gè)圖,我認(rèn)為是對(duì)于EventStorming最清晰、完整且簡(jiǎn)單的概括。完整的闡釋了從系統(tǒng)外部與用戶(hù)的交互,到系統(tǒng)內(nèi)(事件-策略-命令-聚合-事件)的事件傳遞漣漪,以及通過(guò)事件影響到讀模型從而給予用戶(hù)動(dòng)作的響應(yīng),從而形成完整閉環(huán)的全過(guò)程。對(duì)我們了解還原系統(tǒng)的全貌非常有幫助。
前面提到了,EventStorming和DDD兩個(gè)獨(dú)立的工具,形式不同、解決的也是不同的問(wèn)題,那為什么這兩者總是搭檔出現(xiàn)呢?
關(guān)鍵就在于下圖這條紅線(xiàn),就像是月老手中的紅線(xiàn)一樣,將兩個(gè)概念牽在了一起。
DDD提供了一套面向?qū)ο蟮摹胺窖浴?,給出了一套面向?qū)ο蟮姆诸?lèi)框架和架構(gòu)指引,但是在DDD中并沒(méi)有明確給出如何為一個(gè)系統(tǒng)識(shí)別出這些不同種類(lèi)的對(duì)象的過(guò)程和方法。
而EventStorming的出現(xiàn)正好彌補(bǔ)了這個(gè)空白,通過(guò)EventStorming工作坊的方式,正好給我們提供了一個(gè)還原和分析系統(tǒng)的方法,并最終通過(guò)“聚合”這條紅線(xiàn),穿越時(shí)空,無(wú)縫切入到DDD的領(lǐng)域范疇之內(nèi),以“聚合”為支點(diǎn),向上可以進(jìn)一步做問(wèn)題域和限界上下文的戰(zhàn)略分析,向下則可以通過(guò)聚合的進(jìn)一步展開(kāi)進(jìn)行實(shí)體、值對(duì)象等相關(guān)的戰(zhàn)術(shù)分析,引導(dǎo)落地。
而DDD戰(zhàn)略設(shè)計(jì)中問(wèn)題域和限界上下文的識(shí)別,則為我們劃分微服務(wù)提供了非常強(qiáng)有力的支撐,至此我們就通過(guò)EventStorming和DDD的這一對(duì)強(qiáng)力組合的聯(lián)袂輔助下,找到了解決了微服務(wù)架構(gòu)下最困難問(wèn)題之一的,既服務(wù)該如何劃分問(wèn)題的解題思路和落地方法。
那說(shuō)了半天微服務(wù),DDD和EventStorming到底又與業(yè)務(wù)中臺(tái)有什么關(guān)系呢?
DDD、EventStorming與業(yè)務(wù)中臺(tái)
我之前的文章曾提到過(guò)業(yè)務(wù)中臺(tái)與微服務(wù)的關(guān)系,而當(dāng)時(shí)我的觀點(diǎn)很簡(jiǎn)單,就是:沒(méi)有直接關(guān)系。
業(yè)務(wù)中臺(tái)解決的是企業(yè)級(jí)能力復(fù)用的問(wèn)題,而微服務(wù)解決的是運(yùn)行時(shí)解耦的問(wèn)題。業(yè)務(wù)中臺(tái)不一定是微服務(wù)的,采用微服務(wù)架構(gòu)的也不一定就是業(yè)務(wù)中臺(tái),這些之前都提到過(guò),這里就不贅述了。
所以很多人以為使用DDD和EventStorming規(guī)劃業(yè)務(wù)中臺(tái),是因?yàn)槲⒎?wù),在我看來(lái),基于以上的分析這也是站不住腳的,難道我不用微服務(wù)架構(gòu)來(lái)實(shí)現(xiàn)業(yè)務(wù)中臺(tái),就無(wú)法使用DDD和EventStorming了么?
DDD和EventStorming的結(jié)合,形成的是一套“領(lǐng)域分析方法”,可以想象成一套雙劍合璧的劍陣。其目的是透過(guò)現(xiàn)象看本質(zhì),透過(guò)表面的業(yè)務(wù)流程來(lái)分析背后的核心領(lǐng)域問(wèn)題和概念,而微服務(wù)架構(gòu)只是使用了這套能力,來(lái)指導(dǎo)和幫助進(jìn)行服務(wù)劃分而已,并且也不是唯一的指導(dǎo)原則,其他還需要考慮像團(tuán)隊(duì)組成、變更頻率、技術(shù)異構(gòu)邊界、SLA要求等等因素……
而對(duì)于業(yè)務(wù)中臺(tái),這套領(lǐng)域分析方法,則可以指導(dǎo)我們探究與分析業(yè)務(wù)中臺(tái)規(guī)劃過(guò)程中的一個(gè)最困難的問(wèn)題,既:識(shí)別不同的業(yè)務(wù)線(xiàn),到底有哪些業(yè)務(wù)是可以復(fù)用的?
因?yàn)槿绻环治霰砻娴墓δ芎土鞒?,我們總是?huì)發(fā)現(xiàn)雖然不同的業(yè)務(wù)看似都差不多,但總是有不同的地方,很難抽取共性。
這就像我們看每個(gè)人,乍一看都長(zhǎng)得差不多,一個(gè)腦袋一個(gè)身子,倆個(gè)胳膊倆條腿。但是仔細(xì)觀察,又會(huì)發(fā)現(xiàn)每個(gè)人都是不一樣的,細(xì)節(jié)上還是有很大的差別,長(zhǎng)相不同,性格不同,做事方式也不一樣。
而領(lǐng)域分析就像是給人照個(gè)B超一樣或是做一個(gè)性格分析一樣,透過(guò)外表和行為,分析背后的本質(zhì)和機(jī)理,尋找不同背后的相同,找尋變化背后的不變。
而這種通過(guò)領(lǐng)域分析和抽象,找尋不同業(yè)務(wù)線(xiàn)背后面對(duì)的相同的問(wèn)題域,并從中提取共性的業(yè)務(wù)模型、提取共性的業(yè)務(wù)功能、提取共性的業(yè)務(wù)流程、甚至是提取共性的業(yè)務(wù)模式,加工并予以復(fù)用的過(guò)程,也正是業(yè)務(wù)中臺(tái)的規(guī)劃與建設(shè)過(guò)程的關(guān)鍵所在。
這也是為什么當(dāng)我們提到業(yè)務(wù)中臺(tái)規(guī)劃的時(shí)候,總是會(huì)涉及到DDD和EventStorming,并把他們作為核心方法的原因。
總結(jié)
最后,我們用武俠小說(shuō)中的一段場(chǎng)景來(lái)收尾做個(gè)總結(jié):
江湖上流傳著一個(gè)人的傳說(shuō):
十年前,他一身白衣飄飄,仗雙劍叱咤江湖,但只用一劍,已天下無(wú)敵,從來(lái)沒(méi)有人看到過(guò)他的另一把劍出鞘。
十年間,江湖上早已不見(jiàn)了白衣人的蹤跡,人們雖然還在不斷地傳承著這流傳下來(lái)的無(wú)名劍法,但忘已忘卻了這個(gè)劍法背后的那個(gè)人。
十年后,江湖又是一場(chǎng)大亂,白衣人又重現(xiàn)江湖,雖然已沒(méi)有幾個(gè)人認(rèn)識(shí)他,但是認(rèn)識(shí)的人看到他之后都無(wú)不大吃一驚。
這十年,他的容貌沒(méi)有一點(diǎn)變化。
但讓人吃驚的不是他的容貌,而是他的劍:此時(shí),雙劍都已出鞘!
而他的身旁,還站著另一個(gè)持劍的少年,一樣的白衣飄飄,一樣的冷峻與瀟灑,讓人們不禁想起了白衣人十年前的樣子。
兩個(gè)人,三把劍,一套劍陣,能否能平息這場(chǎng)江湖大亂?
或是否還會(huì)有其他的英雄會(huì)橫空出世?
棋至中盤(pán),一切都還未成定論,讓我們一起拭目以待!







