領(lǐng)域驅(qū)動實(shí)戰(zhàn)-支付系統(tǒng)

在Airwallex,領(lǐng)域驅(qū)動設(shè)計(jì)(DDD)方法被用來指導(dǎo)我們的工程師如何對復(fù)雜的業(yè)務(wù)問題和系統(tǒng)設(shè)計(jì)建模。在這篇博客中,我們提供了一個全面的工作流,我們使用DDD模式進(jìn)行建模,然后對支付系統(tǒng)進(jìn)行落地。

簡介

全球支付系統(tǒng)是復(fù)雜和不斷變化的,涉及從訂單、欺詐、通知、與各種支付方式的集成到清算和結(jié)算等廣泛的板塊。

在處理復(fù)雜的系統(tǒng)時,大多數(shù)開發(fā)人員可能會遇到一些一致的問題:

  • 責(zé)任重疊:在一個應(yīng)用程序上使用一系列模型和戰(zhàn)略意味著邊界和職責(zé)不清晰。
  • 沒有隔離和模塊化:復(fù)雜的業(yè)務(wù)工作流程和流程融合在一起并難以擴(kuò)展。
  • 核心業(yè)務(wù)沒隔離:核心業(yè)務(wù)和戰(zhàn)略會給技術(shù)實(shí)施帶來挑戰(zhàn),這使得問題更加復(fù)雜。

在Airwallex,領(lǐng)域驅(qū)動設(shè)計(jì)(DDD)方法被用來指導(dǎo)我們的工程師如何解決復(fù)雜的業(yè)務(wù)問題和系統(tǒng)建模。

然而,DDD只是各種模式的集合,很難將其應(yīng)用于系統(tǒng)設(shè)計(jì)。在這篇博客中,我們提供了一個全面的工作流程,介紹了我們是如何在Airwallex應(yīng)用領(lǐng)域驅(qū)動設(shè)計(jì)的,從中得到的經(jīng)驗(yàn)教訓(xùn),以及我們接下來要做什么。

什么是DDD?

領(lǐng)域驅(qū)動設(shè)計(jì)(由Eric Evans提出)是一組幫助基于業(yè)務(wù)領(lǐng)域的底層模型設(shè)計(jì)軟件系統(tǒng)的思想、原則和模式。DDD有兩個不同的空間,問題空間和解決方案空間。

在問題空間中,您使用戰(zhàn)略模式定義系統(tǒng)的頂層的系統(tǒng)層次,這些戰(zhàn)略模式關(guān)注域、子域和通用語言的分析。

在解決方案空間中,采用戰(zhàn)術(shù)模式來提供一組設(shè)計(jì)模式,您可以使用這些設(shè)計(jì)模式創(chuàng)建領(lǐng)域模型。這些模式包括有界上下文、上下文映射、實(shí)體、聚合、領(lǐng)域事件、領(lǐng)域服務(wù)、應(yīng)用程序服務(wù)和基礎(chǔ)設(shè)施。這些戰(zhàn)術(shù)模式將幫助您設(shè)計(jì)既松散耦合又具有內(nèi)聚性的微服務(wù)。


DDD分層.png

在實(shí)戰(zhàn)中怎么使用DDD

下面是一個常見的案例:
一位顧客想在該商家的網(wǎng)站上購買一件價(jià)格為10美元的t恤。顧客可以用多種支付方式來支付這件t恤,比如Visa卡或微信錢包。在客戶支付后,商家會從支付網(wǎng)關(guān)收到一個通知,顯示客戶的支付已經(jīng)成功。然后,商家可以在Airwallex webapp中查看支付細(xì)節(jié),包括購買價(jià)格、商家費(fèi)用以及資金將何時進(jìn)入Airwallex Global Account錢包。

操作流程

  • 1.分析真實(shí)的業(yè)務(wù)用例來計(jì)算出問題空間中的領(lǐng)域和子域。通常,事件風(fēng)暴是最佳實(shí)踐。
  • 2.在解決方案空間中定義邊界上下文。
  • 3.在邊界上下文中,應(yīng)用戰(zhàn)術(shù)DDD模式來定義實(shí)體、聚合、域服務(wù)、域事件等。
  • 4.使用步驟3的結(jié)果來確定團(tuán)隊(duì)中的微服務(wù)。

下面是分析結(jié)果。

問題空間

領(lǐng)域

支付系統(tǒng)

子域

付款處理:商家可以通過各種付款方式接受客戶的付款。
金融:清算和解決商家的付款資金。

通用語言

付款意向:商家創(chuàng)建的訂單的價(jià)格,產(chǎn)品,客戶等。

付款嘗試:商家創(chuàng)建的交易以獲得訂單的客戶。

付款方式:客戶支付產(chǎn)品的方式。

付款結(jié)算:付款之 后錢進(jìn)入商家錢包。

付款視圖:匯總付款詳細(xì)信息視圖,包含與一筆付款相關(guān)的所有數(shù)據(jù)。

解決問題空間

有界上下文(BC)限定了域模型的范圍。根據(jù)對問題空間的分析結(jié)果,我們可以定義以下邊界上下文:

支付網(wǎng)關(guān): API網(wǎng)關(guān),為商家提供restful API來創(chuàng)建或查看支付。

支付核心模塊: 支付意圖,方法資源管理。

支付適配器: 與一個外部的PSP集成,例如微信,支付寶,Visa,萬事達(dá)等。

支付結(jié)算: 計(jì)算并結(jié)算商戶每次支付的原則和費(fèi)用。支付融合:支付明細(xì)匯總視圖。

