簡體   English   中英

數據訪問層和DDD

[英]Data Access Layer and DDD

我正在嘗試學習域驅動設計的思想,並試圖找出應該將數據庫持久性代碼放在哪里。

通過《 Vaughn Vernon實施域驅動的設計》一書,我了解到存儲庫或數據庫操作(以及連接等)必須保留在Model項目(域模型上下文)本身中。 我的理解正確嗎?

我指的是他的IdentityAccessContext,AgilePMContext等示例,其中存在到存儲庫的接口。 我一直想擁有一個單獨的數據層,然后在此處添加一個層使我陷入循環依賴。 由於接口,實體是在模型中聲明的,因此對於數據層來說是必需的,因此需要從模型中引用數據層以實現持久性。

這是正確的還是我錯過了什么?

我不會說本身就有一個數據訪問層。

實際上,存儲庫使用數據映射器將域轉換為數據,反之亦然。

模型,服務或事務腳本必須使用存儲庫來獲取和持久化對象。 這里沒有循環引用:

  • 服務層注入一個或多個存儲庫以實現域操作。 也就是說,服務將知道如果需要對象並且不關注如何將它們轉換為數據,該怎么辦。
  • 存儲庫使用數據映射器來持久化並獲取數據(1)
  • 數據映射器通常是一個OR / M,例如Entity Framework,NHibernate,Dapper ...

此外,良好的DDD將強制控制反轉,這意味着:

  • 上層知道下層。
  • 較低層不擁有對較高層的任何引用。

總而言之,DDD沒有您所想的DAL,但它試圖抽象並封裝每個關注點,以使上層與基礎數據方法脫鈎。

關於循環參考物...

OP說:

由於接口,實體是在模型中聲明的,因此對於數據層來說是必需的,因此需要從模型中引用數據層以實現持久性。

仔細檢查您的聲明。 如果模型代表的抽象層比數據更高,那么為什么數據應該引用模型?

需要數據的是模型。 並且應該使用接口訪問數據,以使模型與數據訪問策略無關。 正如我之前在此答案中所說的,這稱為控制反轉

也許您認為數據層需要引用實體,因為您仍在考慮舊方法,但是如果您將關注點很好地分離並且使用數據映射器(或自己實現),則數據映射器只是可以將對象映射到原始數據,反之亦然,它不需要引用諸如域對象之類的具體類( 您應該問問自己,Entity Framework如何將您的實體持久化到您喜歡的數據庫引擎,甚至不了解這些實體(2) )。

無論如何,就像我之前在這個答案上所說的那樣,您不應該考慮DAL,而應該考慮一堆存儲庫和一個數據映射器,或者僅僅是存儲庫(請參閱異常(1) )。

通常,依賴項下層被實例化並使用依賴項注入模式提供給上層( 控制反轉的可能實現)。


(1)此規則的例外:如果我們不談論關系存儲,那么也許根本就沒有數據映射器,並且存儲庫通過訪問具有較低抽象/封裝級別的數據來實現其接口。 例如,如果存儲庫實現其操作以XML格式存儲數據,則它將在內部使用XDocument或XmlDocument,並且根本沒有實際的數據映射器。

(2)實際上,像Entity Framework這樣的OR / M框架可以通過配置知道您的模型如何。 雖然不需要編譯您的具體域的引用,但需要使用Code First或其他方法提供類映射)

通過《 Vaughn Vernon實施域驅動的設計》一書,我了解到存儲庫或數據庫操作(以及連接等)必須保留在Model項目(域模型上下文)本身中。 我的理解正確嗎?

存儲庫抽象(接口)應在域層中,但其具體實現在基礎結構層中。

請參閱他的書中的代碼示例: https : //github.com/VaughnVernon/IDDD_Samples/tree/master/iddd_agilepm/src/main/java/com/saasovation/agilepm ,例如domain / model中的TeamRepository接口和LevelDBTeamMemberRepository中的LevelDBTeamMemberRepository / adapter / persistence。

沒有循環引用,因為持久性與Domain緊密耦合,但是Domain僅在需要時才與持久性松散耦合(由於控制反轉,大多數情況下是通過依賴注入實現的)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM