面向領(lǐng)域事件建模

????????試考慮一個(gè)打算入手IPHONE X的90后白領(lǐng),他計(jì)劃在網(wǎng)上某電商平臺(tái)入手,他未必對(duì)網(wǎng)站的建造細(xì)節(jié)感興趣,技術(shù)的選型,實(shí)施的計(jì)劃和許許多多關(guān)于工程細(xì)節(jié)的會(huì)議,對(duì)于平臺(tái)建造者與運(yùn)營(yíng)方是很重要的活動(dòng),但對(duì)于平臺(tái)買(mǎi)家來(lái)講卻遠(yuǎn)遠(yuǎn)沒(méi)有那么重要。

????????對(duì)于IPHONE X的買(mǎi)家關(guān)注的是花期望的價(jià)位,在期望的時(shí)間內(nèi)收到貨物,要保證他的購(gòu)買(mǎi)是沒(méi)有風(fēng)險(xiǎn)的。也不排除購(gòu)買(mǎi)者完全信任這這個(gè)平臺(tái),在其付款后,在收到貨物前完全不關(guān)注訂單狀態(tài),這樣的用戶(hù)關(guān)注的是購(gòu)買(mǎi)的最終狀態(tài)。

????????較為務(wù)實(shí)的買(mǎi)家仍是信任平臺(tái)的,但也想在付款后持續(xù)關(guān)注他的訂單是正確運(yùn)作的。因此,審慎的買(mǎi)家不是給平臺(tái)付款后就無(wú)人照管了,而是為購(gòu)買(mǎi)過(guò)程設(shè)立明確的里程碑,每個(gè)里程碑對(duì)應(yīng)著某一活動(dòng)的完成,并且僅當(dāng)里程碑在依次不斷的突破后,買(mǎi)家才會(huì)認(rèn)為他的訂單在正確的處理過(guò)程中。

????????接下來(lái)看一看,從買(mǎi)家下單到收到貨物,這個(gè)過(guò)程中還會(huì)有哪些里程碑呢。這里把里程碑都命名了該工程的一個(gè)穩(wěn)定狀態(tài):

? ? ? ? 對(duì)于平臺(tái)買(mǎi)家來(lái)講,跟蹤狀態(tài)變化比跟蹤活運(yùn)流更為重要,這些活動(dòng)流可能是平臺(tái)開(kāi)發(fā)人員用流程圖對(duì)平臺(tái)的工作流建模所做的。

????????對(duì)于系統(tǒng)設(shè)計(jì)也一樣,將發(fā)現(xiàn)可視化,詳述,構(gòu)造某些對(duì)象行為的最自然的方法是著眼于從狀態(tài)到狀態(tài)的控制流,而不是著眼從活動(dòng)到活動(dòng)的控制流。后者可以用流程來(lái)表示,對(duì)于前者,基于狀態(tài)機(jī)為整個(gè)系統(tǒng)生命周期建?;蚧贒DD的領(lǐng)域事件為系統(tǒng)建模都是可行方案之一。對(duì)于狀態(tài)機(jī)的應(yīng)用,在UML的時(shí)代非常流行,作為高級(jí)建模技術(shù),能夠完成對(duì)象或整個(gè)系統(tǒng)的生命周期建模,但對(duì)于復(fù)雜系統(tǒng)的系統(tǒng)生命周期建模復(fù)雜度很高,只在特定領(lǐng)域中應(yīng)用很普遍,像電信行業(yè)。隨著DDD的興起,業(yè)內(nèi)更傾向面向領(lǐng)域事件建模來(lái)完成這部分工作,這方面《Event Storming》實(shí)操性很強(qiáng)并且可以快速落地。

????????回到電商平臺(tái)案例,上文已經(jīng)識(shí)別出買(mǎi)家的關(guān)鍵里程碑,對(duì)于一個(gè)完整的系統(tǒng)應(yīng)由多個(gè)角色協(xié)作完成業(yè)務(wù)價(jià)值。為多個(gè)不同的角色在不同場(chǎng)景下實(shí)別出關(guān)鍵里程碑開(kāi)始,如果我們把系統(tǒng)所有相關(guān)角色的里程碑實(shí)別出來(lái),并按時(shí)間順序發(fā)布出去,結(jié)果如下圖。

????????特定領(lǐng)域中發(fā)生的一件事情稱(chēng)為領(lǐng)域事件,上圖中的每個(gè)里程碑即是系統(tǒng)中的領(lǐng)域事件,從整個(gè)系統(tǒng)生命周期的領(lǐng)域事件入手本質(zhì)上就是一種整體性的思考過(guò)程,要求我們用整體的觀點(diǎn)觀察周?chē)氖挛?,看清事件背后的結(jié)構(gòu)和各要素之間的互動(dòng)關(guān)系,并主動(dòng)地“建構(gòu)”和“解構(gòu)”系統(tǒng)構(gòu)建的各種可能。

