我正在努力解決一個基本問題。該專案是在 C# 中,但問題是普遍的。
我遵循始終有效的物件原則。舉個例子,我有一個產品物體,它有一個強制屬性“ProductCategory”。允許的產品類別是用戶定義的,因此會保留(在資料庫中)。
為了型別安全和更好的閱讀,我為各種屬性定義了值物件來封裝這些型別的業務規則。所以有一個 ProductCategory 類。創建 ProductCategory 實體時,工廠方法會檢查例如在創建實體之前傳遞給工廠的字串的最大長度。這確保了 ProdcutCategory 的每個實體都是有效的。
簡單的引數檢查(如長度)既簡單又直接。我的問題是在哪里對持久化的可能值實施驗證檢查。允許值的存盤庫隱藏了持久性技術并具有方法 Exists 或 IsValid。
選項 1)在呼叫工廠之前從應用層呼叫存盤庫。
在這里,域層沒有像許多人提倡的那樣依賴于存盤庫/基礎設施層。但是工廠不能再確保一個有效的物件。業務規則的實作取決于應用層。此外,每個需要 ProductCategory 的命令都必須檢查存盤庫,這違反了 DRY。
選項 2)從值物件工廠呼叫存盤庫
由于工廠是域層的一部分,該層必須能夠訪問存盤庫,這會引入額外的耦合。好處是 ProductCategory 的業務有效性是由物件本身來保證的,不能被規避。
這種困境是否有另一種解決方案,或者是否有任何特定標準鼓勵一種或另一種選擇?如果工廠是針對保存在域層中的存盤庫的介面進行編程的,并且僅由基礎結構層中的存盤庫實作,那是否可以?我試圖理解不同的方法,但在這種情況下我感到迷茫。
uj5u.com熱心網友回復:
如果我理解正確,您的 ProductCategory 值物件會處理它自己的不變數,但是是否可以將特定 ProductCategory 分配給特定產品是用戶定義并存盤在資料庫中的。
您可以使用域事件:
- 您將類別分配給領域模型中的產品。
- 產品添加了一個域事件“ProductCategoryAssigned”。
- 在提交您的作業單元之前,DomainEvent 處理程式會檢查資料庫是否可以將特定類別分配給產品,如果沒有則拋出。
這將防止交易以無效狀態完成。
您可以使用 ValidatorAggregate:
如果您真的希望您的產品“始終有效”,甚至在提交作業單元之前,那么您可以選擇:
- 創建基于產品屬性加載有效類別的 ValidCategoriesAggregate 和 Repository。
- 您的產品的“SetCategory”方法(或工廠方法)將 ValidCategoriesAggregate 宣告為必需引數,強制您的應用程式層在呼叫工廠方法之前獲取一個。
- 在您的工廠方法中,您可以呼叫“ValidCategoriesAggregate.HasCategory(category)”并在創建產品之前拋出(如果不存在)。
盡量避免將存盤庫注入您的域模型。
uj5u.com熱心網友回復:
選項 2 似乎更好。
在這種情況下,耦合不是問題,您將工廠耦合到檢查驗證所需的查詢,使這種依賴關系顯式。
請注意,使此檢查最終不保持一致的唯一方法是將所有資料放在一個聚合中。否則,無法阻止在您進行檢查之后和提交事務之前創建相同類別的事實(這是聚合的真正原因)。
僅當存在真正的問題時才考慮最終的一致性,創建一個類別的頻率如何?產品多久創建一次?發生沖突的可能性有多大?如果發生這種情況有什么真正的問題嗎?
大多數情況下,完全一致比接受最終一致性要昂貴得多。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/326943.html
