日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于事件驱动架构构建微服务第2部分:领域对象和业务规则

發(fā)布時間:2023/12/4 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于事件驱动架构构建微服务第2部分:领域对象和业务规则 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文鏈接:https://logcorner.com/building-microservices-through-event-driven-architecture-part2-domain-objects-and-business-rules/

在本文中,我將實現(xiàn)領域模型:

  • EduSync.Speech.Domain

這是包含核心域的最內(nèi)層。它包含我們的領域?qū)ο蠛蜆I(yè)務規(guī)則。并定義我們的外部接口。

不允許使用數(shù)據(jù)庫、網(wǎng)絡連接、文件系統(tǒng)、UI或特殊框架。

核心領域?qū)ψ陨硪酝獾娜魏问挛镆粺o所知。

這些依賴項及其實現(xiàn)使用接口注入到我們的核心域中。

在上一步結(jié)束時,我們最終得到了一個貧血領域模型。所以讓我們從豐富它開始。

充血領域模型

貧血領域模型是DDD世界中的一種反模式,因此在本節(jié)中,我將使用值對象將領域模型與數(shù)據(jù)契約分離。

貧血領域模型是一種領域模型,其中數(shù)據(jù)和對該數(shù)據(jù)的操作彼此分離。換句話說,只有屬性的類和處理這些屬性的方法位于另一個類中。

因此,這些其他類既可以讀取數(shù)據(jù),也可以修改數(shù)據(jù)。所以領域類必須有public setter。這是缺乏封裝反模式。

讓我們從驗證Title開始。

我的第一個測試是:Title長度必須大于10個字符且小于60個字符:

測試將失敗,因此讓我們實現(xiàn)Title驗證:

Title值對象

實體和值對象的主要區(qū)別在于如何識別它們。

實體由引用相等和標識相等標識。

值對象由引用相等和結(jié)構(gòu)相等來標識。

  • 引用相等:如果兩個對象引用內(nèi)存中的同一個對象,則它們相等

  • 標識相等:如果兩個對象具有相同的標識,則它們相等

  • 結(jié)構(gòu)相等:如果兩個對象的所有成員都相等,則兩個對象相等

實體具有Id字段并且是可變的,而值對象沒有Id字段并且是不可變的。

值對象沒有實體就沒有意義,它必須屬于一個實體。

考慮以下情況:

  • 2輛相同型號、相同顏色、相同年齡等的車輛……總是2輛不同的車輛,因為每輛車都有自己的標識:車輛是一個實體。

  • 2個所有字段都相等的地址(相同的街道號碼、相同的城市、相同的國家,等等)是完全相同的地址:地址是一個值對象。

Title的第一個實現(xiàn)如下所示:

請記住,值對象由引用相等和結(jié)構(gòu)相等來標識.

所以右鍵單擊Title類并選擇生成 Equals和GetHashCode。

Title只有一個值,因此選擇它并單擊確定

Title現(xiàn)在是一個值對象,它的最終實現(xiàn)看起來像這樣

這是Title值對象的單元測試。如果它們具有相同的值,我應該驗證2個標題是否相等,如果不是,則不同

URL值對象

驗證Url的所有邏輯都在名稱為UrlValue的值對象中實現(xiàn)

Type值對象

驗證SpeechType的所有邏輯都在名稱為SpeechType的值對象中實現(xiàn)

Speech領域?qū)ο笕缦滤?#xff1a;

實體和聚合

請記住,實體由引用相等和標識相等標識并具有Id字段。因此,讓我們創(chuàng)建一個基本實體類:Entity,并在Id字段上生成Equals和GetHashCode。如果2個實體E1和E2具有相同的id,則 E1==E2應該返回true

DDD聚合是可以作為單個單元處理的領域?qū)ο蟮募骸@缬唵渭捌溆唵雾?#xff0c;它們將是單獨的對象,但將訂單(及其訂單項)視為單個聚合非常有用。

聚合應該始終處于有效狀態(tài),并且每個聚合都有一個根是一個實體,不屬于該聚合的類只能引用聚合根。

因此,讓我們創(chuàng)建一個繼承自Entity的基類AggregateRoot,我將其設為泛型,因為T是Id字段的類型,并且它可以根據(jù)這些實體而變化?

領域事件

領域事件通過避免直接調(diào)用來實現(xiàn)有界上下文之間的通信。所以一個有界上下文B1引發(fā)一個事件,一個或多個有界上下文B2…Bn對此事件的子訂閱方應該處理該事件以使用它。

因此,讓我們創(chuàng)建一個基類DomainEvent?

但是在這里,由于我實施事件溯源的策略,我的有界上下文產(chǎn)生的所有事件都將保存在我的事件存儲中。對這些事件感興趣的其他有界上下文、服務或其他程序?qū)⒈仨氂嗛喎湛偩€。

比如我每次創(chuàng)建一個新的Speech,然后我都會創(chuàng)建一個SpeechCreatedEvent事件

SpeechCreatedEvent類必須從DomainEvent基類繼承?

聚合根的最終實現(xiàn)將如下所示:?

因為Speech實體是聚合根,所以讓我們繼續(xù)從AggregateRoot繼承它,Speech實體的Id字段是一個 Guid

讓我們添加一些測試來覆蓋 domainEvents?

LogCorner.EduSync.Speech.Application和LogCorner.EduSync.Speech.Domain是100%的代碼覆蓋率?

歡迎關(guān)注我的個人公眾號”My IO“

總結(jié)

以上是生活随笔為你收集整理的基于事件驱动架构构建微服务第2部分:领域对象和业务规则的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。