下面是生成的上下文映射的一個示例:


圖片.png

領(lǐng)域模型

從上面分析的場景和通用語言中,我們可以確定以下聚合、實(shí)體、值對象和域事件:

圖片.png

領(lǐng)域服務(wù)

根據(jù)我們的經(jīng)驗(yàn),領(lǐng)域服務(wù)為單個聚合使用業(yè)務(wù)邏輯服務(wù),遵循單一責(zé)任。通常,我們將封裝領(lǐng)域倉儲、聚合修改和在領(lǐng)域服務(wù)中發(fā)布的領(lǐng)域事件。以PaymentAttemptExecutorService為例:


圖片.png

領(lǐng)域事件

領(lǐng)域事件可以使系統(tǒng)更具有可擴(kuò)展性,并避免任何耦合,且一個聚合不應(yīng)該決定其他聚合應(yīng)該做什么。


圖片.png

例如,當(dāng)PaymentCaptureCommand命令將支付狀態(tài)更改為已支付時,會發(fā)出領(lǐng)域事件PaymentAttemptCapturedEvent。在PaymentAttemptCapturedEvent的領(lǐng)域事件處理程序(EventHandler)中,我們可以在該業(yè)務(wù)邏輯上加上你想要的邏輯。例如,通知支付聚合有界上下文更新支付詳情,通知支付結(jié)算有界上下文計(jì)算結(jié)算金額和費(fèi)用。


圖片.png

基礎(chǔ)設(shè)施

在DDD模式中,基礎(chǔ)設(shè)施層作用于將核心業(yè)務(wù)領(lǐng)域與技術(shù)實(shí)現(xiàn)細(xì)節(jié)分開。該層通常采用ACL (anti - corruption-layer)模式。以領(lǐng)域倉儲為例:


圖片.png

領(lǐng)域倉儲只定義接口功能,但實(shí)現(xiàn)細(xì)節(jié)應(yīng)該隱藏在基礎(chǔ)設(shè)施層中,細(xì)節(jié)上你可以使用PostgreSQL或MongoDB來保存數(shù)據(jù)。例如,在基礎(chǔ)設(shè)施層中,PaymentAttemptPgRepository是基于PostgreSQL的特定實(shí)現(xiàn),而toPO是一個轉(zhuǎn)換器,用于將域?qū)ο驪aymentAttempt轉(zhuǎn)換為持久化對象。


圖片.png

基于領(lǐng)域模型設(shè)計(jì)的微服務(wù)

現(xiàn)在,我們已經(jīng)為支付系統(tǒng)定義了一組有界上下文,并在每個有界上下文中標(biāo)識了一組實(shí)體、聚合和領(lǐng)域事件服務(wù)。下一步是從域模型到應(yīng)用程序微服務(wù)設(shè)計(jì)。這里,我們選擇將一個有邊界的上下文映射到一個微服務(wù)。


圖片.png

收益

采用DDD可以提供許多好處,例如,在所有團(tuán)隊(duì)之間進(jìn)行清晰的溝通,以及在設(shè)計(jì)系統(tǒng)時使用成熟的模式來管理復(fù)雜性并提供更好的可伸縮性。

使用通用語言,我們可以實(shí)現(xiàn)更多的自描述類名和函數(shù)名。
使用聚合模式,我們可以實(shí)現(xiàn)清晰的邊界和單一的職責(zé)。
使用領(lǐng)域事件模式,我們可以分割核心業(yè)務(wù)流程,減少聚合之間的耦合。
通過基礎(chǔ)設(shè)施層和ACL模式,我們可以將核心業(yè)務(wù)領(lǐng)域模型與技術(shù)實(shí)現(xiàn)細(xì)節(jié)分離開來。通過限定上下文模式,我們可以派生出潛在的微服務(wù)候選對象。

挑戰(zhàn)及教訓(xùn)

在實(shí)踐中應(yīng)用DDD時,我們想要分享一些挑戰(zhàn)和經(jīng)驗(yàn)教訓(xùn):

  • DDD是一個復(fù)雜模式的集合,需要整個團(tuán)隊(duì)花費(fèi)很長時間來學(xué)習(xí)和理解,但是它會給您的系統(tǒng)來帶設(shè)計(jì)好處。
  • DDD沒有為如何落地應(yīng)用而提供一個框架。我們在本博客中提供的工作流程是我們的長期實(shí)踐得出的最佳實(shí)踐。
  • 重要的是不要被標(biāo)準(zhǔn)答案所限制。有時,討論一個模型名稱或邊界上下文定義可能會花費(fèi)您大量的時間。
  • DDD他是適合復(fù)雜的系統(tǒng)而不是適合所有的系統(tǒng)。

總結(jié)

  • 在這個博客中,我們談到了各種DDD的概念和策略,并提供了一個在Airwallex支付系統(tǒng)設(shè)計(jì)中應(yīng)用DDD模式的全面工作流程。
  • DDD模式是一個很大的主題(不可能涵蓋全部細(xì)節(jié)),但是我們想介紹一些關(guān)鍵的主題和實(shí)踐該模式的經(jīng)驗(yàn)。
  • 未來,我們將繼續(xù)深入研究DDD模式中的各個主題,如怎么進(jìn)行分層。領(lǐng)域事件存儲、上下文映射模式等,以及如何在系統(tǒng)設(shè)計(jì)中應(yīng)用它們。

原文地址:https://medium.com/@chaojie.xiao/domain-driven-design-practice-modeling-payments-system-f7bc5cf64bb3

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

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

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