跨聚合根边界的领域设计

本文关键字:边界 | 更新日期: 2023-09-27 18:03:03

我是一个DDD新手,在第一次尝试实现这些概念时很挣扎。我正在编写一个应用程序来管理不同用户的一些营销活动,因此活动是一个明显的聚合根,但我也有用户作为一个聚合根。

public class Campaign : IDomainObject
{
    public virtual int CampaignId { get; set; }
    public virtual string Name { get; set; }
    ...
    public virtual int UserId { get; set; }
    ...
    public virtual IList<CampaignEvent> Events { get; set; }
}
public class CampaignEvent
{
    public virtual int CampaignEventId { get; set; }
    public virtual int CampaignId { get; set; }
    public virtual int UserId { get; set; }
    ...
}

所以现在当我搜索要显示的活动列表时,我如何从Id中获得用户的名称?

如果我用与数据库无关的透视图设计模型,我将向两个对象添加UserName字符串并从那里进行开发。然而,我必须实际一点,并考虑这最终将如何与数据库来回转换,而且这个新模型似乎不会与ORM(目前是NHibernate,但我也不相信这与EF是可能的)一起工作。

在不损害DDD概念的情况下,有哪些中间相遇的解决方案可以实现在对象中获得一些可用的用户信息的目标?

跨聚合根边界的领域设计

我认为这里的关键是您要将思维过程更改为实体对实体或值对象关系。

在你建模你的类的方式,你有一个UserId作为一个属性,并谈论它,如果它是一个关系。我认为你想要传达的是Campaign和User, campaigns event和User之间的关系,等等。这是完全可以接受的一个活动是一个聚合根和一个用户是一个聚合根。当您搜索一个活动时,它将与用户有关系,因此如何获得名称是通过从用户实体获取名称。我们不想单独谈论Id,因为这破坏了我们试图建模的真实实体的表征。所以一个广告系列有一个/一个用户/用户集合,一个用户有一个/一个广告系列/广告系列的集合,而不是一个广告系列有一个用户id

如果您希望显示从ORM/域模型获得的某些结果集中的用户名,那么这有点问题。您不应该查询您的域模型。那么该怎么做呢?

嗯,你应该尝试合并一个查询/读取模型。应该开发一个非常简单的查询层。要获取数据,您有几个选项。在此过程中,你可能想要选择一些非规范化。您可以将用户id和名称作为值对象添加到聚合中,以便将其存储在事务性存储中。你的查询将能够访问,并有数据随时可用;否则,您的查询端将需要执行连接。

您还可以通过包含特定于视图的表的真正特定于读的存储来实现最终的一致性。

这种方法可能会带来更多的问题,但它并不像看起来那么麻烦。