如果你有两个处理持久性关系数据库的存储库,一个处理“Person”对象的人员库,一个处理“Address”对象的地址存储库,一个person对象有一个地址集合(可能是懒惰的)。显然,personrepository将用于持久更改person对象,addressrepository将用于持久更改地址对象,但是对于持久更改人员地址集负责的是什么?
有哪些策略可用于将人员对象地址集合的持久修改恢复到数据库?这个责任在哪里存放在存储库中(即使在数据库中它也是存储链接到人的地址)它是个人存储库吗?
我应该提到这不是使用ORM。
感谢您的任何帮助,我们将不胜感激任何策略/澄清。
答案 0 :(得分:5)
有点值得深思:
在决定如何解决问题之前,您需要回答两个问题:
如果对1.的回答是否,而对2.的回答是否定的 - 你不应该有一个AddressRepository,而Person应该负责将地址保存在与外键的正常的1对多关系中在地址中。否则,Person突然负责删除地址 - 或者需要对AddressRepository的引用 - IMO会以极其糟糕的响应能力结束。
如果对1.的答案是否定的,答案是2.是的 - 你有多对多的关系,而且人应该保持这种多对多的关系(因为这是唯一一个有知识的人)需要坚持下去。)
如果对1.的回答是肯定而对2.的回答是否定的 - 地址应该负责更新关系 - 并且应该具有合作伙伴属性,因此对象中的关联是单向的。
最后 - 如果两者都是肯定的 - 你再次拥有多对多的关系,但这次让地址处理多对多关联会更合理。
我希望这有助于您决定:)
答案 1 :(得分:3)
Goblin是正确的,我可以想象的场景非常少,需要一个你可能想要摆脱它的AddressRepository。
话虽如此,您想要查找的设计概念是“Aggregate Root”。很快,这意味着识别对象图中的对象,否则其他对象不能存在。这些是需要存储库的类,它们最终将成为对象图的网关。
当我第一次了解它时,这让我很困惑 - 我认为识别这些物体并不那么简单。出路是“Bounded Context”的附加概念。这可能是应用最少的设计原则。
简而言之,请考虑您正在解决以下两个用户故事。
所以你有类似下面的模型:
这似乎很难剖析。如果Person是根,那么当用户只是更改他们的信息时,我们必须使用Orders关联加载Person对象。如果他们下了很多订单(比如他们为公司管理库存),这可能会成为一个巨大的性能问题。
选择订单作为聚合根也不能解决问题。如果订单没有对某人的引用,那么我们如何能够检查所选地址是否有效?
旁白:老派对这些问题的回答分别是“延迟加载”和“双向关联”。然而,这两种技术都有其自身的复杂性,我确信它们通常比它们的价值更麻烦。
对这种看似冲突的解决方法(为什么我觉得我正在引导Eliyahu Goldratt?)是要承认这两个故事存在于不同的意义背景中。当用户存储地址时,他们不关心订单,同样当管理员正在检查地址时,他们并不关心它所针对的人。存在定义冲突。当两个上下文说“地址”时,它们指的是同一个物理对象,但只是两个截然不同的概念的试金石!就这个人而言,地址只是他们存储的一块测试。就物流经理而言,地址的唯一要求应该是与真实位置相关。
那么为什么甚至让它们成为同一个对象?
你看到发生了什么事吗?您已将问题分解为两个离散且不相关的系统,而且正如我们现在所知,小型,离散和聚焦系统是可维护软件的关键。
那么当这些情境需要沟通时会发生什么?由于两个上下文中的地址对象可能在不同时间使用(并且其中一个是只读的),因此可以想到使用相同的数据库。但是,这不建议(尽管许多人仍然这样做)。相反,两个域上下文之间的通信应该通过显式消息传递和映射机制(例如事件聚合器/消息传递总线)在代码中处理(如果有人知道这两者之间的区别,那么)。