【问题标题】:Best practice: how to implement many-to-many relations using Domain Models without framework最佳实践:如何在没有框架的情况下使用领域模型实现多对多关系
【发布时间】:2018-11-21 09:20:19
【问题描述】:

你好 stackoverflow 成员,

我正在使用纯 PHP 来实现域模型。我有两个实体,实体dog 和实体human 作为狗的主人。

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

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

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

示例:

实体dog 有一个属性数组,其中包含所有连接的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 表?

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

提前致谢!

【问题讨论】:

    标签: php database domain-driven-design


    【解决方案1】:

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

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

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

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

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

    【讨论】:

      【解决方案2】:

      两个存储库只应更改其对应的表,因为这是它们的主要功能(遵循Single responsibility principle)。这些存储库将由Service(具有用于管理关系的实用函数的包装类)包装,其中服务将负责正确更改两个数据库。所以这个服务可以有一个像assignDogToHuman($humanId, $dogId) 这样的函数,这个函数会调用两个存储库并相应地更改它们的数据。

      通过这样做,您可以确保存储库有一个职责(更新自己的表),而服务有责任管理dogshumans 之间的关系。

      这还为您提供了存储库层现在可替换的额外好处。 IE。如果您决定更改数据库(例如从 Mysql 到 MongoDB),则只需交换/更新存储库,因为 assignDogToHuman 调用的函数的实现应该保持不变,并且对于此服务,它并不重要底层数据库是。

      希望对你有帮助,有什么问题可以问

      【讨论】:

        猜你喜欢
        • 2014-09-25
        • 2010-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-05
        相关资源
        最近更新 更多