2017-06-27 35 views
0

感覺就像我指的是上下文映射和反腐敗層的DDD主題,但我不知道如何解決它。外部數據映射到域

如何從外部數據源構造/映射域對象?

作爲一個例子,可能有多個數據源(db,文件,外部服務)。由於我試圖建立與洋蔥建築儘可能相似,這意味着我的域沒有依賴關係。基礎設施依賴於域(特別是基礎設施建設實現了域接口)

  1. 如果基礎設施必須依賴於域(而不是相反),這是否意味着外部數據映射應該在倉庫內進行?

  2. 如果通過構造函數創建對象被視爲業務邏輯(它不應泄漏到域中的任何位置),如何將外部數據映射到域對象?反射?其他方法?也許我誤解了整個概念?

  3. 如果域對象創建需要來自多個源(服務,文件,數據庫)的數據,是否意味着應用程序服務和從多個存儲庫中提取數據的基礎結構(存儲庫)之間應該有一個單獨的層,映射和返回結果域對象?

回答

1

如何從外部數據源構造/映射域對象?

我知道有兩種方法。

最常見的是應用程序通過對值的通用理解與域模型進行通信。應用程序接受它具有的表示形式(例如,文件中的字節),並從中構建一個表示域模型將理解的表示形式。您可以通過工廠(瞭解如何將原始值轉換爲值類型)或構建器來看到這一點。

更爲罕見的方法是,應用程序將它所具有的表示形式包裝到域模型將識別的適配器中(而不是構建具體類型)。在這種風格中,值類型看起來更像角色接口,使領域模型無視底層數據模型。

如果域對象的創建由來自多個倉庫拉數據的多個源(服務,文件,數據庫),豈不是應該有應用服務和基礎設施(倉庫)之間的單獨層需要的數據,不所有的映射和​​返回結果域對象?

我希望知識庫自己在做這項工作 - 知識庫的作用是對鍵值存儲的抽象。

Parnas wrote

我們建議而不是一個開始的艱難的設計決策或設計決策是有可能改變的列表。然後設計每個模塊來隱藏其他人的決定。

services/files/db的選擇是應該隱藏在模塊(存儲庫)中的一個決策示例,該模塊的接口「被選擇爲儘可能少地展示其內部工作方式」。

0

我更喜歡通過顯式實施反腐敗層來做到這一點。我的域通常接受命令來執行任何操作,這是域模型可以接受的。這包括創建對象和進行狀態轉換。

ACL部分從外部數據源讀取數據,或通過其他方式從它們接收數據。然後它將這些數據轉換爲有效的域命令。所有的預檢都通過ACL來完成,ACL既知道外部數據格式,也知道域。

有些情況下,一個外部事件會導致域中的多個操作,甚至跨多個有界的上下文導致多個操作。通常這是通過使用流程管理器完成的。

可能像您所描述的那樣,多個外部數據源需要查詢才能構建一個有效的域命令。在這種情況下,ACL只會這樣做,因爲域中只有一個事務。當外部來源也需要某種確認時,它可能會變得更加複雜,流程管理器也可能對此有用。