0

我有一个项目,我在其中使用了一些域模型。这些模型的 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 并存储数据。

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

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

4

1 回答 1

0

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

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

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

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

于 2019-06-05T12:23:27.367 回答