簡體   English   中英

具有多個繼承聚合根的 DDD + CQRS 模式

[英]DDD + CQRS pattern with multiple inherited Aggregate Roots

免責聲明:我知道 DDD/CQRS 可能不是以下用例的完美選擇,但到目前為止它在項目中的其他任務上工作得很好,我想出於學習目的堅持使用它(例如,學習困難的方法不要使用它;)。

假設我正在構建一個博客平台並有 3 種類型的帖子: LifestylePostRecipePostReviewPost 它們具有相同的抽象基礎 class PostBase ,它是一個聚合根,它們都共享一些屬性,如Author或實現方法,如PublishDelete等,這些方法改變它們的Status並驗證 state 是否有效。 每個創建的帖子都以Draft開始,幾乎不需要任何驗證,但切換到已Published驗證幾乎所有屬性。

實現像PublishPostDeletePost這樣的命令/處理程序是一件輕而易舉的事,但是當我考慮CreatePostUpdatePost時問題就開始了。 這些是我目前面臨的一些困境:

  1. 為每個帖子類型或所有帖子類型創建/更新命令/處理程序

將它們分別用於每個帖子類型讓我可以更好地控制邏輯,允許精確地定制每個命令 model,但讓我的 API 對客戶來說更加復雜。 使用第二個選項,我可以通過命令中的一些鑒別器解析帖子類型,並檢查是否提供了該特定類型的所有必要屬性。

  1. 首先創建空的帖子草稿或已經填充了數據

當用戶創建新帖子(具有初始狀態的草稿)時,我已經可以調用 API 並向數據庫添加一個空帖子,然后更新該帖子,或者我可以等到用戶輸入任何數據並單擊保存。 這基本上是帖子構造函數中的 arguments 的問題。

  1. 一般處理帖子更新

這是我現在遇到最大問題的地方。 由於有相當多的屬性可以由用戶更改或不可以更改,因此很難將它們拆分為聚合根內的特定方法,而不僅僅是使用大量可為空的 arguments 進行Update ,其中 null 表示尚未提供該屬性由客戶提供,因此不會更改。 此外,在此處添加Status屬性意味着必須解決驗證 state 的正確方法。 這個解決方案在某種程度上不像是一個合適的 DDD 設計......

你會在每個點上做出哪些決定,為什么?

  1. 為每個帖子類型或所有帖子類型創建/更新命令/處理程序

取決於帖子類型的差異是否影響API。 如果您的客戶根據帖子類型與您的 API 進行了不同的交互,那么我將為每種類型提供特定的命令。 如果您的 API 與帖子類型無關,那么這是內部業務問題。 然后,您應該確保域實現因類型而異,因為多態域比簡單的“類別”屬性要多得多。

  1. 首先創建空的帖子草稿或已經填充了數據

取決於了解用戶已經開始處理草稿對您的系統是否有任何價值。 如果它像個人博客,可能不是。 如果您正在為報紙編寫軟件,那么它可能對任何人都具有洞察力。 詢問您的領域專家。

  1. 一般處理帖子更新

在我看來,這是一個界面設計問題,而不是業務邏輯問題。 如果你的用戶想要做很多小的改變,你應該考慮在你的 API 中提供 PATCH 路由,使用像JsonPatch這樣的標准。 根據您的實施技術,您可以從為您進行 object 修補的庫中受益,從而節省大量代碼編寫。

帖子類型之間的行為真的有區別嗎? 他們不都有Draft()Publish()Cancel()行為嗎?

鑒於 inheritance 表示X is a Y ,那么您基本上是在說它們都是一樣的。 這對我來說就像一個單一的Post聚合,在某處可能有一個“PostType”值可能是不變量的一部分(例如,如果你有一個業務規則說“評論帖子在冷靜期結束之前不能發布).

這將意味着一組應用程序服務來調用這些方法(並驗證它們實現的不變量)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM