域实体是否应该进行任何数据格式验证?

时间:2014-04-30 13:21:19

标签: validation oop domain-driven-design cqrs separation-of-concerns

从这个book中获取关于验证的一些想法,将数据验证放在域对象中真的是一个很好的做法和正确的SoC吗?在那里,他提供了关于验证地址,检查它是否在字符间隔之间,添加模式等的示例。当考虑验证时,如果用户从应用程序询问某些内容(例如,在命令对象(cqrs)并在命令无效时停止用户?另外一个问题是国际化,如何处理不同字母的模式?另外一个问题是重复检查,如果域对象检查属性的每个不变量(当它可以是混合类型时),但命令实际上只假设一个单一的invariatn有效,该怎么办?

为什么我感到困惑是因为埃里克·埃文斯在前面写了这本由弗农写的书,但我发现一些设计风格是不合适的。那么在域中或域外验证属性格式(字符串长度,字符串格式等,如该地址示例)更好吗?

1 个答案:

答案 0 :(得分:3)

有用户输入验证(通常是输入格式)和业务规则。输入验证在入口点完成是有意义的(通常是控制器,并且取决于它可以自动完成的框架),向前发送无效数据进行处理没有任何好处。

但是,域包含大多数输入验证规则,因此您似乎必须在将规则保留在域内或重复自己之间进行选择。但您不必这样做,因为输入验证可以很容易地封装到值对象(VO)中,因此它们是域的一部分,但您仍然可以在域外使用它们来验证输入。

这就是为什么最好尽可能多地使用VO,它们通常是域概念并且它们确保值有效。使用它们的实体必须拒绝空值。

我不知道如何验证命令,最多可以检查用户或上下文是否可以创建和发送该命令,但命令本身只是一个带有相关参数的语义DTO。由命令处理程序决定命令的有效性。另外,我不认为命令应该采取任何措施,它是关于 不要做什么,如何来做它。

关于i18n,IMO验证者必须了解当前的文化,因此可能的解决方案是返回当前文化模式的服务。这意味着验证器(我通常将其作为VO的静态方法实现)将采用类似 IKnowValidationPatterns 的方式作为依赖。