6

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

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

替代文字

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

我还有一个Location的抽象概念,显然是 Streets、Cities、Neighbourhoods 等。

现在,这在我看来自然是两个清晰的总根。

所以我创建了两个存储库,一个名为PostRepository,另一个名为LocationRepository

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

但是现在我处于一个城市的“登陆页面”的场景中(例如)。

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

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

但是我怎样才能在不跨越边界的情况下检索这些信息呢?

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

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

如果您需要任何澄清,请告诉我。

编辑

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

例如,这是我们 BLL 中用于检索所有评分 >= 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 添加到 Post 域模型。

但是通过这样做,我跨越了总体界限——不是吗?

4

3 回答 3

9

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

另外,位置真的是聚合根吗?聚合根的定义是它充当一致性的边界。这符合位置的定义吗?我会说位置是一个价值对象。

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

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

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

于 2010-11-26T09:36:45.787 回答
6

我会在创建时将帖子绑定到该位置,以便对于每个位置我可以(通过存储库)获取相关帖子的列表。它看起来像这样:

创建:

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);
}

在后台,帖子和位置之间的关联将实现为多对多表关系。此解决方案存在一个问题:添加新位置需要扫描所有帖子并将它们分配到新位置(如果适用)。

希望有帮助。

于 2010-11-26T05:30:43.140 回答
0

假设您使用了规范模式,您可以使用 Location 对象构建 Post Specification 吗?然后您只需将规范传递给您的帖子存储库,然后返回结果。

于 2010-11-26T03:44:50.590 回答