【问题标题】:How do I design a model with generated ID如何设计具有生成 ID 的模型
【发布时间】:2019-06-05 09:29:18
【问题描述】:

我有一个项目,我在其中使用了一些领域模型。 这些模型的 ID 是确定性的,仅取决于对象的内容。两个属性相同的对象将具有相同的 ID。这适用于我模型的任何对象。

此计算是递归的,这意味着它会遍历引用并将它们自己的 ID 合并到计算中。它基本上是一棵默克尔树。

例如,如果我有一个 A 类和 B 类如下:

public class A {
   public string Value { get; }
   public B RefToB { get; }
}

然后我将计算 RefToB 的 ID,然后将所有内容序列化为字节,然后计算此字节数组的 SHA1,以获得另一个字节数组,这将是我的最终 ID。

我将使用计算出的 SHA1 将对象的字节存储到专门为我的目的定制的 KeyValue 存储中。

这让我可以很容易地比较子树。

现在,我不想添加构建无效模型对象的可能性,因此我无法将 byte[] id 参数添加到构造函数中,因为它是计算值。

我使用 DTO 模型映射,我的商店使用 DTO 来计算 ID 并存储数据。

我尝试坚持六边形架构,这意味着我有一个持久性项目和一个域模型项目,域没有依赖关系。

问题是:我觉得我做错了设计,但我无法很好地解释我的错误行为。你认为我应该以不同的方式进行这个设计吗?

【问题讨论】:

    标签: c# oop domain-driven-design hexagonal-architecture


    【解决方案1】:

    如果你要创建一个值对象,这意味着你的对象的内容是不可变的,那么这个值对象应该在内部生成这个 ID。这是你的领域的一部分,这是业务逻辑,所以它必须是你的价值对象的一部分。

    在java中,它就像一个hashCode,在对象内部计算。

    这不是您的 DTO 工作,而是您自己的目标。通过这样做,您可以使它们更正确,无法破解并传递会使您的模型无效的错误值,并且也更容易测试:创建两个具有相同值的不同对象,并检查它们的 ID 是否相等。很简单!

    如果您要使用同样适用的可变对象,只需即时计算您的 ID,而不是在构造函数中创建实例时计算。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-03
      • 2023-03-20
      • 2010-11-11
      • 1970-01-01
      • 1970-01-01
      • 2018-12-09
      • 1970-01-01
      相关资源
      最近更新 更多