我有一个使用某些领域模型的项目。 这些模型的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和存储数据。
我尝试坚持六角形的体系结构,这意味着我有一个Persistence项目和一个Domain模型项目,domain没有依赖项。
问题是:我觉得我做错了设计,但是我不能对我做错的事情给出很好的解释。您认为我应该以不同的方式进行此设计吗?
答案 0 :(得分:0)
如果要创建值对象,这意味着对象的内容是不可变的,则此值对象应在内部生成此ID。这是您域的一部分,也是业务逻辑,因此它必须成为价值对象的一部分。
在Java中,它像hashCode一样,是在对象内部计算的。
这不是您的DTO工作,而是您自己的对象。通过这样做,您可以使它们更正确,更不可能被破解并传递错误的值(这将使模型无效),并且也更易于测试:创建两个具有相同值的不同对象,并检查其ID是否相等。非常简单!
如果您要使用可变对象,则只需立即计算ID,而不是在构造函数中创建实例即可。