有没有一种优雅的方法可以将域验证放入域层?

Is there a elegant way of putting domain validations inside domain layer?

我是域驱动设计的新手,在编写域模型时有一件事困扰着我。如何处理域验证?

我正在设计图书馆管理系统,用户可以在其中搜索书籍并查看书籍是否在库中。 如果不是,用户可以创建图书请求,从而创建某种队列。规则是我们没有存货。现在我有关于书籍实体内部数量的信息,这不是问题,但如果我有不同的限界上下文来请求书籍和书籍目录怎么办。然后我必须以某种方式联系另一个 vertical/service 并在创建书籍聚合之前询问(验证)书籍数量为零。

我也在检查用户是否有有效的会员卡,他是否已经借过书,用户是否有任何书籍的主动请求。

困扰我的事情

由于验证,我需要知道在将聚合传递给域模型之前究竟要包含什么。我不确定这是最安全的方法,因为我的验证准确性将取决于 specification/query,等等

还有一个很重要的事情。当应用程序层方法开始执行并且某些内容无效时,客户端将仅获得已执行代码的验证消息,并且很有可能有更多内容阻止代码执行。如果用户正在填写某些表格,这可能真的很不方便。

解决这个问题的初步想法。

我有 command/handler 体系结构并且我正在使用 MediatR,所以我正在考虑在命令和处理程序之间移动域验证,这将暂时解决我的问题,但该方法将在有界上下文和域中传播域知识模型不够聪明,无法防止无效操作。更准确地说,我需要在执行应用程序方法(处理程序)之前考虑我需要验证的内容。

所以我很好奇。有没有明确的方法来处理域模型内的域验证?

Is there any clear way of handling domain validations inside domain model?

是;他们需要工作和仔细思考。

仔细思考的一个方面是区分消息验证与域逻辑。消息验证是一个孤立的事情,消息是否有效取决于消息的模式——是否存在所有必需的字段,数据是否采用正确的形式,数字是否在允许的范围内,等等。真的,我们在问这个问题 "did the client fill out the form correctly?"

将有效消息与先前已知的信息(又名领域模型的 "state")集成是一个领域逻辑问题。状态是有意选择的——领域模型一个用于记录你的领域的状态机。

根据您的域和可用的信息,可能存在表示客户没有得到他们想要的东西的状态。 "The road less traveled" 并不意味着事物 无效 .

此外,如果您的系统是分布式的(不同的数据由不同的机构负责),那么该数据的任何本地缓存副本都必然是陈旧的,并且可能已过时。请参阅 Pat Helland 的 Memories, Guesses, and Apologies。我们有时会给出错误的答案是分配工作的必然结果。如果我们负责,那么我们会进行成本收益分析,以确保分配工作的预期收益抵消预期风险。