【问题标题】:How to retrieve Aggregate Roots that don't have repositories?如何检索没有存储库的聚合根?
【发布时间】:2013-05-22 17:54:17
【问题描述】:

Eric Evan 的 DDD 书,第 1 页。 152:

仅为实际需要的 AGGREGATE 根提供存储库 直接访问。

1。 是否应该通过那些确实需要直接访问的聚合根的存储库来检索和保存不需要直接访问的聚合根?

例如,如果我们有 CustomerOrder 聚合根,并且无论出于何种原因我们不需要直接访问 Order AR,那么我假设只有 orders 可以是通过遍历Customer.Orders属性获得的吗?

2。 ICustomerRepository 应该何时检索订单?当Customer AR 被检索(通过ICustomerRepository.GetCustomer)或者当我们遍历Customer.GetOrders 属性时?

3。 ICustomerRepository 自己应该检索订单,还是应该将此责任委托给IOrderRepository?如果是后者,那么一种选择是将IOrderRepository 注入ICustomerRepository。但是由于外部代码不应该知道IOrderRepository 甚至存在(如果外部代码知道它的存在,那么它也可以直接使用IOrderRepository),那么ICustomerRepository 应该如何获得对IOrderREpository 的引用?

更新:

1

关于实现,如果使用像 NHibernate 这样的 ORM, 不需要 IOrderRepository。

a) 你是说在使用 ORM 时,我们通常不需要实现存储库,因为 ORM 隐含地提供了它们?

b) 我确实计划学习一种 ORM 技术(可能是 EF),但是从我读过的关于 ORM 的内容来看,似乎如果你想将域或应用层与持久层完全分离,那么这两层应该'不使用 ORM 表达式,这也意味着 ORM 表达式和 POCO 应该只存在于 Repository 实现中?

c) 如果存在某种情况,由于某种原因 AR root 没有直接访问权限(并且项目不使用 ORM),那么您对 ​​3. 的回答是什么?

谢谢

【问题讨论】:

    标签: domain-driven-design ddd-repositories aggregateroot


    【解决方案1】:

    我很难想到聚合不需要直接访问的示例。但是,我认为在撰写本文时(大约 2003 年),对限制或消除聚合之间的可遍历对象引用的强调并不像今天那样普遍。因此,Customer 聚合可能会引用 Order 聚合的集合。在这种情况下,可能不需要直接引用Order,因为从Customer 遍历是可以接受的。

    关于实现,如果使用像 NHibernate 这样的 ORM 完成,则不需要 IOrderRepositoryOrder 聚合只会有一个映射。此外,Customer 的映射将指定更改应向下级联到相应的Order 聚合。

    ICustomerRepository 应该何时检索订单?

    这个问题引起了人们对聚合之间的可遍历对象引用的关注。 ORM 提供的一个解决方案是延迟加载,但是lazy loading can be problematic。理想情况下,仅在需要时才检索客户的订单,这取决于上下文。因此,我的建议是避免聚合之间的可遍历引用,而是使用存储库搜索。

    更新

    a) 您仍然需要实现 ICustomerRepository 的东西,但是如果配置了映射,那么实现将非常简单——您将委托给 ORM 的 API 来实现每个存储库方法。但是不需要 IOrderRepository。

    b) 对于完全封装,存储库接口将不包含任何特定于 ORM 的内容。存储库实现将使存储库合同适应 ORM 细节。

    c) 很难对我无法想象的场景做出判断,但似乎不需要 Order 存储库接口,您仍然可以拥有一个 Order Repository 来更好地分离职责。也不需要注入,只需让 Customer repo 实现创建一个 Order repo 实例。

    【讨论】:

    • 我认为您通常不会将应用程序/域层与持久层完全解耦,仅仅是因为在应用程序/域层中使用 ORM 表达式提供了很多好处?
    • 视项目而定。有时抽象存储库实现并不是很有价值。其他时候它对于封装目的是有意义的。他们的关键是不要过度设计抽象。
    • 我认为最重要的是实际上要了解聚合存储库不是您的实体和存储库实现之间的 1 1 关系,存储库本身应该代表您的聚合的设计方式,因此,您的域,在您的情况下,您可以收集查询以在您的存储库中获取客户和客户订单,而无需进行对象遍历(假设您的客户订单可能会越来越大),但与往常一样,它依赖™
    猜你喜欢
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 2012-08-04
    • 1970-01-01
    相关资源
    最近更新 更多