Domain driven design DDD-如何设计不同有界上下文之间的关联

Domain driven design DDD-如何设计不同有界上下文之间的关联,domain-driven-design,aggregateroot,bounded-contexts,Domain Driven Design,Aggregateroot,Bounded Contexts,我已经设置了一个域项目,该项目正在填充ORM。域包含多个不同的聚合,每个聚合都有自己的根对象。 我的问题是,应该如何处理跨越聚合边界的属性 这些属性是否应该忽略边界,以便有边界上下文a中的域对象引用上下文B中的对象 或者,上下文A到B之间是否没有直接链接,上下文A中的对象是否具有可用于通过B聚合根从B获取域对象的“int-ContextBId”属性 或者 一个例子: 上下文A=用户 上下文B=游戏 在Users上下文中有一个对象UserOwnedGames。此对象有一个属性User,它是对同

我已经设置了一个域项目,该项目正在填充ORM。域包含多个不同的聚合,每个聚合都有自己的根对象。 我的问题是,应该如何处理跨越聚合边界的属性

  • 这些属性是否应该忽略边界,以便有边界上下文a中的域对象引用上下文B中的对象
  • 或者,上下文A到B之间是否没有直接链接,上下文A中的对象是否具有可用于通过B聚合根从B获取域对象的“int-ContextBId”属性
  • 或者
一个例子:
上下文A=用户
上下文B=游戏

Users
上下文中有一个对象
UserOwnedGames
。此对象有一个属性
User
,它是对同一
Users
上下文中的对象的引用。对象还具有
游戏
的属性,该属性显然不在用户中,而是在
游戏
上下文中


这种关系会(或应该)是什么样子?这在数据库中很清楚(即2个外键),但代码应该是什么样子?

这取决于您使用的有界上下文策略

如果您选择共享内核,我认为它们之间有直接关系(直接引用或标识符引用,我相信其他人会在其他答案中解释优缺点)是好的。您还提到了通过数据库表集成的这些对象


但是,如果您选择反损坏层,您最好将它们分开(仅使用标识符来保持关系),使用适配器转换器进行集成(不进行数据库集成)。

您应该避免跨BC的DB引用-您不应该尝试确保来自不同BC(事务)的聚合之间的引用完整性。理想情况下,事务应该只存在于单个聚合中,甚至不存在于BC中

最好为ID使用简单的值对象——UserId和GameId——并在需要时将它们分配给实体。通过这种方式,这些“远程”实体完全分离,因此您不必担心它们的连接。可以使用消息传递平台实现同步

如果您有空闲时间,请阅读这些有价值的文章(由沃恩·弗农撰写):


听起来您的
用户
上下文还需要一个
游戏
实体。但是请注意,这不一定是作为
游戏
上下文根的同一
游戏
实体。这两个有界上下文可能对
游戏是什么以及它有什么属性有不同的想法。只有身份将两个游戏对象绑定在一起

User Context
{
    Aggregate Root User
    {
        Identity;
        Name;
        OwnedGames : List of Game value entities
    }

    Value Entity Game
    {
        Identity;
        Name;
    }
}

Game Context
{
    Aggregate Root Game
    {
        Identity;
        Name;
        Owner : User value entity
        HighScore : int
        TimesPlayed : int
        ... A whole bunch of other properties which are not relevant in the User context
    }

    Value Entity User
    {
        Identity;
        Name;
        // No OwnedGames property, in this context we don't care about what other games the user owns.
    }
}

非常有趣的概念。。我甚至从来没有想过要有同一事物的多个版本。在DDD中,没有关于事物“是什么”的全局、明确的概念,“事物”在某些上下文中只是一个“事物”。那么,如何处理跨上下文同步对同一属性的引用呢?假设我在用户上下文中更新User的Name属性,那么如何让它在游戏上下文中更新User的Name属性呢?当请求时,您是否使用getter跨上下文访问其他上下文?或者你有什么方法来同步这两个吗?嗨@Balrog30,这就是域事件的来源。看到这个Hi,但是如果我想在数据库级别强制执行数据完整性