首页 > 解决方案 > 最佳实践:如何在没有框架的情况下使用领域模型实现多对多关系

问题描述

你好stackoverflow成员,

我正在使用纯 PHP 来实现域模型。我有两个实体,实体doghuman充当狗主人的实体。

这是一个多对多的关系。Aowner可以拥有多个,dog并且 adog由许多人拥有humans(假设这只狗属于一个家庭或一对夫妇)。

我有一个数据库表,dog还有human一个 n:n 连接表。我有两个实体,它们是 POPO。而且我还有两个存储库,一个dog用于human. 这些存储库具有 crud 操作并负责数据库查询。

哪个存储库负责管理 n:n 表?

例子:

entitydog有一个属性数组,其中包含所有 connected human,反之亦然。如果我创建一个新的human喜欢:$human = new Human('name');并让他拥有一个已经存在的dog喜欢:$human->addDog($dog);谁负责 n:n 连接?我可以$dogRepo->Update($human->getDogs()[0]);更新数据库中的狗,或者我可以这样做$humanRepo->Insert($human)。DogRepo 是否也应该插入新的human(利用 HumanRepo)?HumanRepo 是否也应该更新dog(利用 DogRepo)。还是业务逻辑对此负责?(调用insertHuman()updateDog()与业务逻辑分开)。在所有这些方法中,我不知道哪个存储库负责 n:n 表?

听起来像是一个常见问题,但我在网上找不到合适的解决方案。

提前致谢!

标签: phpdatabasedomain-driven-design

解决方案


在 DDD 中,我们根据业务规则设计聚合。每个聚合都保护自己的不变量。当我们设计它们时,我们的脑海中没有表或关系表,只有不变量和一致性要求。

话虽如此,您遇到了困难,因为您没有确定不变量或没有。

拥有狗的人会以某种特定的方式行事吗?如果人类没有/确实拥有狗,是否会拒绝某些人类命令?Human然后,您将拥有的狗 ID(而不是狗实例!)列表添加到聚合中。

人类拥有的狗与没有主人的狗的行为是否不同?Dog然后将所有者 ID 列表添加到聚合。

还是它们之间的这种关系仅显示在 UI 中?然后将其添加为单独的聚合,即DogOwnershipByAHuman(id, dogId, humanId)不要用不需要的数据污染DogHuman聚合。


推荐阅读