代码之家  ›  专栏  ›  技术社区  ›  RPM1984

DDD-我如何避免在这里跨越聚合边界?

  •  5
  • RPM1984  · 技术社区  · 15 年前

    我们正在开发一个新项目(重新编写现有的应用程序),我的域模型/存储库设计遇到了问题。

    以下是我们的域模型中两个关键部分的(简化)版本:

    alt text

    如你所见,我有一个抽象的概念 可以是评论、讨论、照片、视频等。帖子也可以有评论。

    我也有一个抽象的概念 位置 很明显是街道、城市、社区等。

    现在,我自然而然地认为这是两个清晰的聚合根。

    所以我创建了两个存储库,一个叫做 存储库 还有一个叫 位置存储库 .

    这一切都很好,我可以添加/获取任何类型的帖子(或评论),并通过这两个存储库之一添加/获取任何类型的位置。

    但是现在我正在为一个城市(例如)设计一个“登陆页面”。

    在这个页面上,我基本上需要显示“这个位置的所有帖子”。

    这是如何定义的?好吧,一个帖子可以(可选)在某个位置贴上标签。实现细节,所以我不想太深入地研究数据(因为这不是DDD的目的),但基本上有地理空间智能,可以通过位置的形状文件以及标记的位置的纬度/经度来确定在特定位置中包含哪些位置。

    但是我如何在不跨越边界的情况下检索这些信息呢?

    我使用哪个存储库?我需要一个新的吗?

    如果这很重要(或出于好奇),这是一个Web应用程序(ASP.NET MVC),带有SQL Server 2008数据库和实体框架4.0。

    如果你需要澄清,请告诉我。

    编辑

    我们目前使用规范模式的修改版本来检索域模型。

    例如,这是我们的BLL中用于检索所有评审的代码,其中score>=4:

    var reviews = postRepository // GenericRepository<Post>
          .Find() // IQueryable<Post>
          .OfType<Review>() // IQueryable<Review>
          .Where(x => x.Score >= 4)
          .ToList(); // List<Review>
    

    但现在我需要一些这样的代码:

    var reviews = postRepository
        .Find()
        .OfType<Review>()
        .Where( //lat long, or Locations FK )
        .ToList();
    

    问题是,我不知道如何在不添加中间联接实体(locationPost,因为它是多对多的)的情况下执行上述查询,并将FK添加到后域模型中。

    但是这样做,我就跨越了总的界限,不是吗?

    3 回复  |  直到 11 年前
        1
  •  6
  •   Szymon Pobiega    15 年前

    我会在创建时将post绑定到该位置,这样对于每个位置(通过存储库),我都可以获得相关post的列表。如下所示:

    创造:

    var p = new Post(latitude, longitude);
    var locations = locationRepository.FindByCoordinates(latitude, longitude);
    foreach (var l in locations)
    {
        l.AssociatePost(p);
    }
    session.Save(p);
    

    检索:

    var associatedPosts = postRepository.FindByLocation(locationId);
    foreach (var p in associatedPosts)
    {
        Display(p);
    }
    

    在引擎盖下,职位和位置之间的关联将实现为多对多表关系。此解决方案有一个问题:添加新位置需要扫描所有文章并将其分配到新位置(如果适用)。

    希望有帮助。

        2
  •  9
  •   Roger Johansson    15 年前

    为什么这是个问题? 根据埃文斯在他的书中所说,一个AR很可能引用另一个AR。 (但是,您不能从另一个ar引用ar中的子元素)

    此外,地点是否真的聚集了树根? 聚合根的定义是它充当一致性的边界。 这符合地点的定义吗? 我认为位置是一个价值对象。

    这里几乎有两个关于存储库和AR关联的营地:

    一个说所有聚合根 不得不 通过各自的存储库获取,AR应该使用软关系,例如它们之间的ID

    一种说法是聚合根可以很好地获取其他相关的聚合根,而存储库仅仅是查找聚合根的一种方法。

        3
  •  0
  •   Scott Whitlock    15 年前

    假设您使用了规范模式,可以使用location对象构建一个post规范吗?然后您只需将规范传递给您的post存储库,并返回结果。