2010-03-23 13 views
2

如果您需要在頁面上生成只讀數據列表,並且該數據自然來自多個,可能包含5個或更多不同的儲存庫?在DDD中,您如何使用多個存儲庫進行只讀列表

我們使用的是DDD,並且通過存儲庫強制訪問我們的數據庫,但是出現了一種似乎不適合DDD的情況,我們試圖決定使用最佳模式。

例如,假設您有一個基於社區的網站,包括視頻,論壇,博客等。您有一個包含評論列表的論壇頁面。這很粗糙,但我希望它是有道理的。

<table> 
<tr><td>User Name (with possible link)</td><td>User's community score.</td><td>User Avatar</td><td>User's E-mail</td><td>User's blog</td><td>User's videos</td></tr> 
</table> 
<table> 
<tr><td>This is a comment.</td></tr> 
</table> 

所以每個註釋包含幾個不同的部分組成:一個用戶名,社區得分,化身,電子郵件,用戶的博客和用戶的視頻頁面。傳統上,這些信息都來自不同的存儲庫。

問題在於效率。存儲庫可以被最大化,但只能圍繞它們創建的集合。在您需要訪問位於多個存儲庫中的數據時,使用存儲庫對於讀取訪問而言效率低下。

我的解決方案是創建一個UserInformation DTO的有關信息,並放置方法在UserForumsRepository與簽名

ILIst<UserInformation> GetUserForumsUserInformationByForumPostID(int forumPostID). 

我的一位同事認爲,以這種方式使用DTO打破設計模式我們一直在使用並建議更好的方法是獲取論壇評論ID列表,然後將這些ID傳遞到各個存儲庫以返回結果。

我個人認爲,存儲庫的主要目的是封裝對CRUD的CUD部分很重要的業務邏輯,但應該以最有意義的方式生成只讀列表。如果合適的話,我認爲從存儲庫中完全刪除只讀列表方法(例如,在用於多個不同類型頁面的常用窗口小部件中)是有意義的。

你如何處理這種情況?

回答

1

回答#2

這是怎麼需要的是具體的倉庫和客戶端之間的額外服務層。有時,客戶端需要的與儲存庫層提供的不同,特別是在可以分發儲存庫的情況下。服務層允許您定義粗粒度方法並隱藏來自客戶端的細粒度細節。通過服務層,您可以將輕量級DTO傳遞到客戶端,而不是完整的業務對象。

要映射業務對象DTO的和反向,該工具Automapper變得很流行。

1

我討厭回答我自己的問題,但我沒有任何意見,我似乎找到了來自通常嫌疑犯的答案:福勒。

在我們的設計中,它與最簡單的DDD相同,我們的應用程序直接連接到我們的存儲庫以獲取和更新數據。但是,在更復雜的情況下,具體存儲庫和應用程序層之間還有一個額外的服務層。不要將對象從域模型傳遞到客戶端,而是傳遞DTO。根據Fower(PoEAA 401),你「......通常不能從領域模型中傳輸對象,......因爲這些對象通常連接在一個複雜的網絡中,即使不是不可能,也很難序列化「。 Fowler繼續說道:「相反,您必須從域對象傳輸簡化形式的數據。」

所以實際上,特別是在分佈式系統中,將DTO傳遞給客戶端是常態。服務層如何從域層組裝這些DTO應該對客戶端不感興趣。

我必須承認,我對福勒的這個陳述有點困惑。我非常喜歡在ASP.Net MVC中使用域模型的便利性。它在創建主從UI設計模式視圖時特別方便。當強類型視圖與客戶關聯時,它只需要一行代碼就可以包含CustomerOrders.ascx分部視圖(具有IList類型)並將customer.Orders傳遞給部分視圖。也許可以繼續這樣做,只要域對象沒有問題,但這是未來的問題。

+0

一個行爲較少的域模型是一個稱爲貧血域模型的反模式。我們使用dto來解決您遇到的問題。一個或多個存儲庫被組合起來,將多個實體映射到一個扁平dto,然後發送給客戶端。如果您將您的實體發送給客戶端,那麼您就會冒着域模型以不一致的方式進行狀態變異的風險。 – 2010-05-02 12:26:39

+0

您是在服務層還是在存儲庫層中執行此操作? – John 2010-05-03 16:20:50

相關問題