2016-08-06 63 views
2

我最近開始探索域驅動設計並且有一個問題。假設我的應用程序中有一個Product,Category,Manufacturer域模型。和產品看起來是這樣的:在域驅動設計中獲取關聯聚合

public class Product 
{ 
int ProductId; 
string Title; 
string Description; 
double Price; 
int CategoryId; 
Category Category; 
Manufacturer Manufacturer; 
} 

總體上在顯示產品的詳細視圖,類別名稱和製造商名稱顯示(而不是它們的ID)。但類別和製造商是不同的聚合。問題是如何獲取製造商和類別名稱以及產品域模型。 ProductRepository將只返回產品域模型(與categoryId和ManufacturerId一起)。

  1. ,要麼是我的產品服務提出了另一個請求獲取 的CategoryId和ManufacturerId
  2. 或者當產品從產品存儲庫中取出,我可以獲取它們。

但我不需要所有的屬性,我只需要他們的標題。我面臨着所有領域模型的類似問題。

請幫我該如何解決這個問題。

回答

0

通常在顯示產品的詳細視圖中顯示類別名稱和製造商名稱(而不是它們的ID)。 ...問題是如何獲取製造商和類別名稱以及產品領域模型。 ProductRepository將只返回產品域模型(與categoryId和ManufacturerId一起)

正如我所看到的,類別名稱和製造商名稱用於顯示,因此它是介紹性關注。 我建議具有產品服務於某個屏幕單獨讀取模型只(見Command Query Responsibility Segregation (CQRS)):

public class ProductReadModel 
{ 
    int ProductId; 
    string Title; 
    string Description; 
    double Price; 
    string CategoryName; 
    string ManufacturerName; 
} 

有不同的方式來填充/構建模型:

  • 如果我們的使用ORM(例如NHibernate)在關係數據庫中持久化聚合,然後您可以使用原始SQL或輕量級ORM(例如Dapper)直接查詢數據庫。你不需要爲它庫,你只需要QueryHandler

  • 如果我們的聚集是事件來源,那麼你只需聽域事件(如CategoryNameChanged/ManufacturerNameChanged),然後項目(denormalise)他們入ProductReadModel並將其存儲在任何存儲(即使在內存中)。

  • 如果您的聚合在關係數據庫中持久存在,您還可以觸發並投影/取消規範域事件。

+0

謝謝你的迴應!如果我開始爲詳細信息頁面使用Read模型,我沒有在應用程序中看到很多DomainModel的用法。列表頁面也將獲取'閱讀模型'以及詳細信息頁面。只有在創建/編輯產品時,「域模型」可能會有用。它是否正確? – Pragmatic

+0

是的,當數據進入應用程序並強制實施不變量時,Rich Domain Model對您的寫入(創建/編輯)具有更多價值。使用域模型進行讀取(顯示列表/詳細信息)是過度殺毒,這通常會導致應用程序性能下降。 –

+0

因此,如果用戶想要從詳細頁面(使用讀取模型填充)編輯某個領域模型,應用程序服務將首先從數據庫中獲取領域模型,然後將所有值從讀取模型複製到領域模型,驗證它們和他們插入它?甚至在添加關聯的情況下:例如,在向產品添加標籤的情況下,服務將首先獲取產品域模型,向其子列表添加標籤,然後對其進行驗證並進行編輯? – Pragmatic

2

有多種方法可以處理這個問題:

本地緩存/視圖模型

保持在內存中的高速緩存中,在你的服務,它的CategoryId和CategoryTitle(同爲生產商)之間的映射 - 這可以通過:

  • 收聽一個事件(即CategoryCreated)。如果你有一個事件驅動的系統,這將是首選。如果相關,您還可以聽其他事件(即CategoryTitleUpdated)。
  • 通過向外部服務發出web請求。您將首先查詢本地緩存,然後決定是否調用外部服務。你需要考慮你的緩存有多陳舊。

Denormalising數據

您可以通過保存CategoryTitle旁邊的類別編號重複的數據。這樣你就沒有電話給外部服務。權衡是你需要考慮CategoryTitle可能改變的頻率以及你如何處理這種改變。

報告「域」

你可以有一個完全獨立的服務,監聽來自其他服務的數據,並保持視圖模型的用戶界面。這會讓您的其他服務無視其他服務的擔憂。當使用事件驅動的系統,你會偵聽事件形成其他的服務,讓您打造的UI

0

另外一個視圖模型@ tomliversidge的答案,我建議考慮在複合UI模式(你可以找到一個例子here)。

在那裏,您將有一個服務網關構建一個複合視圖模型,該模型由來自3個服務(產品,製造商和類別)的信息組成。