构造函数参数和值对象实现选项



我无法解决一个难题。

  1. 如果我将ValueObjects建模为c#records,我最终会因为with {Property = something}而出现问题,因为在这种情况下,自动生成的init属性可能会绕过构造函数中强制执行的一些逻辑,例如

  2. 如果我将它们建模为常规类,那么我必须检查在将它们用作参数的构造函数/方法中它们是否为null。

  3. 如果我将它们建模为struct(我倾向于大多数atm(,那么我没有空检查,但仍然有默认值检查(如果实体不允许(。

  4. 我能想到的最后一个选项是将它们建模为struct,其中私有isValid属性最初设置为false,在我的构造函数中设置为true,并在getters中签入。

我是否缺少任何其他选项,这些选项有望使使用VO的构造函数/方法中的null检查变得不必要,同时又是真正不可变的?

[更新]

一个例子:

public LegalSubject(LegalSubjectId id,
GeneralInfo generalInfo,
VatId vatId,
LegalSubjectId? customerId
{
// LegalSubjectId cannot be null
// GeneralInfo cannot be null
// VatId cannot be null
}

现在,每个值对象(例如GeneralInfo(的属性都在创建时进行检查。因此,例如,它强制要求GeneralInfo.Name不为空,GeneralInfo.Email不为空等等…(显然,struct在这里不适用,因为默认值会使VO处于无效状态(。

在这个使用VO的类中,最好有一种方法来避免null检查/默认检查。structisValid(在非默认构造函数中设置(解决了这个问题,但我希望还有其他我缺少的解决方案。

PS。如果强制执行可为null的引用类型(而不仅仅是警告(,这将解决问题。但事实并非如此。

就我所了解的值对象而言,您不应该拥有无效的值对象。它们应该始终有效且不可变。

因此,除了检查所有参数是否有效的构造函数(或工厂方法(之外,没有其他选择了。你似乎非常关注null,你确定这是你能得到的唯一无效数据吗?

如果您唯一关心的是null值,那么您可能希望研究可为null的引用类型,这可能会使其更容易。

但最终,是的,一个带有构造函数的常规类会检查输入的有效性,以构建一个有效的、不可变的对象,这就是构建值对象的方式。

最新更新