2009-09-25 39 views
6

已經看過這部影片由Greg Yound在DDD如何在內存變化中實現CQS?

http://www.infoq.com/interviews/greg-young-ddd

我想知道你怎麼能實現命令查詢分離(CQS)與DDD,當你在內存中的變化有哪些?

使用CQS,您有兩個存儲庫,一個用於命令,一個用於查詢。 以及兩個對象組,命令對象和查詢對象。 命令對象只有方法,沒有屬性可以暴露對象的形狀,並且不能用於在屏幕上顯示數據。 另一方面,查詢對象用於在屏幕上顯示數據。

在視頻中,命令總是進入數據庫,因此您可以使用查詢存儲庫來獲取更新的數據並在屏幕上重新顯示。

您可以在ASP.NET中使用類似於和編輯屏幕的CQS,其中在內存中進行了更改,並且屏幕需要隨着更改更新幾次,然後將更改持久保存到數據庫中?

例如

  1. 我取從查詢信息庫中查詢對象,並在屏幕上顯示出來
  2. 我點擊編輯
  3. 我重新獲取距查詢對象庫的查詢對象和顯示它編輯模式下的表格
  4. 我更改表格上的一個值,該表格自動取消並取回命令對象併發出相關命令
  5. 如何做:我現在需要顯示更新因爲命令對計算字段進行了更改。由於命令對象尚未保存到數據庫,因此無法使用查詢存儲庫。而且對於CQS,我並不打算暴露命令對象的形狀以顯示在屏幕上。如何獲取查詢對象,並將更新後的更改顯示在屏幕上。

我能想到的幾個可能的解決方案是擁有一個會話存儲庫或從命令對象獲取查詢對象的方法。 或者CQS不適用於這種情況?

在我看來,視頻中的變化直接持續到數據庫中,我還沒有找到一個CQS DDD的例子,它解決了批量更改域對象和更新視圖的問題在最終發出保存域對象的命令之前修改域對象。

回答

1

如果你確實想用CQS來做這件事,我會說Query repo和Write repo都有一個對同一個後備存儲的引用。通常這個引用是通過外部數據庫 - 但在你的情況下,它可能是一個列表<T>或類似的。

+1

感謝您的回覆。 我想知道如果在內存中進行更改時使用CQS,而不是直接持久保存到數據庫,設計有多普遍/好? 這基本上是我們提出的是使用會話存儲庫允許查詢存儲庫通過會話變量訪問命令數據。 稍後可能需要HttpContext存儲庫。 有沒有人見過這個實現?感謝讚賞。 – Ian 2009-10-05 10:43:45

+0

在我看來,你用來操縱數據源的方法不應該依賴於數據源的種類。 Repository模式允許您將這些差異抽象出來,使您可以將任何數據源視爲可查詢的對象集合。這取決於個人存儲庫實現以確定目標數據源 - 因此理論上你會有一個「InMemoryRepository」和「DatabaseRepository」 - 或者你有什麼。 – 2009-10-05 14:32:20

+0

是的,我明白你可以交換數據庫存儲庫的InMemory存儲庫。 CQS的部分價值在於您向數據庫發出命令,並分別使用查詢存儲庫將更新的數據回拉。在內存中,命令對象處於會話中,因此查詢存儲庫只能撤回命令對象中的數據。使用數據庫版本,那麼查詢對象可以完全不同於命令對象,看起來與內存CQS的關係更接近。想知道這與CQS試圖實現什麼相吻合 – Ian 2009-10-06 13:25:11

0

在內存中,您通常會使用Observer design pattern

實際上,你總是希望使用這種模式,但是當數據庫中的某些內容發生變化時,大多數數據庫並不能提供一種有效的方法來調用應用程序中的方法。

+0

不知道。 使用CQS,您將讀取與寫入分開。 Query儲存庫與Write儲存庫分開。 因此,如果我沒有將域實體保存到存儲庫,那麼查詢存儲庫如何獲取數據? 我是否需要一種方法來從域對象獲取查詢對象,更新狀態,還是你說查詢對象會觀察域對象並更新自身? 或者可能引入會話存儲庫? – Ian 2009-09-25 14:21:54

0

Patterns of Enterprise Application ArchitectureUnit of Work設計模式與CQS很好地匹配 - 它基本上是一個堅實的東西在數據庫中的大命令。

+0

感謝您的鏈接,但仍然不回答我的問題。 基本上用CQS你有一個只有方法(命令)的對象和另一個包含對象形狀的對象。 有兩個存儲庫,一個用於命令對象,一個用於查詢對象。 因此,您從不使用命令對象重新填充屏幕,而是使用查詢對象。 如果不將命令對象的更改保存到數據庫,如何重新顯示通過調用命令所做的更改? 由於更改不在數據庫中,因此無法使用查詢存儲庫。 – Ian 2009-09-30 11:25:09

3

因此,這聽起來像你想在這裏是一個更細化的命令。

EG:用戶與網頁進行交互(假設使用購物車進行結賬)。

獲取信息的多頁正在構建命令。直到用戶實際上檢查出所有信息在單個命令中發送到域的位置,我們稱之爲「CheckOut」命令。

演示模型對抽象這種類型的交互非常有幫助。

希望這會有所幫助。

格雷格

+0

Hi Greg, 你有這樣的例子嗎? 目前,我走下了查詢對象的路線,並將其放入一個「購物車」對象,該對象序列化查詢對象以允許在回發之間進行更改(也可以使用會話)。 一旦對象完成更新,它就被傳遞給命令對象。 如果我有更多時間,那麼可以使用與查詢對象不同的對象來將它們存儲在編輯更改中,例如演示文稿模型。 我使用相同的對象來顯示和編輯,這是否與您提出的演示模型一樣? 謝謝 – Ian 2009-11-18 11:36:26

1

也爲您的疑慮休息...

這些更使最終一致性的擔憂,而不是CQRS。您不需要最終與CQRS保持一致,就可以使命令的處理以一致的方式寫入報告存儲(或使用與上述相同的實體存儲)。實際上,我建議人們將其作爲基礎架構來完成,並在以後逐步實現,並在需要時引入最終一致性,因爲與此相關的成本與此相關。

+0

不確定這是否適用於我的情況,到目前爲止只有一個數據庫,因此不必擔心更新報告存儲區,並且命令對象使用NHibernate,因此更改會持久保存回數據庫。 或者這是否適用於我的情況?不確定你指的是哪一個? – Ian 2009-11-18 11:51:03

-2

JdonFramework是CQRS DDD Java框架,如果你明白我的問題是提供一個域事件+異步模式,更多的細節https://jdon.dev.java.net/