首先,我认为验证有点棘手,部分原因是需要考虑的各种背景。最终,将在各个应用层执行验证规则。至少,域对象中应该有标准的守卫。这些只是常规的前置条件和参数检查,它们应该是任何设计良好的对象的一部分,并且符合您对该Reigster
方法的看法。正如lazyberezovsky 所说,这是为了防止对象进入无效状态。在这一点上,我支持始终有效的学校。我认为如果需要将实体保持在无效状态,应该为此创建一个新实体。
然而,单独使用这种方法的一个问题是,经常需要将这些验证规则导出到其他层,例如表示层。此外,在表示层,规则需要有不同的格式。它们需要同时呈现,并可能翻译成另一种语言,例如 JavaScript,以便立即获得客户端反馈。尝试从类引发的异常中提取验证规则可能很困难或不切实际。或者,可以在表示层重新创建验证规则。这要简单得多,尽管可能违反 DRY,但它允许规则依赖于上下文。特定工作流可能需要与实体本身强制执行的验证规则不同的验证规则。
所描述方法的另一个问题是,可能存在实体范围之外的验证规则,并且这些规则必须与其他规则合并在一起。例如,对于用户注册,另一个规则是确保电子邮件地址是唯一的。托管适用用例的应用程序服务通常会强制执行此规则。但是,它还必须能够将此规则导出到其他层,例如表示。
总的来说,我尝试将尽可能多的约束检查放入实体本身,因为我认为实体应该始终有效。有时可以设计规则框架,使其既可用于引发异常又可导出到外层。其他时候,简单地跨层复制规则会更容易。