2008-10-07 51 views
12

如果你有一個領域對象,並且你想要做一些有用的和中心的領域對象的責任,如確保它是有效的,你有時需要訪問相關對象的狀態以執行此驗證。如何避免貧血的領域層,並仍然有豐富的驗證和業務規則

如何避免域對象需要調用到存儲庫或數據訪問層?由於性能的原因,即使使用延遲加載,您也無法始終採用集合關係,而且您經常希望在域對象中執行查詢。您可以將存儲庫實現依賴注入到域中,但不是真正純粹且複雜的測試。

我總是放鬆一些事情,並允許使用DI從域訪問存儲庫。我沒有看到如何在複雜的應用程序中創建「純」域圖層的清晰示例,該應用程序並不貧乏,並且服務/應用程序層做了所有的咕嚕聲並且弄亂了應該成爲域對象內部的東西。

回答

12
  • 如果對象是一個值對象,它 應該是不可變的,施工期間驗證 。

  • 如果對象 是根聚集,且其 自己的狀態足以告訴你 如果它是有效還是無效,你可以在上面通過匯聚添加 驗證方法,其中 級聯。

  • 最後,我認爲這是你的主要 關注,如果你需要訪問 幾個相關對象(即是 不在同一集合),以確保 其中之一是有效的,你 明確需要在特定的驗證服務中將這種邏輯推回 。

我真的認爲注入服務和存儲庫到實體並不是最好的選擇。創建專門的服務似乎更合適,我不明白爲什麼它會導致你有貧血域對象。

簡而言之,如果您可以在不依賴服務或存儲庫的情況下驗證對象狀態,請讓對象在聚合根級別處理它。當您需要查詢服務或存儲庫時,或者當您需要其他實體時,則強烈考慮將此邏輯移到對象之外。

+0

注入到實體是保持域層解耦的主要思想。在實體中注入存儲庫是最佳選擇。你的專業服務是什麼意思?僅當命令的上下文跨越多個實體時才使用域服務。不應該有專門的實體服務。 「 - (2x減)」 – Tudor 2012-10-04 23:08:55

1

幾小時前我回答了一個類似的問題。答案中包含一些指導原則,當我嘗試用邏輯和行爲來豐富我的模型,但不會使依賴於與技術相關的東西變得骯髒。 Having trouble putting real-world logic into the DDD domain layer

該答案還鏈接到其他有用的資源。

祝你好運,隨時給我發郵件或問我關於DDD和避免貧血模型。這是一個有趣的話題,人們傾向於以不同的方式解決這個問題。