18

示例:您的数据库具有名为“CustomerOrdersOnHold”的SQL视图。该视图返回特定客户和订单数据字段的过滤组合。您需要在应用程序中从此视图获取数据。如何访问这种视图适合存储库模式?你会创建一个“CustomerOrdersOnHoldRepository”吗?像这样的只读视图被视为聚合根?只读数据库视图如何适应存储库模式?

回答

24

我宁愿分开读库,优选地甚至更名为Finder或阅读器,资料库是指对于不用于查询只读数据的域用法,您可以参考this articlethis,它解释了Finder分离表单存储库的用法。

我也建议读模式的分离从写模型架构CQRSthere

这种架构可以让你即使在数据存储和使用事件采购方面,从写模型读取模型分开。

因为你可以利用一些CQRS概念,而不由刚刚从发现者分开储存库分离数据库的复杂中间的解决方案,对于这种类型的解决方案的样品阅读本post

(使用同一个数据库,但分离发现者表格存储库)检查this sample

+0

我认为这是最好的答案。这种类型的数据/对象与域无关,正如穆罕默德指出的那样,术语库与聚合/域/交易相关联,所以使用这个术语可能会产生误导。 CQRS旨在解决这个确切的问题。我回过头问了一个类似的问题:http://stackoverflow.com/questions/2098112/ddd-how-to-implement-performant-repositories-for-searching –

+0

伟大的答案,由于伟大的联系。这帮助我从另一个更清晰的角度看待我的代码。 –

+0

如果您有Finder,您如何命名“Saver”?库?但是,然后存储库应该能够访问数据AKA“查询”...如何解决这个问题? – JorgeeFG

0

我认为可以拥有一个像“CustomerOrdersOnHoldRepository”这样的独立存储库。存储库的接口将反映对象是只读的(通过不定义Save/Add/MakePersistent方法)。

How to write a repository

...但还有另一种策略,我很喜欢:多 库。在我们的订购示例中,我们没有理由可以拥有两个存储库:AllOrders和SurchargedOrders。 AllOrders代表 包含系统中每一单的订单,SurchargedOrders 代表它的一个子集。

我不会调用返回的对象一个Aggrgate根。聚合是为了一致性,数据交换和生命周期。你的物体没有任何这些。看起来它们也不能被归类为值对象('特征或属性')。他们只是独立的课程。

+0

我倾向于给视图自己的存储库,但是,这是我的理解是,存储库仅在聚合根上运行(http://thinkddd.com/glossary/aggregate-root/)。 –

+0

该规则是关于避免直接访问聚合的内部部分。你没有这些内部部件,就像你没有任何不变式和生命周期一样。可以从存储库返回这些对象。如果你喜欢,称它们为聚合根,但这可能有点误导。 – Dmitry

0

您的只读数据将被视为DDD世界中的值对象。

我通常会将值对象的访问方法放在现有存储库中,直到创建单独的存储库时才有意义。它类似于可能返回状态的静态列表是一个地址表上所使用的方法:

IAddressRepository 
{ 
    Address GetAddress(string addressID); 

    List<string> GetStates(string country); 
} 
+0

那么在你的场景中,如果我有一个CustomerRepository或一个OrderRepository,我会添加一个方法到这些仓库之一?即'ICustomerRepository.GetCustomerOrdersOnHold(args)'或'IOrderRepository.GetCustomerOrdersOnHold(args)'? –