gpt4 book ai didi

repository - 应如何表示将聚合根添加到存储库?

转载 作者:行者123 更新时间:2023-12-04 19:23:21 24 4
gpt4 key购买 nike

假设我们有一个类型为 Order 的聚合根实体,它关联客户和订单行。当我考虑订单实体时,更自然地将其概念化为没有 Id 就没有定义。没有 Id 的订单似乎比订单更好地表示为订单请求。

要将订单添加到存储库,我通常会看到人们在没有 Id 的情况下实例化订单,然后让存储库完成对象:

class OrderRepository
{
void Add(Order order)
{
// Insert order into db and populate Id of new order
}
}

我喜欢这种方法的一点是,您正在向 OrderRepository 添加一个 Order 实例。这很有意义。但是,订单实例没有 ID,在存储库的使用者范围内,订单没有 ID 对我来说仍然没有任何意义。我可以将 OrderRequest 定义为 order 的一个实例并将其添加到存储库中,但这感觉就像从一个橙子中获取一个苹果,然后将它添加到一个橙子列表中。

或者,我也看到了这种方法:
class OrderRepository
{
Order AddOrder(Customer customer)
// It might be better to call this CreateOrder
{
// Insert record into db and return a new instance of Order
}
}

我喜欢这种方法的一点是,没有 Id 的订单是未定义的。在创建和返回订单实例之前,存储库可以创建数据库记录并收集所有必需的字段。这里的味道是,您实际上从未将订单实例添加到存储库中。

无论哪种方式都有效,所以我的问题是:我是否必须接受这两种解释中的一种,或者是否有最佳实践来模拟插入?

我发现这个答案很相似,但对于值对象:
how should i add an object into a collection maintained by aggregate root .当谈到值对象时,没有混淆,但我的问题涉及具有从外部源(自动生成的数据库 ID)派生的标识的实体。

最佳答案

我想首先排除第二种方法。这不仅看起来违反直觉,而且还违反了几个好的设计原则,例如 Command-Query SeparationPrinciple of Least Surprise .

其余选项取决于域逻辑。如果领域逻辑规定没有 ID 的 Order 没有意义,那么 ID 是 Order 的必需不变量,我们必须对其进行建模:

public class Order
{
private readonly int id;

public Order(int id)
{
// consider a Guard Clause here if you have constraints on the ID
this.id = id;
}
}

请注意,通过标记 id字段为 readonly我们使它成为一个不变量。对于给定的 Order 实例,我们无法更改它。这与 Domain-Driven Design 完美契合的 实体图案。

您可以通过将 Guard Clause 放入构造函数来进一步强制执行域逻辑,以防止 ID 为负数或零。

到现在为止,您可能想知道这如何与数据库中自动生成的 ID 一起工作。好吧,它没有。

没有好的方法可以确保提供的 ID 尚未被使用。

这让您有两个选择:
  • 将 ID 更改为 Guid。这允许任何调用者为新订单提供唯一 ID。但是,这也要求您使用 Guid 作为数据库键。
  • 更改 API 以便创建新订单不采用 Order 对象,而是采用您建议的 OrderRequest - OrderRequest 可能与 Order 类几乎相同,但减去 ID。

  • 在许多情况下,创建新订单是一项在任何情况下都需要特定建模的业务操作,因此我认为进行这种区分没有问题。尽管 Order 和 OrderRequest 在语义上可能非常相似,但它们在类型层次结构中甚至不必相关。

    我什至可以说它们不应该相关,因为 OrderRequest 是 值对象 而 Order 是 实体 .

    如果采用这种方法,AddOrder 方法必须返回一个 Order 实例(或至少是 ID),否则我们无法知道刚刚创建的订单的 ID。这让我们回到 CQS 违规,这就是为什么我倾向于 更喜欢实体 ID 的指南 .

    关于repository - 应如何表示将聚合根添加到存储库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2096705/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com