????????以事件為線(xiàn)索進(jìn)行反推,是可以找到觸發(fā)事件的命令及命令的發(fā)出者的,命令執(zhí)行成功后產(chǎn)生事件。在實(shí)踐的過(guò)程中,經(jīng)常被問(wèn)到的問(wèn)題是查詢(xún)商品算不算命令?這里有一個(gè)權(quán)衡標(biāo)準(zhǔn),當(dāng)在超市購(gòu)物時(shí),我們也會(huì)查看貨架上的商品,大部分查看后并沒(méi)有對(duì)我和我的購(gòu)物車(chē)產(chǎn)生任何變化,這種沒(méi)有產(chǎn)生副作用的操作并不是命令,當(dāng)用戶(hù)看完一個(gè)商品,他做了放入購(gòu)物車(chē)的決定,那么,這個(gè)決定會(huì)改變其購(gòu)物車(chē)的狀態(tài)及后續(xù)的付款金額,即:有副作用的用戶(hù)決策,可以稱(chēng)之為命令。

????????得到命令后,很容易分析出命令的發(fā)起方,有可能是一個(gè)人或是一個(gè)系統(tǒng)。部分模型如下:


????????到目前為止我們帶著要解決的問(wèn)題做的問(wèn)題層面的分析,從買(mǎi)家如何在電商平臺(tái)上購(gòu)買(mǎi)IPHONE X開(kāi)始的,到不同角色關(guān)注的領(lǐng)域事件,命令與角色。是時(shí)候?yàn)閱?wèn)題設(shè)計(jì)解決方案了,解決方案是從上圖中抽象出系統(tǒng)元素,并看清它們之間的互動(dòng)關(guān)系,系統(tǒng)中的元素不要使用動(dòng)詞,要使用名詞。用動(dòng)詞來(lái)表述,得到的往往不是系統(tǒng)的結(jié)構(gòu),更像是在描述一個(gè)故事。分析后的模型如下:


????????在構(gòu)建任何系統(tǒng)時(shí)都是為了解決特定的問(wèn)題,如:構(gòu)建電商系統(tǒng)銷(xiāo)售所有數(shù)碼產(chǎn)品。對(duì)于問(wèn)題的處理最常用到的辦法是分而治之,將問(wèn)題域分解成多個(gè)子域,子域解決一個(gè)或多個(gè)小問(wèn)題,上圖中的系統(tǒng)關(guān)鍵元素就是小問(wèn)題的解決方案,這些元素我們稱(chēng)之為聚合。分而治之后,需要粘合這些方案協(xié)作解決整個(gè)系統(tǒng)要解決的問(wèn)題。這時(shí)應(yīng)該跳出單因思考方式,從全局看問(wèn)題,透過(guò)現(xiàn)象看本質(zhì),分析事物之間的關(guān)系。將子關(guān)鍵元素自下而上的抽象出對(duì)應(yīng)的子域后的部分結(jié)果是:

????????對(duì)于復(fù)雜的子域,有一些相似的問(wèn)題與模型,為了保證模型的整潔度,讓設(shè)計(jì)元素職責(zé)單一并有效的分離模型的關(guān)注點(diǎn),限定解決問(wèn)題的邊界可以幫助我們解決這個(gè)問(wèn)題。例如:對(duì)于商品目錄邊界內(nèi)商品的關(guān)注的屬性與物流邊界內(nèi)商品關(guān)注的屬性是不一樣,把它們建模成一個(gè)商品對(duì)象,會(huì)增加模型的耦合度,語(yǔ)義上也會(huì)存在二義性,在語(yǔ)義邊界內(nèi)建模會(huì)簡(jiǎn)化與解耦對(duì)象模型,將這種邊界與語(yǔ)義的限定稱(chēng)為限界上下文。


????????限定語(yǔ)義邊界內(nèi)的一組對(duì)象解決了系統(tǒng)中的一類(lèi)問(wèn)題,有了限界上下文,系統(tǒng)模型開(kāi)始從具體演進(jìn)到抽象,也方便從抽象層面確定模型之間的關(guān)系,DDD中稱(chēng)之上下文關(guān)系映射,從限界上下文層面將不同的子問(wèn)題聯(lián)系起來(lái)讓它們相互協(xié)作來(lái)解決問(wèn)題。下圖中用U(Upstrean)與D(Downstream)來(lái)表示上下游之間的關(guān)系,要注意上下游的方向,方向代表了特定的含義,如果U/D畫(huà)反,很可能會(huì)陷入思考的誤區(qū)。

????????上圖是我們面向領(lǐng)域事件建模的成果,如果作為微服務(wù)系統(tǒng)設(shè)計(jì)過(guò)程,你已經(jīng)完成了服務(wù)分析,服務(wù)設(shè)計(jì)與服務(wù)拆分,一般情況每個(gè)限界上下文會(huì)被建模成一個(gè)服務(wù),上文中提到的關(guān)鍵要素被建模成聚合。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容