2011-05-31 34 views
1

我目前正在基於DDD原則爲產品/派對管理系統創建概念驗證。其中一個要求是,派對數據(客戶,經銷商)將存儲在網絡上的CRM中,產品特定數據將存儲在內部SQL數據庫中(見下文)。DDD,BoundedContexts,域事件和事務

CRM系統(基於web)
客戶(包括姓名,地址,電子郵箱,聯繫偏好等)
經銷商(包含姓名,地址,工作狀態)

產品系統(內部部署)
BaseProduct(限定了香草產品)
ResellerProduct(限定了基本產品將由經銷商出售的定製) CustomerProduct(限定了產品,其客戶爲REG istered)。

我一直在對我如何實現解決方案的不同方法進行大量的研究,但我正在努力理解所有概念以及它們如何應用於我的問題。

我開始將區域分割成2個不同的有界上下文,Party和Product。我爲這些上下文中的每一個定義了域模型,並且在實體引用另一個模型中的概念時,我將它們留作簡單的Guid ID(即產品域中的CustomerProduct將具有相關Guid的CustomerRef值)。

然後我實現了一個派對基礎設施實現,它使用API​​調用Web CRM和使用NHibernate的產品基礎設施實現。對於每一個我實現了UnitOfWork,所以我可以控制每個上下文中的事務處理。應用程序層將在運行時注入兩個上下文並使用它們。

例如:

  • ApplicationService.RegisterNewProduct(客戶ID,產品編號 )
  • 開始 工作(PartyUnitOfWork.Begin(), ProductUnitOfWork.Begin())
  • 的每個單元的交易
  • 使用每個上下文 的存儲庫來查找相關域對象 (Party.Customer.Find(Id), Product.ResellerProduct.Find(Id))
  • 執行邏輯來確定是否 客戶符合資格,產品 有效等
  • 創建一個新的CustomerProduct並保存 到產品的系統
  • 提交各上下文的UnitOfWork

然後我開始探索有限的上下文有點進一步,並且正在考慮重構應用程序,以便每個上下文對另一個上下文的概念表示有限,但只針對該上下文。即在產品上下文中,我將擁有一個客戶實體,該客戶實體具有Id,Name和Active狀態,但可能沒有聯繫首選項等。然後,我會使用DomainEvents協調不同系統之間的活動,以使其數據保持最新(即If在CRM系統中創建了一個新客戶,產品系統會提出和處理一個事件以更新其客戶表示)。因此,上面的例子會改變,所以只使用了產品上下文。

爲了進一步混淆事項,比如說'RegisterNewProduct'調用也創建了一個新的Customer,我是否會在Product系統中創建客戶並提出一個由Party系統處理的'NewCustomer'事件?

我希望收集人們對這些想法的評論?

+1

爲什麼你需要兩個概念?在這些情況下是否有任何術語具有不同的含義?如果沒有歧義,我會從一個簡單的上下文開始,然後將其分割爲大小無法管理的大小。 – 2011-06-02 06:36:20

+0

理想情況下,我只想要一個上下文,即具有CustomerProducts集合的Customer。然而,因爲在這種情況下,客戶和客戶產品將在不同的系統中,我認爲他們需要分開。因此,我將有一個持久層與CRM實體交互,另一層與數據庫實體交互。我不確定我會如何構造它;我有一個持久層可以處理通過NHibernate訪問CRM和數據庫嗎? – watsite 2011-06-02 11:47:41

+0

我認爲你如何存儲和檢索你的數據是一個技術細節,你應該將這個邏輯深入到存儲庫實現中。 – 2011-12-11 10:53:08

回答

1

除了我的評論/問題,您所描述的UnitOfWork方法存在根本性問題。其中一個單位會犯一類問題,一個單元會失敗。您將最終得到一個跨兩個上下文的分佈式事務。

如果您確實需要擁有多個綁定上下文,那麼對於有界上下文的更好(主觀)方法是在它們之間進行基於消息的異步通信。您可以在一個上下文中執行鍼對聚合的命令,並在相同的事務中執行鍼對持久化數據庫更改的命令(例如,通過NServiceBus或MassTransit)發佈消息(事件),以發生事件。另一個上下文接收消息/事件並作出反應。

如果你是一個純粹主義者,你可以使用這種方法來進行所有集合間通信。通過這樣做,您可以刪除擁有工作單元的要求。

它有什麼意義嗎?

+0

感謝您的評論。我同意你詳細描述的UnitOfWork問題,這就是讓我考慮使用有界上下文的原因,因此每個上下文只會與一個數據存儲進行交互。關於具有事件的應用程序的結構,我是否需要在一個系統中表示數據並引發事件,即在產品系統(數據庫支持)中,我有一個客戶的概念,這是一個客戶的概念,我稱之爲客戶.assignToProduct(產品),這會引發CRM系統可以處理的事件並更新其客戶/產品表示? – watsite 2011-06-02 11:54:23

+0

客戶 - 產品關係是否存儲在兩個系統中?誰擁有這種關係? – 2011-06-03 12:02:14

+0

理想情況下,如果是一個系統,我會將客戶作爲聚合根,並且它將擁有與客戶產品的關係。但是,因爲客戶將位於雲中的CRM以及內部數據庫中的CustomerProduct之間,所以兩者之間的關係將被拆分,並且最終將爲客戶關係管理客戶聚合根和客戶內部系統的CustomerProduct根。我想知道的是,如果我應該在預測系統中創建客戶的概念以更好地反映這種關係? – watsite 2011-06-03 12:24:19