全对象图上的DDD验证


@Value
@Builder
public class Parent {
@NotNull
private String firstName;
private Child child;
@Builder
public class Child {
@NotNull
private String firstName;

这是我的挑战,我们正在进行DDD,并在构造函数中或通过构建方法(构建器模式(验证对象。我想要实现的是能够以一种可以收集所有验证错误的方式构建完整的对象树。

正如你在下面的代码中看到的那样,我只会收集孩子的错误,缺少父母的名字。

请注意,这些对象是手动创建的,否则,我只会添加@Valid之类的,但我认为手动构建对象时这不起作用。

仅供参考:我使用弹簧靴堆栈。

Parent.builder()
.firstName(null)
.child(Child.builder()
.firstName(null)
.build())
.build();

为了从域模型对象中提供错误列表,我通常会在聚合根中收集所有可能产生的错误,该根会再次从其子域对象中收集潜在错误。这种方法遵循的思想是收集错误,而不是在第一次出现错误时立即抛出异常。

你可以看看这个答案,它已经说明了这种方法的一个例子(尽管它是C#代码,但模式与语言无关(。

我通常将验证和域模型分离。

例如,我对表示请求主体的视图应用验证(请参阅此处的此类验证示例(,然后只有在确定验证通过后才尝试实例化值对象。在您的情况下,这意味着您将把注释放在视图上,而不是放在VO上。

请注意,对VO应用验证是没有意义的:您能够创建它的事实意味着已经满足了所有约束。

如果您正在使用弹簧堆栈,这里有一种方法:

创建一个名为ParentFactory的新@Component。工厂将有效对象的创建封装在DDD中。

在这个工厂中,您可以使用构建器模式或constructor调用——这并不重要,因为对象创建是抽象的。

此外,ParentFactory得到注入的javaxValidator,因此能够执行上面提到的任务

在DDD中,您的实体不负责执行诸如";收集";错误,除非这是你无处不在的语言的一部分。您想要做的是让实体引发DomainEvent,并且您可以使用单个侦听器来收集和使用所有引发的事件。

最新更新