【问题标题】:Clarification in dealing with collections with the repository pattern使用存储库模式处理集合的说明
【发布时间】:2011-04-04 22:11:08
【问题描述】:

如果您有两个存储库处理关系数据库的持久性,一个处理“Person”对象的 personrepository 和一个处理“Address”对象的 addressrepository,并且一个 person 对象有一个地址集合(可能是延迟加载)。显然,personrepository 将用于持久化对 person 对象的更改,而 addressrepository 将用于持久化对地址对象的更改,但是什么负责持久化对 person 地址集合的更改?

有哪些策略可用于将人员对象地址集合的修改持久化回数据库?存储库中的责任在哪里(它会是个人存储库,即使在数据库中它是存储到一个人的链接的地址)?

我应该提一下,这不是使用 ORM。

感谢您的帮助,任何策略/澄清将不胜感激。

【问题讨论】:

    标签: design-patterns orm domain-driven-design repository-pattern


    【解决方案1】:

    Goblin 是正确的,我可以想象很少有场景会调用您可能想要摆脱它的 AddressRepository。

    话虽如此,您要查找的设计概念是“Aggregate Root”。很快,这意味着识别对象图中的对象,没有这些对象就不能存在其他对象。这些是需要存储库的类,它们最终将成为您的对象图的网关。

    当我第一次了解它时,我感到很困惑——我不认为识别这些物体会这么简单。出路是“Bounded Context”的附加概念。这可能是应用最不充分的设计原则。

    简而言之,假设您正在解决以下两个用户故事。

    • 作为用户,我希望能够在网站上存储所有以前的送货地址,以便在下订单时更轻松地访问它们
    • 作为一名物流管理员,我想要打印出我们需要运送到明天的所有地址,以便我可以相应地规划运送路线

    所以你有类似以下模型的东西:

    这似乎很难剖析。如果 Person 是根,那么当用户只是更改他们的信息时,我们将不得不加载带有 Orders 关联的 Person 对象。如果他们下了很多订单(比如他们为公司管理库存),这可能会成为一个巨大的性能问题。

    选择顺序作为聚合根也不能解决问题。如果订单没有对 Person 的引用,那么我们将如何检查所选地址是否有效?

    顺便说一句:这些问题的老派答案分别是“延迟加载”和“双向关联”。然而,这两种技术都有其自身的复杂性,我相信它们通常比它们的价值更麻烦。

    解决这个看似冲突的方法(为什么我觉得我在引导Eliyahu Goldratt?)是承认这两个故事存在于不同的意义上下文中。当用户存储地址时,他们不关心订单,同样,当管理员检查地址时,他们不关心它的对象。存在定义冲突。当两个上下文说“地址”时,它们指的是同一个物理对象,但只是作为两个非常不同概念的试金石!就个人而言,地址只是他们存储的一个测试块。就物流经理而言,对地址的唯一要求应该是与实际位置相关。

    那么为什么它们是同一个对象呢?

    你知道发生了什么吗?您已将问题分解为两个离散且不相关的系统,并且,正如我们现在所知,小型、离散和集中的系统是可维护软件的关键。

    那么当这些上下文需要通信时会发生什么?由于两个上下文中的地址对象可能在不同时间使用(其中一个是只读的),因此可以使用相同的数据库。但是,不建议这样做(尽管很多人还是这样做了)。相反,两个域上下文之间的通信应该通过显式消息传递和映射机制(例如事件聚合器/消息传递总线)在代码中处理(如果有人知道两者之间的区别的话)。

    【讨论】:

    • 你用什么来画那些花哨的图像? :)
    • 希望我可以将多个答案标记为正确,感谢另一个好答案。
    • @Arnis L. 这些都来自 yUml.me,有时也来自 websequencediagrams.com
    【解决方案2】:

    有点深思:

    在决定如何解决问题之前,您确实需要回答两个问题:

    1. 地址可以在没有人的情况下存在吗?
    2. 一个地址可以由多个人拥有吗?

    如果 1. 的答案是否定的,而 2. 的答案是否定的 - 你不应该有 AddressRepository 并且 Person 应该负责以正常的一对多关系与外键保存地址地址中。否则,Person 会突然负责删除 Addresses - 或者需要对 AddressRepository 的引用 - IMO 将以可怕的响应能力而告终。

    如果 1. 的答案是否定的,而 2. 的答案是肯定的 - 你有一个多对多关系,并且 Person 应该保持这种多对多关系(因为这是唯一一个知道需要持久化它)。

    如果 1. 的答案是肯定的,而 2. 的答案是否定的 - 地址应该负责更新关系 - 并且应该有一个合作伙伴属性,因此对象中的关联是单向的。

    最后 - 如果两者都是肯定的 - 你再次有一个多对多的关系,但这次让地址处理多对多关联会更合理。

    我希望这可以帮助您做出决定:)

    【讨论】:

    • 感谢您提供如此详尽的回答:)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多